当我们使用element-ui时,如果弹窗内容较多elementui弹窗设置时间,我们往往会将弹窗封装成一个组件,如下:
弹窗内容
// DetailDialog.vue js
props: {
visible: {
type: Boolean,
default: false
}
}
el-dialog 会改变 props 并报错
然而,会有一个问题。 当el-dialog内部的shutdown事件被触发时,比如点击弹窗阴影等,会发出改变当前组件的props[visible]的事件,因为组件不能直接改变props属性。 也会报错。
我们添加了一个中间变量innerVisible来拦截props[visible]的变化和获取
弹窗内容
// DetailDialog.vue js
export default {
props: {
visible: {
type: Boolean,
default: false
}
},
computed: {
innerVisible: {
get: function() {
return this.visible
},
set: function(val) {
this.$emit('update:visible', val)
}
}
}
}
这样,当el-dialog内部改变prop[visible]时,我们会通过emit('update:')方法通知父组件,防止直接改变props。 事实上,父组件需要添加sync修饰符来接受更改:
至此,封装的弹出组件没有问题。
继续优化,使用v-model控制显示和隐藏
// DetailDialog.vue js
export default {
model: {
prop: 'visible', // 修改 v-model 绑定的props名称
event: 'toggle' // 修改 v-model 绑定的自定义事件名
},
props: {
visible: {
type: Boolean,
default: false
}
},
computed: {
innerVisible: {
get: function() {
return this.visible
},
set: function(val) {
this.$emit('update:toggle', val)
}
}
}
}
连接v-model后elementui弹窗设置时间,使用起来变得更加复杂和简洁。
继续优化并打包成mixin
当频繁封装弹出组件时,上述逻辑也需要不断复制,所以我们继续优化,将上述控制显示和隐藏逻辑封装到mxins中,可以直接复用。
// vModelDialog.js
export default {
model: {
prop: 'visible',
event: 'toggle'
},
props: {
visible: {
type: Boolean,
default: () => {
return false
}
}
},
computed: {
innerVisible: {
get: function() {
return this.visible
},
set: function(val) {
this.$emit('toggle', val)
}
}
}
}
这样封装弹出插件时,只需要引入mixins即可完成显示和隐藏逻辑。
// DetailDialog.vue js
import vModelDialog from './vModelDialog.js'
export default {
mixins: [vModelDialog],
}