2

一个组件上只能定义一个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>

效果图

image.png

注意:

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

小结

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


webxEJIr
95 声望0 粉丝

计算机网络爱好者