关于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

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理