

vue父子组件状态同步的最佳方式
source link: http://www.cnblogs.com/o00o/p/13642978.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

哈喽!大家好!我是木瓜太香,一位老牌儿前端工程师,平时我们在使用 vue 开发的时候,可能会遇到需要父组件与子组件某个状态需要同步的情况,通常这个是因为我们封装组件的时候有一个相同的状态外面要用,里面也要用,今天我们就来看看怎么优雅的解决这个问题吧!
一般来说我们实现这个功能,只需要父组件通过 props
传递给子组件就好了,但是理想很丰满,现实很骨感,如果我们直接在子组件更改传进来的 props
,不出意外浏览器会给你一坨大红色的报错,因为在 vue 中我们的数据流动是自上而下的,而子组件直接更改父组件传来的 props
则是自下而上的数据流动,这是 vue 不允许的。
所以通常我们的解决办法是,父组件通过 props 传入状态给子组件,子组件通过 props 来初始化另外一个内部的状态,子组件每次更改状态之后都通知父组件,然后由父组件来更改自己的状态,其实就是 props on emit 的应用,接下来我们来上代码。
父组件 Father.vue
<template> <div class="father"> <h1>父组件维护的状态:{{food}}</h1> <son :food="food" @update:food="f => food = f"></son> </div> </template>
子组件 Son.vue
<template> <div class="son"> <h2>子组件中维护的状态:{{innerFood}}</h2> <button @click="innerFood = '100斤牛肉'">点击更改子组件状态</button> </div> </template> <script> export default { data () { return { innerFood: this.food } }, props: { food: String }, watch: { innerFood (nv) { this.$emit("update:food",nv) } } } </script>
可以看到我们上述的写法,其实是维护了父子组件中的不同的两个状态,我们做的工作只是将这两个状态同步了,这种写法没有任何问题,其实对于子组件的部分我们也可以通过 computed 来实现,下面我们来看一看另一种子组件内维护同步状态的方法:
子组件 Son.vue 的另一种写法
<template> <div class="son"> <h2>子组件中维护的状态:{{innerFood}}</h2> <button @click="innerFood = '100斤牛肉'">点击更改子组件状态</button> </div> </template> <script> export default { props: { food: String }, computed: { innerFood: { get () { return this.food }, set (nv) { this.$emit("update:food",nv) } } } } </script>
好了,两种写法我们都已经演示完毕,现在我们来优化一下父组件中的写法。
父组件中可以看到我们之前在上面绑定了一个 update:food
事件,并且使用箭头函数做了一个赋值,其实这里我们可以稍微优化一下,不要箭头函数直接赋值,因为我们触发的是自定义事件,而我们触发的时候给的第一个参数就是新值,我们可以直接通过 $event
拿到这个值,所以可以写成如下形式:
优化后的父组件
<template> <div class="father"> <h1>父组件维护的状态:{{food}}</h1> <son :food="food" @update:food="food = $event"></son> </div> </template>
到这里你以为就结束了?其实我们还可以更近一步,只要满足我们以上的事件命名方式,我们实际上可以使用 sync
修饰符代替事件的绑定,也就是我们不用写事件绑定了,但是子组件内部的事件触发依然不能少,最终优化的结果如下:
<template> <div class="father"> <h1>父组件维护的状态:{{food}}</h1> <son :food.sync="food"></son> </div> </template>
到此我们就真的完成了父子组件的同步,当然在子组件中维护一个状态不一定是必须的,如果我们只用父组件传给我们的 props
做展示,而子组件没有对这个 props
直接更改的行为,那么我们就不用在子组件创建另外一个状态,我们子组件想改他的时候只需要在合适的时机提交合适的事件即可,但是有一种情况我们不得不在子组件中创建另一个状态,就是我们父组件传入的状态在子组件中用于 v-model 这种双向数据绑定的功能时,由于 v-model 会自动更改值所以直接填入从父组件接受的 props 就不合适了。
有前端问题需要讨论的可以加我的qun:237871108。也可以通过哔哩哔哩搜索木瓜太香找到我。
Recommend
-
162
原本想放张老尤的照片的,烧三根香膜拜一下的,可惜图片和不上去,在前端这么mmp的时代,天天有那么多B事,在数据驱动的时候,大家都推崇数据的走向都是单向数据流,都是通过父组件去向子组件传递数据,还是那句话,那来这么多B事,只要注意点就可以了,合理的运用...
-
47
// father.js <template> <div id="father"> 这是父组件: <p>父组件</p> <Child ref="child" :msg="msg" @click="faClick"></Child> </div> &...
-
46
面试官:Vue 中父子组件通信有哪些方式? 自己先想一分钟。 无可否认,现在无论大厂还是小厂都已经用上了 Vue.js 框架,简单易上手不说,教程详尽,社区活跃,第三方套件还多。真的是前端开发人员必备技能。而且在面试当中也往往会问到关于 Vue 方面的各种问
-
43
vue项目的一大亮点就是组件化。使用组件可以极大地提高项目中代码的复用率,减少代码量。但是使用组件最大的难点就是父子组件之间的通信。 子通信父 父组件 <template> <div class="parent">...
-
46
-
15
作者:小土豆biubiubiu 博客园: www.cnblogs.com/HouJiao/ 掘金: https://juejin.im/user/58c61b436...
-
45
一. 认识组件的嵌套 组件之间存在嵌套关系: 在之前的案例中,我们只是创建了一个组件App; 如果我们一个应用程序将所有的逻辑都放在一个组件中,那么这个组件就会变成...
-
20
Vue组件库开发:另类通信方式问题:不用Vuex怎么让兄弟组件便捷通信?甚至让业务组件和内部组件通信?答案:使用eventHub如果不使用EventHub,我们想让父组件的两个子组件,甚至两个孙子组件之...
-
10
vue 使用 v-model 双向绑定父子组件的值 vu_ 2020年2月2日 上午 671 字 ...
-
5
vue的组件通信(父子之间、非父子之间)1、 props/$emits(1) v-model(input的修饰符.lazy, .number, .trim),.sync(父组件:title.sync="myTitle",子组件要this.$emit('update:title', this.title + ':: after update'))语法糖,在表单控...
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK