💎一站式轻松地调用各大LLM模型接口,支持GPT4、智谱、星火、月之暗面及文生图 广告
[TOC] >[success] # 组件间双向绑定高级内容 v-model的使用同时也可以参考我的另一篇文章中的 [v-model和.sync的用法](https://www.kancloud.cn/wangjiachong/vue_notes/1971967#vmodelsync_304) 1. **v-model(修改单个值)**:**v-model绑值,达到子组件可以修改父组件的值的效果** 2. **v-model(修改多个值)**:**可以绑定多个v-model值,达到修改多个值** >[success] ## v-model(修改单个值) 上一章讲了讲了如果想做到 **子组件想修改父组件的值,子组件要通过$emit触发父组件的自定义方法,然后在父组件中修改值** 。其实 **v-model** 同样可以做到 **子组件修改父组件传递的数据**,写法如下: **index.html** ~~~ <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>组件间双向绑定高级内容</title> <!-- 通过cdn方式引入vue --> <script src="https://unpkg.com/vue@next"></script> </head> <body> <div id="root"></div> </body> <script> // 父组件 const app = Vue.createApp({ data(){ return { count: 1 } }, template: ` <counter v-model="count" /> ` }) // 子组件 app.component('counter', { props: ['modelValue'], methods: { handleClick(){ this.$emit('update:modelValue', this.modelValue + 2) } }, template: ` <div @click="handleClick">{{modelValue}}</div> ` }) const vm = app.mount('#root') </script> </html> ~~~ 上面代码 **子组件** 中的 **modelValue** 是 **固定写法** ,如果你不想叫做 **modelValue** ,你可以 **自定义名称** ,这样写: ~~~ <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>父子组件间如何通过事件进行通信</title> <!-- 通过cdn方式引入vue --> <script src="https://unpkg.com/vue@next"></script> </head> <body> <div id="root"></div> </body> <script> // 父组件 const app = Vue.createApp({ data(){ return { count: 1 } }, template: ` <counter v-model:app="count" /> ` }) // 子组件 app.component('counter', { props: ['app'], methods: { handleClick(){ this.$emit('update:app', this.app + 2) } }, template: ` <div @click="handleClick">{{app}}</div> ` }) const vm = app.mount('#root') </script> </html> ~~~ 这样写绑定**v-model** 的地方必须要这样写:**<counter v-model:app="count" /\>** ,拼接成:**v-model:组件中props自定义的名称** >[success] ## v-model(修改多个值) 上面的 **v-model** 例子,看着是简单了很多,但是 **只能修改单个属性值** ,那我如果想用 **v-model修改多个属性值** 该怎么办呢, 代码如下: **index.html** ~~~ <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>组件间双向绑定高级内容</title> <!-- 通过cdn方式引入vue --> <script src="https://unpkg.com/vue@next"></script> </head> <body> <div id="root"></div> </body> <script> // 父组件 const app = Vue.createApp({ data(){ return { count: 1, count1: 1 } }, template: ` <counter v-model:count="count" v-model:count1="count1" /> ` }) // 子组件 app.component('counter', { props: ['count', 'count1'], methods: { handleClick(){ this.$emit('update:count', this.count + 2) }, handleClick1(){ this.$emit('update:count1', this.count1 + 2) } }, template: ` <div @click="handleClick">{{count}}</div> <div @click="handleClick1">{{count1}}</div> ` }) const vm = app.mount('#root') </script> </html> ~~~ >[success] ## 组件的v-model配合自定义的修饰符使用 在组件的 **v-model** 上,还可以 **自定义修饰符** 来使用,只需要 **在子组件中判断父组件传入的修饰符是什么,然后执行响应的逻辑来处理v-model绑定的值即可** ,像下面例子中,传入了一个 **自定义大写修饰符** ,代码如下: index.html ~~~ <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>组件间双向绑定高级内容</title> <!-- 通过cdn方式引入vue --> <script src="https://unpkg.com/vue@next"></script> </head> <body> <div id="root"></div> </body> <script> // 父组件 const app = Vue.createApp({ data(){ return { count: 'a' } }, template: ` <counter v-model.uppercase="count" /> ` }) // 子组件 app.component('counter', { props: { 'modelValue': String, modelModifiers: { // modelModifiers指传递过来的修饰符 default: () => ({}) } }, // mounted(){ // // 打印传过来的修饰符 // console.log(this.modelModifiers) // uppercase:true // }, methods: { handleClick(){ let newValue = this.modelValue + 'b' if(this.modelModifiers.uppercase){ // 是否使用了uppercase(全部大写)修饰符 newValue = newValue.toUpperCase() } this.$emit('update:modelValue', newValue) } }, template: ` <div @click="handleClick">{{modelValue}}</div> ` }) const vm = app.mount('#root') </script> </html> ~~~