一、弹框组件

1.首先需要写一个弹框组件model.vue,包括遮罩层及弹框本身。

//html部分
<template>
  <div class="model">
    <div class="mask">123</div>
    <div class="model-dialog">
      <div class="model-header">
        <span>提示</span>
        <a href="javascript:;" class="icon-close" ></a>
      </div>
      <div class="model-body">
        <div class="body">这是条消息</div>
      </div>
      <div class="model-footer">
        <button class="btn">确认</button>
      </div>
    </div>
  </div>
</template>
//css部分
.mask {
  position: fixed;//这里用固定定位,后面设置动画时才不受影响
  top: 0;
  height: 100%;
  width: 100%;
  background-color: rgba(167, 165, 165, 0.486);
  opacity: 0.5;
  z-index: 9;
}
.model-dialog {
  position: absolute;
  //让弹框居中显示
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  background-color: #fff;
  border-radius: 12px;
  width: 600px;
  height: 300px;
  border: 1px solid #f5f5f5;
  overflow: hidden;
  z-index: 10;//这里注意层级要比mask大,覆盖它
}
.model-header {
  position: relative;
  height: 50px;
  padding-left: 10px;
  padding-top: 10px;
  font-size: 20px;
  line-height: 50px;
  background-color: #f5f5f5;
  border-bottom: 1px solid rgb(177, 176, 176);
}
.model-body {
  height: 150px;
  line-height: 150px;
  font-size: 28px;
  text-align: center;
  background-color: #fff;
}
.model-footer {
  background-color: #f5f5f5;
  height: 100px;
  text-align: center;
  line-height: 100px;
}
.btn {
  width: 180px;
  height: 40px;
  border-radius: 8px;
  background-color: rgb(180, 103, 103);
  color: #fff;
  font-size: 18px;
  border: none;
}
.icon-close {
  position: absolute;//如果不加绝对布局,图表显示不出来
  background-color: pink;
  right: 15px;
  top: 16px;
  width: 30px;
  height: 30px;
  z-index: 10;
  background: url("../assets/icon-close.png") no-repeat;
  background-size: contain;
}

2.子组件绑定v-show

v-show是条件渲染,和v-if一样,但v-if 有更高的切换开销,而 v-show 有更高的初始渲染开销。如果需要非常频繁地切换,则使用 v-show 较好;如果在运行时条件很少改变,则使用 v-if 较好。因为是弹框组件,需要经常切换,我们这里就使用v-show。


这里v-show=“showModel”绑定了父组件传过来的值showModel,若值为true,那么显示该样式,反之,值为false则不显示。

<script>
export default {
  name: "model",
  props: {
    //是否展示弹框
    showModel: Boolean,
  },
};
</script>

二、引用该弹框组件

先简单写一个按钮,当点击这个按钮时弹出弹窗

<template>
  <div class="home">
    <button class="btn" @click="show">点击显示弹框</button>
    <model :showModel="showModel"></model>//传值给子组件
  </div>
</template>

<style scoped>
.home {
  width: 100%;
  height: 1000px;
}
.btn {
  display: block;
  background-color: pink;
  width: 200px;
  height: 100px;
  margin: 0 auto;
}
</style>

再引入弹框组件model.vue

<script>
import Model from "../components/model.vue";
export default {
  name: "index",
  components: {
    Model,
  },
  data() {
    return {
      showModel: false,
    };
  },
  methods: {
    show() {
      this.showModel = true;
      console.log(this.showModel);
    },
  },
};
</script>

这里要注意的是,因为取消键是在子组件中,如果直接给取消键添加方法close(),在方法中修改showModel会报错。

因为子组件不能修改父组件传过来的值,就算在方法中修改showModel的值,父组件中的showModel是不会变成false的。
所以只能通过在子组件中绑定事件,当点击关闭键时,触发事件cancel。

在父组件中定义该事件

当点击关闭按钮是,子组件传给父组件cancel事件,父组件修改showModel的值为false。

三、添加vue动画

这样就完成了逻辑部分,但是缺少了动画效果,提示框的显示变得很生硬,所以这里我再给提示框添加一个vue transition动画。
在子组件顶部添加transition过度,并设置样式即可。

这里用到了v-enter、v-enter-active、v-leave-active三个过度类名,它们的功能如下:

v-enter:定义进入过渡的开始状态。在元素被插入之前生效,在元素被插入之后的下一帧移除。
v-enter-active:定义进入过渡生效时的状态。在整个进入过渡的阶段中应用,在元素被插入之前生效,在过渡/动画完成之后移除。这个类可以被用来定义进入过渡的过程时间,延迟和曲线函数。
v-leave-active:定义离开过渡生效时的状态。在整个离开过渡的阶段中应用,在离开过渡被触发时立刻生效,在过渡/动画完成之后移除。这个类可以被用来定义离开过渡的过程时间,延迟和曲线函数。

.model {
  z-index: 10;
  transition: all 0.5s;
}
.slide-enter-active {
  top: 0;
}

.slide-leave-active {
  top: -100%;
}
.slide-enter {
  top: -100%;
}

这样就实现了点击按钮弹出对话框的功能啦~~

更多推荐

用vue实现消息弹框