在vue2中,v-model和.sync的区别

最近在封装一个弹窗组件时,用了比较复杂的逻辑去做显示和隐藏的逻辑,在查看同事的代码之后,才知道还有更简单的方法,自己已经忘了一些API.
popup组件里统一的template:

<div v-if='isShowPopup'>
// 弹窗内容
</div>

自己的方法

 data(){
	return {
    isShowPopup: false,
    }
 },
  methods: {
    showPopup() {
      this.isShowPopup = true
    },
    closePopup() {
      this.isShowPopup = false
    }
  }

在外部通过给popup组件绑定ref=‘xxx’,从而通过this.$refs.xxx.showPopup()/ closePopup() 实现显示和隐藏控制
同事的方法

// popup组件 
  props: {
    show: {
      type: Boolean,
      default: true
    },
  },
   computed: {
    isShowPopup: {
      get() {
        return this.show;
      },
      set(val) {
        this.$emit("update:show", val);
      }
    }
  },

在外部通过给popup组件绑定:show.sync=‘xxx’,从而通过this.xxx = true / false 实现显示和隐藏控制

从以上可以看到,同事的方法实现思路更加清晰,也比较符合官方文档的要求:
在vue2中,v-model和.sync的区别_第1张图片
以上的意思总结:在某些情况下,我们可能需要对组件的一个prop值进行“双向绑定”。真正的双向绑定可能会产生维护问题,因为该变化的来源在父组件和子组件中都不明显。所以我们建议在子组件里以update:myPropName的模式发出事件,父组件可以以:myPropName.sync=‘xxxx’ 绑定在子组件里。
代码比较如下:
传统的方法

<text-document
  :title="doc.title"
  @updateTitle="doc.title = $event"
></text-document>

在text-document的子组件里以 this.$emit(“updateTitle”, xxx);发出
新的方法:

<text-document
  v-bind:title="doc.title"
  v-on:update:title="doc.title = $event"
></text-document>

可简写成

<text-document v-bind:title.sync="doc.title"></text-document>

在text-document的子组件里以 this.$emit(“update:title”, xxx);发出

可以看到在新的方法里,用户可通过.sync 和 update: 就可知道父子之间的传值关系
喜欢思考的小伙伴的,可能发现v-model不也是双向绑定吗,是不是里面也是.sync 和 update: 的一种实现?
没错!

<ChildComponent v-model="pageTitle" />

// would be shorthand for

<ChildComponent :value="pageTitle" @input="pageTitle = $event" />

所以也可以写成:

<ChildComponent v-bind:value.sync="pageTitle" />

v-model默认是使用value作为prop,input作为事件,如果想改的话,可以借助于model,

Vue.component('base-checkbox', {
  model: {
    prop: 'checked',
    event: 'change'
  },
  props: {
    checked: Boolean
  },
  template: `
    
  `
})

需要注意的是,你仍然需要在组件的props选项中声明 checked

更多细节可参考官方文档:https://v2.vuejs.org/v2/guide/components-custom-events#sync-Modifier

你可能感兴趣的:(vue,vue.js)