Vue 中的 .sync 修饰符

105 阅读1分钟

例一

场景描述:Child.vue是一个子组件,Child.vue通过props得到父组件的数据,那么Child.vue可否修改父组件的props?答案是可以的,通过this.$emit可以触发事件,并且传参,即可修改父组件的props。
Child.vue文件内容如下:

  <template>
  <div class="child">
    我是儿子,我要花爸爸的钱——{{money}}
    <button @click="$emit('update:money',money-100)">
      <span>花钱</span>
    </button>
  </div>
  </template>

  <script>
  export default {
    props:["money"]
  }
  </script>>

  <style>
  .child{
    border:3px solid green;
  }
  </style>

App.vue文件内容如下:

<template>
  <div class="app">
    App.vue 我是爸爸,现在有{{total}}
    <hr>
    <Child :money="total" v-on:update:money="total=$event"/>
  </div>
</template>>

<script>
import Child from "./Child.vue"
export default{
  data(){
    return {total:10000};
  },
  components:{
   Child
  }
}
</script>
<style lang="stylus" scoped>
  .app{
    border:3px solid red;
    padding:10px;
  }
  
</style>

结果如下:
用.sync实现
App.vue改写如下:

<template>
  <div class="app">
    App.vue 我是爸爸,现在在有 {{total}}
    <hr>
    <Child :money.sync="total"/>
  </div>
</template>

<script>
import Child from "./Child.vue";
export default {
  data() {
    return { total: 10000 };
  },
  components: { Child: Child }
};
</script>

<style>
.app {
  border: 3px solid red;
  padding: 10px;
}
</style>

实现的效果是一样的,需要注意的是::money.sync="total"等价于:money="total" v-on:update:money="total=$event"

三个vue规则

  • 组件不能修改props外部数据
  • this.$emit可以触发事件,并传参
  • $event可以获取$emit的参数

例二


<template>
    <div class="details">
        <myComponent :show.sync='valueChild' 
        style="padding: 30px 20px 30px 5px;
        border:1px solid #ddd;margin-bottom: 10px;">
        </myComponent>
        <button @click="changeValue">toggle</button>
    </div>
</template>
<script>
import Vue from 'vue'
Vue.component('myComponent', {
      template: `<div v-if="show">
                    <p>默认初始值是{{show}},所以是显示的</p>
                    <button @click.stop="closeDiv">关闭</button>
                 </div>`,
      props:['show'],
      methods: {
        closeDiv() {
          this.$emit('update:show', false); //触发 input 事件,并传入新值
        }
      }
})
export default{
    data(){
        return{
            valueChild:true,
        }
    },
    methods:{
        changeValue(){
            this.valueChild = !this.valueChild
        }
    }
}
</script>

这个例子大家可以动手在codesandbox尝试一下。
注意,这里的:show.sync='valueChild'等价于:show="valueChild" v-on:update:show="valueChild=$event"
vue修饰符sync的作用是:当一个子组件改变了一个props的值时,这个变化也会同步到父组件中。