乐趣区

关于vue.js:深入理解sync修饰符

一个组件上只能定义一个 v -model,如果其余 prop 也要实现双向绑定的成果该怎么办呢?简略的办法是子组件向父组件发射一个事件,父组件监听该事件,而后更新 prop。具体如下:

<template>

 <!-- info.vue 组件定义了一个 value 属性,和一个 valueChanged 事件 -->
 <div>
    <input @input="onInput" :value="value" />
 </div>
</template>

<script>

export default {
 props: {
     value: {
         type: String,
         default: ""
     }
 },

 data() {return {};
 },

 methods: {onInput(e) {

 // 形式 1

 this.$emit("valueChanged", e.target.value);

 // 形式 2

 this.$emit("update:value", e.target.value);

 // 多个 prop 都要实现双向绑定、简化版本

 this.$emit("update:a", e.target.value);

 this.$emit("update:c", e.target.value);

 }

 }

};

</script>

父组件 index.vue

<template>
<div>
     <!-- 父子组件间双向数据绑定 -->
     <h3> 形式 1: 传统形式 </h3>
     <info :value="myValue" @valueChanged="change"></info>
     <p>{{myValue}}</p>
</div>
 </template> 

<script>
import info from "./sub_index_6/info.vue";
export default {
 components: {info},

 data() {
     return {
       // 形式 1 传统形式
       myValue: "1234",
     };
 },
 methods: {
     // 形式 1 传统形式
     change(e) {this.myValue = e;}
 }
};
</script>

上述写法太麻烦了,通过.sync 能够简化下面代码,只须要修两个中央:

  1. 组件内触发的事件名称以“update:myPropName”命名,相应的上述 info 组件改为 update:value
  2. 父组件 v -bind:value 加上.sync 修饰符,即 v-bind:value.sync
    这样父组件就不必再手动绑定 @update:value 事件了。

用法 1: v-bind:prop.sync=”propvalue”

// info.vue 组件 
... 
methods: {onInput(e) { 
         // 形式 2
         this.$emit("update:value", e.target.value);
     } 
 }

父组件

 <h3> 形式 2: .sync</h3>

 <info :value.sync="myValue2"></info>

 <p>{{myValue2}}</p>
 
 ...data(){
     return {
        // 形式 2 .sync
        myValue2: "5678",
     }
 }
 

用法 2 v-bind.sync=”obj”

如果一个组件的多个 prop 都要实现双向绑定,依据下面学到的常识,只须要每个 prop 加 sync 修饰符

<template>
 <!-- info.vue 组件定义了一个 value 属性,和一个 valueChanged 事件 -->
 <div>
    <input @input="onInput" :value="value" />
 </div>
</template>

<script>
export default {
 props: {
 value: {
     type: String,
     default: ""
 },
 a: {
     type: String,
     default: ""
 },
 b: {
     type: String,
     default: ""
 },
 c: {
     type: String,
     default: ""
 },
 d: {
     type: String,
        default: ""
     }
 },

 data() {return {};
 },
 methods: {onInput(e) {
 // 多个 prop 都要实现双向绑定、简化版本
 this.$emit("update:a", e.target.value);
 this.$emit("update:c", e.target.value);
 }
 }

};

</script>

父组件

<h4> 多个 prop 都要实现双向绑定 </h4>

 <info
 :a.sync="value1"
 :b.sync="value2"
 :c.sync="value3"
 :d.sync="value4"
 ></info>

 <p>{{value1}} -- {{value2}} -- {{value3}} -- {{value4}}</p>
 
 ...data(){
     return {
         // 多个 prop 都要实现双向绑定
         value1: "1",
         value2: "2",
         value3: "3",
         value4: "4",
     }
 }

这样写太麻烦,vue 提供了一种更简便的办法,v-bind.sync = “ 对象 ”

残缺代码

父组件

<template>
<div>
 <!-- 父子组件间双向数据绑定 -->
 <h3> 形式 1: 传统形式 </h3>
 <info :value="myValue" @valueChanged="change"></info>
 <p>{{myValue}}</p>

 <hr />
 
 <h3> 形式 2: .sync</h3>
 <info :value.sync="myValue2"></info>
 <p>{{myValue2}}</p>

 <h4> 多个 prop 都要实现双向绑定 </h4>
 <info
 :a.sync="value1"
 :b.sync="value2"
 :c.sync="value3"
 :d.sync="value4"
 ></info>
 <p>{{value1}} -- {{value2}} -- {{value3}} -- {{value4}}</p>

 <h4> 简化版本 </h4>
 <info v-bind.sync="obj"></info>
 <p>{{obj.a}} -- {{obj.b}} -- {{obj.c}} -- {{obj.d}}</p>
</div>

</template>

<script>
import info from "./sub_index_6/info.vue";
export default {
 components: {info},
 data() {
 return {
     // 形式 1 传统形式
     myValue: "1234",

     // 形式 2 .sync
     myValue2: "5678",

     // 多个 prop 都要实现双向绑定
     value1: "1",
     value2: "2",
     value3: "3",
     value4: "4",
     // 简化版本
     obj: {a: "1", b: "2", c: "3", d: "4"}
 };
 },

 methods: {
     // 形式 1 传统形式
     change(e) {this.myValue = e;}
 }
};

</script>

子组件

<template>
 <!-- info.vue 组件定义了一个 value 属性,和一个 valueChanged 事件 -->
<div>
 <input @input="onInput" :value="value" />
</div>
</template>

<script>
export default {
 props: {
 value: {
     type: String,
     default: ""
 },
 a: {
     type: String,
     default: ""
 },
 b: {
     type: String,
     default: ""
 },
 c: {
     type: String,
     default: "" 
 },
 d: {
     type: String,
     default: ""
 }
},
data() {return {};
},
methods: {onInput(e) {
     // 形式 1
     this.$emit("valueChanged", e.target.value);

     // 形式 2
     this.$emit("update:value", e.target.value);

     // 多个 prop 都要实现双向绑定、简化版本
     this.$emit("update:a", e.target.value);
     this.$emit("update:c", e.target.value);
 }

}
};
</script>

效果图

留神:

带有.sync 修饰符的 v -bind 不能喝表达式一起应用(例如 v-bind:title.sync = “doc.title + ‘!'” 是有效的)。取而代之的是,你只能绑定你想要绑定的属性名。

小结

一个组件须要提供多个双向绑定的属性时应用,只能选用一个属性来提供 v-model 性能,但如果有其余属性也要提供双向绑定,就须要.sync

退出移动版