vue父子组件状态同步的最佳方式
哈喽!大家好!我是木瓜太香,一位老牌儿前端工程师,平时我们在使用 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。也可以通过哔哩哔哩搜索木瓜太香找到我。
vue父子组件状态同步的最佳方式的更多相关文章
- vue父子组件状态同步的最佳方式续章(v-model篇)
大家好!我是木瓜太香!一名前端工程师,之前写过一篇<vue父子组件状态同步的最佳方式>,这篇文章描述了大多数情况下的父子组件同步的最佳方式,也是被开源中国官方推荐了,在这里表示感谢! 这次 ...
- vue父子组件路由传参的方式
一.get方式(url传参): 1.动态路由传参: 父组件: selectItem (item) { this.$router.push({ path: `/recommend/${item.id}` ...
- 【Vue课堂】Vue.js 父子组件之间通信的十种方式
这篇文章介绍了Vue.js 父子组件之间通信的十种方式,不管是初学者还是已经在用 Vue 的开发者都会有所收获.无可否认,现在无论大厂还是小厂都已经用上了 Vue.js 框架,简单易上手不说,教程详尽 ...
- vue组件定义方式,vue父子组件间的传值
vue组件定义方式,vue父子组件间的传值 <!DOCTYPE html> <html lang="zh-cn"> <head> <met ...
- vue父子组件之间传值
vue父子组件进行传值 vue中的父子组件,什么是父组件什么是子组件呢?就跟html标签一样,谁包裹着谁谁就是父组件,被包裹的元素就是子组件. 父组件向子组件传值 下面用的script引入的方式,那种 ...
- vue父子组件的传值总结
久违的博客园我又回来了.此篇文章写得是vue父子组件的传值,虽然网上已经有很多了.写此文章的目的就是记录下个人学习的一部分.接下来我们就进入主题吧! 在开发vue项目中,父子组件的传值是避免不掉的. ...
- 【转】vue父子组件之间的通信
vue父子组件之间的通信 在vue组件通信中其中最常见通信方式就是父子组件之中的通性,而父子组件的设定方式在不同情况下又各有不同.最常见的就是父组件为控制组件子组件为视图组件.父组件传递数据给子组件使 ...
- Vue父子组件生命周期
转载自:https://blog.csdn.net/a8725585/article/details/79092505 vue父子组件钩子函数触发顺序 beforeMount后mounted前构造子组 ...
- vue父子组件传值加例子
例子:http://element-cn.eleme.io/#/zh-CN/component/form 上进行改的 父传子:用prop:子组件能够改变父组件的值,是共享的,和父操作是 ...
随机推荐
- 制作 macOS Sierra U盘USB启动安装盘方法教程 (亲测)
备注:相关镜像到apple官网下载 https://discussionschinese.apple.com/thread/250596904 进去点击"请使用这个 App Store 链接 ...
- [C#.NET 拾遗补漏]07:迭代器和列举器
大家好,这是 [C#.NET 拾遗补漏] 系列的第 07 篇文章. 在 C# 中,大多数方法都是通过 return 语句立即把程序的控制权交回给调用者,同时也会把方法内的本地资源释放掉.而包含 yie ...
- CPF 入门教程 - 数据绑定和命令绑定(二)
CPF netcore跨平台UI框架 系列教程 CPF 入门教程(一) CPF 入门教程 - 数据绑定和命令绑定(二) 数据绑定和Wpf类似,支持双向绑定.数据绑定和命令绑定是UI和业务逻辑分离的基础 ...
- 【Floyd】珍珠
[题目描述] 有n颗形状和大小都一致的珍珠,它们的重量都不相同.n为整数,所有的珍珠从1到n编号.你的任务是发现哪颗珍珠的重量刚好处于正中间,即在所有珍珠的重量中,该珍珠的重量列(n+1)/2位.下面 ...
- 你们要的MyCat实现MySQL分库分表来了
❝ 借助MyCat来实现MySQL的分库分表落地,没有实现过的,或者没了解过的可以看看 ❞ 前言 在之前写过一篇关于mysql分库分表的文章,那篇文章只是给大家提供了一个思路,但是回复下面有很多说是细 ...
- 文华财经赢顺外盘期货行情数据API接口开放代码
文华财经赢顺外盘期货行情数据API接口开放代码 怎么才能获取到外盘期货行情数据API接口呢?不少朋友就会考虑到文华财经行情API接口,本身文华财经就是一个软件提供商,提供行情API接口也 ...
- nvm -- node 多版本管理器
Node.js 越来越热,应用的场景也越来越多. 在开发中,我们可能同时在进行多个 node 项目,而这些不同的项目所使用的 node 版本又是不一样的,或者是要用更新的 node 版本进行试验和学习 ...
- SpringBoot项目 使用Jenkins进行自动化部署 (gitLab管理项目)_
1.部署服务器创建好对应文件夹和启动脚本 创建文件夹 mkdir /wdcloud/app/rps/rps-module-category 创建启动脚本 cd /wdcloud/app/rps/rps ...
- 操作系统-I/O(2)设备的分配
作业执行前对设备提出申请时,指定某台具体的物理设备会让设备分配变得简单,但如果所指定设备出现故障,即便计算机系统中有同类设备也不能运行 设备独立性:用户通常不指定物理设备,而是指定逻辑设备,使得用户作 ...
- php使用curl来获取远程图片
本文章来介绍php使用curl来获取远程图片实现方法,有需要了解采集远程图片的朋友不防进入参考. curl要求php环境支持才行. 可以运行phpinfo()函数是否支持,一般要将php.ini中;e ...