【Vue基础】-父子组件中的sync 修饰符

97 阅读1分钟

如果你不理解Vue的props传递数据是单向传递的话,你很容易想把父组件传递的值直接在子组件中改变,极其容易犯的错,如下:

父组件中:

<child-cpn :title="title"></child-cpn>

子组件中:

<template>
  <div>
    <button @click="sendMsg">子组件Two按钮</button>
    父组件传给子组件的title:{{title}}
  </div>
</template>
...
props:['title'],
methods:{
  sendMsg(){
      this.title = '改变了'
  }
}
...

Error:你直接改了父组件传给子组件的数据,而props数据是向下传递的,会报错:[Vue warn]: Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders. 避免直接改变值,每当父组件重新渲染时,这个值会被重写(覆盖)。

遇到上面的问题,你首先会想到的是下面这种方案:

父组件中:

<child-cpn :title="title" @changeTitle="changeTitle"></child-cpn>
...
data(){
 return{
  title:'今天天气不错',
 }
}
methods:{
  changeTitle(val){
     this.title = val
  }
}
...

子组件中:

<template>
  <div>
    <button @click="sendMsg">子组件Two按钮</button>
    父组件传给子组件的title:{{title}}
  </div>
</template>
...
props:['title'],
methods:{
  sendMsg(){
     this.$emit('changeTitle','改变了')
  }
}
...

总结:当你想在子组件中操作父组件的数据,实际上的思维方式:是通过子组件$emit携带数据发送一个事件给父组件,通过父组件来改变这个数据,本质上并没有让子组件去改父组件的数据,而是子组件借父组件的手去改变父组件的数据,以达到'子组件改了父组件值'的假象。

回过头来看看官网的:在有些情况下,需要对prop 进行“双向绑定”,官方推荐采取的是update结合.sync来处理这类问题。(sync:同步)

父组件中:

 
 <child-cpn :title.sync="title"></child-cpn>
 // 上面的写法是个简写,实际做的操作如下
 // <child-cpn :title="title" @update:title="(val) => { title = val;}"></child-cpn>

子组件中:

<template>
  <div>
    <button @click="sendMsg">子组件Two按钮</button>
    父组件传给子组件的title:{{title}}
  </div>
</template>
...
props:['title'],
methods:{
  sendMsg(){
      this.$emit('update:title','改变了')
  }
}
...

总结:最开始的做法有出处,在$emit事件中,是以update:myPropName这种事件来触发,配合父组件中.sync修饰符,不用再在父组件中写一个@事件,更简单明了。