1. 技术选型

Vue + ElementUI

2. 需求功能分析

点击按钮,出现弹框。点击取消或者弹框右上角叉号,关闭弹框。

3. 组件树结构

4. 实现思路 

4.1 方案一 (wrong)

  • 用户点击MainContent触发点击事件
  • MainContent通知父组件显示弹框
this.$emit('showAlertModal')
  • 父组件接收通知并改变showAlertModal变量的值
this.showAlertModal = true
  • 父组件传值给AlertModal告诉它:请开始你的表演
<AlertModal :show="showAlertModal"></AlertModal>
  • 子组件拿到这个值之后,脱掉隐身衣
<el-dialog title="title" :visible.sync="show"></el-dialog>
  • 当用户点击到取消按钮或者弹出框右上角的叉号时,子组件更改show的值隐藏自己
CloseThis () {
    this.show = false
}

这个方案是可以正常运行的,但是会报错,因为Vue不允许子组件更改父组件的变量。

4.2 方案二 (wrong)

  • 子组件中不直接更改父组件传过来的show值,而是在computed中使用一个变量来接收它
computed: {
  showThis: {
    get: function () {
      return this.show
    }
  }
}
  • 子组件通过showThis变量来操作隐身衣
<el-dialog title="title" :visible.sync="showThis"></el-dialog>
  • 在用户点击取消按钮的时候通过改变showThis的值来达到隐藏效果
CloseThis () {
    this.showThis = false
}

结果表现为弹出框能点开,但是关不上,报错信息为:Computed property "showThis" was assigned to but it has no setter.

好吧,查了一下官方文档发现需要如果需要读取和设置computed中的属性需要同时具备get和set方法,就像下面这样

但是继续观察这个写法,发现set方法中修改的变量值正是get方法中返回的变量值。平移到我们这个场景中则表现为set方法中需要修改this.show的值,而this.show是父元素传下来的,是不能修改的,所以这个方法也不可行!

4.3 方案三 (right)

  • 子组件在data中定义一个showThis变量,初始值为null
data () {
  return {
    showThis: null
  }
}
  • 在组件挂载的时候将父元素传来的show赋值给showThis 
mounted () {
    this.showThis = this.show
}
  • 为show和showThis两个变量添加监听,每当它们发生变化的时候就进行相应的操作
watch: {
  showThis: function(newV, oldV){
    // 告诉父元素改变show的值
    this.$emit('closeModal', newV)
  },
  show: function (newV, oldV) {
    this.showThis = newV
  }
}
  • 父元素拿到子元素传来的closeModal事件的dom及事件触发的函数内容如下
<AlertModal 
    @closeModal="CloseModal"
    :show="showAlertModal"></AlertModal>
CloseModal(...data) {
  this.showAlertModal = data[0]
}

 

Logo

前往低代码交流专区

更多推荐