vue2中.sync的使用和在vue3中.sync的移除后的替代使用
修饰符 .sync 的作用:
.sync
修饰符的作用就是实现父子组件数据的双向绑定,简化功能逻辑代码 。当然,v-model
也是可以实现数据的双向绑定,但是,一个组件只有一个v-model
,所以 ,v-model
只能针对一个变量进行数据绑定,而.sync
修饰符可以实现多个参数的数据双向绑定。- 在对一个 prop 进行“双向绑定,单向修改”的场景下,因为子组件不能直接修改父组件,
.sync
在2.3版本引入,作为一个事件绑定语法糖,利用EventBus
,当子组件触发事件时,父组件会响应事件并实现数据更新,避免了子组件直接修改父组件传过来的内容。
vue2中使用.sync
父组件数据传入子组件中后更新
在父组件中传入数据到子组件中后,然后在子组件中处理了后,需要改变父组件数组的时候,我们一般会使用 $emit
传递一个事件更新给父组件,父组件再对原来传入的数据进行更新修改。
比如,我们在父组件中使用一个模态框组件,如下:
// 父组件
<template><div id="app"><button @click="openModal">打开模态框</button><!-- 以下三种方法都可,我一般用的第一种 --><!-- 使用方法事件处理器 --><MyModal :isShow="isShow" @closeModal="closeModal" /><!-- 使用$event变量 --><MyModal :isShow="isShow" @closeModal="isShow = $event" /><!-- 使用内联事件处理器 --><MyModal :isShow="isShow" @closeModal="(val) => isShow = val" /></div>
</template><script>
import MyModal from './components/MyModal.vue'export default {name: 'App',components: {MyModal},data() {return {isShow: false}},methods: {openModal() {this.isShow = true},closeModal(val) {this.isShow = val}}
}
</script><style>
#app {font-family: Avenir, Helvetica, Arial, sans-serif;-webkit-font-smoothing: antialiased;-moz-osx-font-smoothing: grayscale;text-align: center;color: #2c3e50;margin-top: 60px;
}
</style>// 模态框组件
<template><div v-if="isShow"><h1>我是模态框</h1><button @click="closeModal">关闭模态框</button></div>
</template><script>export default {props: ['isShow'],methods: {closeModal() {this.$emit('closeModal', false)}}
}
</script>
优化1
我们对上述代码进行一些优化,将父组件的 @closeModal
改为 @update:isShow
同时,将 $emit
方法更新为 update:isShow
。
代码如下:
// 父组件
<template><div id="app"><button @click="openModal">打开模态框</button><!-- 使用方法事件处理器 --><!-- <MyModal :isShow="isShow" @closeModal="closeModal" /> --><!-- 使用$event变量 --><!-- <MyModal :isShow="isShow" @closeModal="isShow = $event" /> --><!-- 使用内联事件处理器 --><!-- <MyModal :isShow="isShow" @closeModal="(val) => isShow = val" /> --><MyModal :isShow="isShow" @update:isShow="(val) => isShow = val" /><MyModal :isShow="isShow" @update:isShow="isShow = $event" /><MyModal :isShow="isShow" @update:isShow="closeModal" /></div>
</template><script>
import MyModal from './components/MyModal.vue'export default {name: 'App',components: {MyModal},data() {return {isShow: false}},methods: {openModal() {this.isShow = true},closeModal(val) {this.isShow = val}}
}
</script><style>
#app {font-family: Avenir, Helvetica, Arial, sans-serif;-webkit-font-smoothing: antialiased;-moz-osx-font-smoothing: grayscale;text-align: center;color: #2c3e50;margin-top: 60px;
}
</style>// 模态框组件
<template><div v-if="isShow"><h1>我是模态框</h1><button @click="closeModal">关闭模态框</button></div>
</template><script>export default {props: ['isShow'],methods: {closeModal() {// this.$emit('closeModal', false)this.$emit('update:isShow', false)}}
}
</script>
优化2
将父组件 :isShow="isShow"
加上 .sync
,变成 :isShow.sync="isShow"
,.sync
如果用一句话来说就是同步更新了子组件的数据变化,而从实现的角度来说就是 .sync
就是@update:isShow="closeModal"
的语法糖,是一种简写的形式。
代码如下:
// 父组件
<template><div id="app"><button @click="openModal">打开模态框</button><!-- 使用方法事件处理器 --><!-- <MyModal :isShow="isShow" @closeModal="closeModal" /> --><!-- 使用$event变量 --><!-- <MyModal :isShow="isShow" @closeModal="isShow = $event" /> --><!-- 使用内联事件处理器 --><!-- <MyModal :isShow="isShow" @closeModal="(val) => isShow = val" /> --><!-- <MyModal :isShow="isShow" @update:isShow="(val) => isShow = val" /><MyModal :isShow="isShow" @update:isShow="isShow = $event" /><MyModal :isShow="isShow" @update:isShow="closeModal" /> -->// 改的就这一句,其他都一样,模态框组件代码不用变<MyModal :isShow.sync="isShow" /></div>
</template>
...
总结,对比优化1和优化2,你只需掌握优化2即可。
vue3中移除了.sync
使用 v-mode:xxx
代替了
- 注意不写
v-model
后的xx属性是不生效的,毕竟这并不是真正的v-model
代码如下:
// 父组件
<template><!-- .sync修饰符在vue3.0版本已弃用,应该使用v-model:xxx --><MyDemo v-model:msg="msg" />
</template><script setup name="App">
import { ref } from 'vue'
import MyDemo from './components/MyDemo'const msg = ref('hello')
</script><style>
</style>// 子组件
<script setup>
defineProps(['msg'])
defineEmits(['update:msg'])
</script><template><h1>{{ msg }}</h1><button @click="emit('update:msg', '数据改变了')">changeMsg</button>
</template><style></style>
欢迎评论区一起讨论呀~