网站首页 > 技术文章 正文
sync和v-model有极高的相似度,在第11篇文章中较长的解释了v-model,有兴趣可以翻看看。
这篇我们来解决sync的问题,我觉得它还比较有用,所以写一篇。
先看实例
父组件打开一个modal窗口,但是在关闭时会面临一个很重要的问题,那就是它要不要通知父组件呢?图示如下:
在这里,提出一个名词,称为组件状态的”单一数据源“原则。
单一数据源原则
通俗的说就是,父子组件状态的同步必须遵循”父祖件是状态的所有者“,也就是父祖件控制状态。它的理由大概有两点:
- 如果子组件自己关闭了,那么父组件的的visible状态还是true,这样状态就混乱了。
- 父组件中可能还有别的东西依赖父组件的这个状态。比如说,当这个弹窗弹出时,某个按钮要禁用,或者某个组件要不可见等等。也就是说除了父组件,可能还有一堆别的东西也依赖这个状态,所以父组件必须要明确知道当前的状态。
sync使用格式和实现原理
使用方式如下:
<child-modal :visible.sync="isShow"></child-modal>
也比较简单,在绑定的属性名visible后面加一个sync修饰符即可,那么Vue实际生成的我方动作如下:
//伪码
with(this){
f= function($event){
isShow = $event
}
}
可以看到和v-model几乎相同。同时,在子组件的events中创建一个事件,名为:'update:visible',伪码如下:
//伪码
events={
'update:visible': f
}
名字为:update:xx的样式。
最后,子组件在发生变化时,通过this.$emit('update:visible',value)来调用这个事件,就可以修改父组件的值。状态图示如下:
状态的双向绑定就像一个环。
总结
sync和v-model有99%的相似度,可以参考第11篇的内容。但是可以看出,sync在语境上比v-model更适合父子组件状态的同步,而且主要看它的思想,就是sync主要解决的是什么问题,它在实际开发中使用很广泛。
完整的实验代码
在这个代码中,完整模拟了上面的理论。
<div id="app">
<!-- 1.依赖isShow的元素 -->
<h2 v-if="!isShow">我是依赖isShow状态的元素</h2>
<!-- 2.打开modal -->
<button @click="isShow = true">打开弹窗</button>
<!-- 3.弹窗的显隐 -->
<child-modal :visible.sync="isShow"></child-modal>
</div>
<script src="../vue.js"></script>
<script>
Vue.component('child-modal', {
props: ['visible'], // 接收父组件的 visible 属性
template: `
<div style="border:1px solid red" v-if="visible">
<p>我是弹窗内容</p>
<button @click="close">关闭</button>
</div>
`,
methods: {
close() {
this.updateVisible(false)
},
//封装一个方法
updateVisible(value){
this.$emit('update:visible',value)
}
}
});
new Vue({
data() {
return {
isShow: false // 控制弹窗显示的状态
}
}
}).$mount('#app')
</script>
猜你喜欢
- 2025-10-14 SpringBoot Jar包冲突在线检测_springboot jar war
- 2025-10-14 前端笔记:HTML output标签介绍及用法
- 2025-10-14 前端切图css高级阴影用法drop-shadow
- 2025-10-14 CSS 颜色体系详解_css颜色写法
- 2025-10-14 仅使用一个 DIV 配合 CSS 实现饼状图
- 2025-10-14 Python——Html(表格, , ,、表单 、自定义标签 和)
- 2025-10-14 Python疯狂练习60天——第十五天_疯狂python讲义电子版
- 2024-08-09 网页制作里的边框border常见用法(包含圆角)【210】
- 2024-08-09 总结Css 常用的操作(css基本操作)
- 2024-08-09 css实现渐变色圆角边框(css渐变背景色)
- 最近发表
- 标签列表
-
- cmd/c (90)
- c++中::是什么意思 (84)
- 标签用于 (71)
- 主键只能有一个吗 (77)
- c#console.writeline不显示 (95)
- pythoncase语句 (88)
- es6includes (74)
- sqlset (76)
- apt-getinstall-y (100)
- node_modules怎么生成 (87)
- chromepost (71)
- flexdirection (73)
- c++int转char (80)
- mysqlany_value (79)
- static函数和普通函数 (84)
- el-date-picker开始日期早于结束日期 (76)
- js判断是否是json字符串 (75)
- c语言min函数头文件 (77)
- asynccallback (87)
- localstorage.removeitem (77)
- vector线程安全吗 (70)
- java (73)
- js数组插入 (83)
- mac安装java (72)
- 无效的列索引 (74)