大家好!我是木瓜太香!一名前端工程师,之前写过一篇《vue父子组件状态同步的最佳方式》,这篇文章描述了大多数情况下的父子组件同步的最佳方式,也是被开源中国官方推荐了,在这里表示感谢!

这次作为续章是对上一篇文章的特殊情况的补充,并会给出较详细的描述与代码演示,当然如果你单看这篇文章来解决特定问题也是可行的。

对于父子组件状态同步,这篇文章 《vue父子组件状态同步的最佳方式》 讲述了大多数情况下的最优解,但是当我们希望自己创建的可复用组件和封装的逻辑能够尽量行为一致的时候情况可能会有所不同,举个例子,我们现在要封装一个输入框组件叫做 MyInput 我们知道普通的输入框通常会使用 v-model 来做双向数据绑定,这里如果想让封装的 MyInput 组件在使用上与普通的输入框是一致的,我们就难免要让自定义组件也支持 v-model 指令,这之中其实本质上也会涉及到父子组件的状态同步问题,使用我们之前讲的方式也能基本实现,只是借助 vue 暴露出来的 api 可以让我们写法更优雅,接下来我们使用不同的方式来实现这个组件。

原来的实现方式

自定义的MyInput组件

<template>
<div class="myInput">
<!-- 这里只能用 vModel 不可以使用横杠写法 -->
<input type="text" :value="vModel" @input="inputHandle">
</div>
</template> <script>
export default {
name: "MyInput",
props: {
// 这里也可以写成 'v-model': String 但是建议根据风格来,如果左边都没有引号就直接驼峰
vModel: String
},
methods: {
inputHandle (event) {
// 注意:这里使用 update:v-model 或 update:vModel 都可以
this.$emit("update:v-model", event.target.value)
}
} }
</script>

使用方式

// 方式一
<my-input :v-model="text" @update:v-model="text = $event"></my-input>
// 方式二
<my-input :v-model.sync="text"></my-input>

可以看到,原来的方式也能实现,但是就使用来说v-model被当成属性,一定要在前面加上:才可以用动态属性,结果就变成了:v-model,然后我们为了简化写法去掉事件绑定,我们最终的效果就是 :v-model.sync这种写法总会让人觉得怪怪的,接下来我们就来解决这个问题

vue-api的方式实现

自定义的MyInput组件

<template>
<div class="myInput">
<input type="text" :value="value" @input="inputHandle">
</div>
</template> <script>
export default {
name: "MyInput",
props: {
value: String
},
methods: {
inputHandle (event) {
this.$emit("input", event.target.value)
}
} }
</script>

使用方式

<my-input v-model="text"></my-input>

看到这里可能一部分同学会一脸懵逼,这就同步了?emm,其实还真同步了,那 value 从哪儿来的,input 事件也没绑定啊,的确这些都被我们省略掉了,其实这是 vue 的 api 带给我们的便利,在我们试图向自定义组件传入 v-model 这个特殊的属性的时候,vue 会帮我们做两件事,一件是将 v-model 中的值作为 value 的值向下传递,这是我们在内部要写 props value 的原因,另一件是在当前自定义组件上监听 input 事件,并在触发改事件的时候,将第一个参数赋值给 v-model 中的变量。你可以看到在我们肉眼不可见的地方 vue 为我们做了很多实际,但是大家要明白他为什么给你做这么多,仔细想想不难看出,这些逻辑是业务场景中重复次数很多的逻辑, vue 不给你做,你自己也要做,还会闲麻烦!当然这还没结束呢!下面更精彩!

为属性 value 和事件 input 命名

有些时候我们可能希望 value 就作为一个普通的属性往下传,而我们的业务场景里面 input 作为事件也不够形象,反正就是 value 和 input 不符合你的业务中的语义,这个时候我想改名,咋办?接下来看下面的代码:

<template>
<div class="myInput">
<input type="text" :value="text" @input="inputHandle">
</div>
</template> <script>
export default {
name: "MyInput",
model: {
prop: "text", // 该属性名
event: "update:v-model" // 改事件名
}
props: {
text: String // 即便改名了,这里也必不可少
},
methods: {
inputHandle (event) {
this.$emit("update:v-model", event.target.value)
}
} }
</script>

上面就展示了我们怎么更名,其实就是改变了 props 中的接受的字段名,然后新增了 model 选项,这里需要注意的是,不管怎么样 props 中的字段都必不可少。

实际应用:父子组件状态同步

如标题所说,这个 api 依然可以用作一些特殊情况下的父子组件状态同步,这里举一个实际的列子,假设我们使用某框架,这个框架提供给我们模态框组件名叫 Modal 这个组件需要添加 v-model 属性来显示隐藏模态框,通常我们的模态框会有很多的逻辑,这个时候我们会考虑将其封装成一个自定义的组件,这个时候我们希望封装过得组件和原来的模态框组件具备相同的使用方式都是加 v-model 来显示隐藏,这是时候我们讲到的功能是不是就特别合适了呢?

有前端问题需要讨论的可以加我的qun:237871108。也可以通过哔哩哔哩搜索木瓜太香找到我。

vue父子组件状态同步的最佳方式续章(v-model篇)的更多相关文章

  1. vue父子组件状态同步的最佳方式

    哈喽!大家好!我是木瓜太香,一位老牌儿前端工程师,平时我们在使用 vue 开发的时候,可能会遇到需要父组件与子组件某个状态需要同步的情况,通常这个是因为我们封装组件的时候有一个相同的状态外面要用,里面 ...

  2. vue父子组件路由传参的方式

    一.get方式(url传参): 1.动态路由传参: 父组件: selectItem (item) { this.$router.push({ path: `/recommend/${item.id}` ...

  3. 【Vue课堂】Vue.js 父子组件之间通信的十种方式

    这篇文章介绍了Vue.js 父子组件之间通信的十种方式,不管是初学者还是已经在用 Vue 的开发者都会有所收获.无可否认,现在无论大厂还是小厂都已经用上了 Vue.js 框架,简单易上手不说,教程详尽 ...

  4. vue组件定义方式,vue父子组件间的传值

    vue组件定义方式,vue父子组件间的传值 <!DOCTYPE html> <html lang="zh-cn"> <head> <met ...

  5. vue父子组件之间传值

    vue父子组件进行传值 vue中的父子组件,什么是父组件什么是子组件呢?就跟html标签一样,谁包裹着谁谁就是父组件,被包裹的元素就是子组件. 父组件向子组件传值 下面用的script引入的方式,那种 ...

  6. vue父子组件的传值总结

    久违的博客园我又回来了.此篇文章写得是vue父子组件的传值,虽然网上已经有很多了.写此文章的目的就是记录下个人学习的一部分.接下来我们就进入主题吧! 在开发vue项目中,父子组件的传值是避免不掉的. ...

  7. 【转】vue父子组件之间的通信

    vue父子组件之间的通信 在vue组件通信中其中最常见通信方式就是父子组件之中的通性,而父子组件的设定方式在不同情况下又各有不同.最常见的就是父组件为控制组件子组件为视图组件.父组件传递数据给子组件使 ...

  8. Vue父子组件生命周期

    转载自:https://blog.csdn.net/a8725585/article/details/79092505 vue父子组件钩子函数触发顺序 beforeMount后mounted前构造子组 ...

  9. vue父子组件传值加例子

    例子:http://element-cn.eleme.io/#/zh-CN/component/form         上进行改的 父传子:用prop:子组件能够改变父组件的值,是共享的,和父操作是 ...

随机推荐

  1. 单元测试新方法:用setUp方法 @Before注释

    public class CentralizedPUDMatchServicePacTest { PacMatchService pacMatchService; @Before public voi ...

  2. 【NOI2014】魔法森林 - 动态加边SPFA

    题目描述 为了得到书法大家的真传,小 E 同学下定决心去拜访住在魔法森林中的隐 士.魔法森林可以被看成一个包含 n 个节点 m 条边的无向图,节点标号为 1,2,3,…,n,边标号为 1,2,3,…, ...

  3. jqgrid 获取选中用户的数据插入

    因为查询出的表和被插入的表不是在同一个数据库,所以先从前台jqgrid表格中获取到数据后,再插入表中. 实现: 获取到jqgrid选中 的每行数据之后,发ajax请求把数据以json格式传入后台,后台 ...

  4. echarts 导出为word文档

    https://www.jianshu.com/p/5bd47ab59bbe 主要思路:前台echarts生成图片后,获取base64码,传给后台解析,然后写入freemarker模板,进行下载. 图 ...

  5. Flutter 状态管理之BLoC

    在正式介绍 BLoC之前, 为什么我们需要状态管理.如果你已经对此十分清楚,那么建议直接跳过这一节.如果我们的应用足够简单,Flutter 作为一个声明式框架,你或许只需要将 数据 映射成 视图 就可 ...

  6. C++多线程基础教程

    目录 1 什么是C++多线程? 2 C++多线程基础知识 2.1 创建线程 2.2 互斥量使用 lock()与unlock(): lock_guard(): unique_lock: conditio ...

  7. C++ Templates (2.1 类模板Stack的实现 Implementation of Class Template Stack)

    返回完整目录 目录 2.1 类模板Stack的实现 Implementation of Class Template Stack 2.1.1 声明类模板 Declaration of Class Te ...

  8. python3在科学计算中的三种常用数据结构

    在科学研究中,数据运算是必不可少的,下面介绍python语言在科学计算中常用的数据结构和运算函数. 主要数据结构: (1)列表,用中括号表示,元素之间逗号分隔,每个元素可以是数字,字符,也可以是列表, ...

  9. Docker Run Cadvisor failed: inotify_add_watch /sys/fs/cgroup/cpuacct,cpu: no such file or directory

    原文链接:https://blog.csdn.net/poem_2010/article/details/84836816 没有找这个文件, 这是一个bug,在系统中,是cpu,cpuacct 可以去 ...

  10. 推荐一款万能抓包神器:Fiddler Everywhere

    搞IT技术的同行,相信没有几个人是不会抓包这项技能的(如果很不幸你中枪了,那希望这篇文章给你一些动力),市面上的抓包工具也有很多,常用的有:Charles.Fiddler.Burpsuite.Wire ...