prop,$emit与.sync

官网地址
有些时候,我们需要对vue组件的prop进行"双向绑定"
如单独把一个弹框封装到子组件中时,可以对prop使用双向绑定
在使用子组件时,给子组件的属性添加.sync修饰符,这样就相当于可以直接在子组件中直接修改父组件的值了

// 父组件
<template>
  <div>
    <el-button @click="open">打开弹框</el-button>
    <dialogTest :showDialog.sync="dialogVisible"></dialogTest>
  </div>
</template>

<script>
import dialogTest from "./dialogTest.vue"
export default{
  components:{
    dialogTest
  },
  data() {
    return {
      dialogVisible: false
    }
  },
  methods:{
    open() {
      this.dialogVisible = true
    }
  }
}
</script>
// 子组件
<template>
  <div>
    <el-dialog title="测试" :visible.sync="showDialog" width="30%">
      <span>测试.sync与$emit</span>
      <span slot="footer" class="dialog-footer">
        <el-button @click="cancel">取 消</el-button>
        <el-button type="primary" @click="cancel">确 定</el-button>
      </span>
    </el-dialog>
  </div>
</template>

<script>
export default{
  props: {
    showDialog: {
      type: Boolean,
      default: false
    }
  },
  methods:{
    cancel() {
      this.$emit("update:showDialog", false)
    }
  }
}
</script>

但是这样写,使用组件自带的关闭按钮或者通过"esc"关闭时会报错
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: "showDialog"
等我找到解决办法来更新......QAQ
解决方法:
在子组件中不要直接使用prop的值,转换一下就好了
原因是这样写相当于监听了visibleDialog的值,每次visibleDialog的值改变之后,都会去调用this.$emit("update:showDialog", false),这样就不会有问题了

// 子组件
<template>
  <div>
    <el-dialog title="测试" :visible.sync="visibleDialog" width="30%">
      <span>测试.sync与$emit</span>
      <span slot="footer" class="dialog-footer">
        <el-button @click="cancel">取 消</el-button>
        <el-button type="primary" @click="cancel">确 定</el-button>
      </span>
    </el-dialog>
  </div>
</template>

<script>
export default{
  computed:{
    visibleDialog: {
      get() {
        return this.showDialog
      },
      set(val) {
        this.$emit("update:showDialog", false)
      }
    }
  },
  props: {
    showDialog: {
      type: Boolean,
      default: false
    }
  },
  methods:{
    cancel() {
      this.visibleDialog = false
    }
  }
}
</script>
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容