我很希望项目中可以多接触一些新东西,实践出真知,对于编程来说就是要多动手,多总结几录,多思考,才能更好的避坑,因为动手了会发现好多你以为的不是你以为的。

概述

PC 端项目中,一直使用的是Element UI
,最近功能迭代,有一个选择专家的弹窗在多个页面应用到,因此需要将dialog进行封装以便复用,在Element-UI 的基础上,对dialog
进行封装,最重要的是一个属性值的控制 即 visible,对于dialog 中要显示哪些内容,按照一般组件传过来就可以了。

核心问题

el-dialog 的 visibile 属性值 只能在父组件或者子组件中一个进行修改,父组件传给子组件的属性值不能在子组件中直接进行修改,这是VUE
比较介意的。如果在子组件中直接修改就会报以下错误。

vue.runtime.esm.js?2b0e:619 [Vue warn]: Avoid mutating a prop directly since
the value will be overwritten whenever the parent component re-renders.
Instead, use a data or computed property based on the prop's value. Prop being
mutated: "dialogFormVisible"

found in

---> <MyDialog> at src/views/packageDialog/MyDialog.vue
       <DialogDemo> at src/views/packageDialog/dialogDemo.vue
         <App> at src/App.vue
           <Root>

问题解决

父组件传给dialog 子组件的 属性值 不直接使用在visible 属性值上,取另外的值与其同步

在dialog 子组件中 通过watch 监听父组件中传值的变化,进行同步

子组件中需要关闭dialog 时,同样要触发父组件中的时间,修改父组件中定义的控制dialog 显示的值

核心代码如下:

    dialogShow(val) {

      this.dialogFormVisible = val

    }

  },

  methods: {

    closeDialog() {

      this.$emit('dialogShowChange', false)

    }

  }

整体Demo 代码

父组件:
<template> <div class="dialogDemoContainer"> <el-button type="primary"
@click="dialogShowChange(true)">show dialog</el-button> <div v-if="dialogShow"
class="dialogBox"> <myDialog :dialogShow="dialogShow"
@dialogShowChange="dialogShowChange"></myDialog> </div> </div> </template>
<script> import myDialog from './MyDialog.vue' export default { data() { return
{ dialogShow: false } }, components: { myDialog }, methods: {
dialogShowChange(val) { this.dialogShow = val } } } </script> <style
lang="scss" scoped> .dialogDemoContainer { text-align: center; padding: 20px;
.dialogBox { text-align: left; } } </style>
dialog 子组件:
<template> <el-dialog title="收货地址" :visible.sync="dialogFormVisible"
@close="closeDialog"> <el-form :model="form"> <el-form-item label="活动名称"
:label-width="formLabelWidth"> <el-input v-model="form.name"
autocomplete="off"></el-input> </el-form-item> <el-form-item label="活动区域"
:label-width="formLabelWidth"> <el-select v-model="form.region"
placeholder="请选择活动区域"> <el-option label="区域一" value="shanghai"></el-option>
<el-option label="区域二" value="beijing"></el-option> </el-select>
</el-form-item> </el-form> <div slot="footer" class="dialog-footer"> <el-button
@click="closeDialog">取 消</el-button> <el-button type="primary"
@click="closeDialog">确 定</el-button> </div> </el-dialog> </template> <script>
export default { props: { dialogShow: { type: Boolean, default: false } },
data() { return { dialogFormVisible: this.dialogShow, form: { name: '', region:
'', date1: '', date2: '', delivery: false, type: [], resource: '', desc: '' },
formLabelWidth: '120px' } }, watch: { dialogShow(val) { this.dialogFormVisible
= val } }, methods: { closeDialog() { this.$emit('dialogShowChange', false) } }
} </script> <style lang="scss" scoped> </style>
最终,要记住问题得本质,及这类问题得解决,希望不断采坑不断进步。

技术
下载桌面版
GitHub
Gitee
SourceForge
百度网盘(提取码:draw)
云服务器优惠
华为云优惠券
腾讯云优惠券
阿里云优惠券
Vultr优惠券
站点信息
问题反馈
邮箱:[email protected]
吐槽一下
QQ群:766591547
关注微信