博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
v-model指令在组件中怎么玩
阅读量:5742 次
发布时间:2019-06-18

本文共 2599 字,大约阅读时间需要 8 分钟。

作者:孙辉,美团金融前端团队成员。15年毕业加入美团,相信技术,更相信技术只是大千世界里知识的一种,个人博客:

备注:文章内容和案例均基于Vue2(具体版本为Vue2.3.4)

笔者最近在写组件的时候,遇到了 v-model 的使用问题,在 Vue 官方文档中,有是关于 v-model 指令在组件中的使用,查阅文档后,依然不得要领,最后几番折腾,理论结合实践,终于领悟其精髓,遂成文分享之。

v-model 通常都是运用在表单组件中,在这里我们以一个 select组件为例,组件命名为 a-select

v-model写在哪?

第一个问题就是 v-model 指令是写在子组件里还是父组件里。

我在最开始写组件时就遇到这个问题,归根结底是对在组件中使用 v-model 指令的了解还处于混沌的状态。

文档中有提到

要让组件的 v-model 生效,它应该 (在 2.2.0+ 这是可配置的):

  • 接受一个 value 属性
  • 在有新的值时触发 input 事件

所以我们需要通过触发事件来实现 value 的更新,而 Vue 中:

父子组件的关系可以总结为 props down, events up

那么很明显,我们是在父组件里写 v-model

子组件怎么更新父组件的值?

那在父组件中我们可以这么写:

复制代码

告诉我们,v-model 只是一个语法糖,实际的含义是:

复制代码

那在子组件中,怎么更新父组件的值(parentValue)呢?我翻遍了文档,也没找到,但我找到了一段看似相关的 ,因为其中说了:

默认情况下,一个组件的 v-model 会使用 value 属性和 input 事件,但是诸如单选框、复选框之类的输入类型可能把 value 属性用作了别的目的

同样,我们的 select 组件的 value 值也被占用,而且没有 input事件

看来我们需要定制 v-model 了, 开始之前,我们先来把例子看懂。

Vue.component('my-checkbox', {      model: {        prop: 'checked',        event: 'change'      },      props: {        checked: Boolean,        // this allows using the `value` prop for a different purpose        value: String      },      // ...    })复制代码

新增的 model 属性值里有两个key,分别为 propevent,值分别为 checkedchange,看到这里,我们弯起嘴角,会心一笑。

model 属性值(model这个名称真是取得简明扼要啊)里的两个key其实就是 v-model 这个语法糖所代表的 prop 和 event,分别表示 该表单元素的值改变元素值时触发的事件, 在 input 中,这两个值是valueinput(默认值),在 checkbox 中表示 checkedchange

以此类推,在 select 中就表示 selectedchange

到这里,我就需要指出我们上面说的一个错误了,此时的 v-model 在父组件中的实际含义是:

复制代码

那么我们可以这么来写子组件:

    export default() {        model: {            prop: 'selected',            event: 'change'        },        props: {            selectData: {                type: Array            },        },        methods: {            emitChange(value){                this.$emit('change', value);            }        }    }复制代码

唯一的问题在于,我们需要在初始化时设置选中项,该怎么办?我们还有一个 selected 属性值没有呢。甚至官网也温馨提示我们:

注意你仍然需要显性声明 checked 属性。

所以这里我们需要显性声明 selected 属性,不过,因为有 v-model 的存在,我们可以不用在父组件里传入 selected值,是不是少了一点工作量呢?

所以子组件里是这么写的:

    export default() {        model: {            prop: 'selected',            event: 'change'        },        props: {            selectData: {                type: Array            },            selected: {                type: [String,Number]            }        },        methods: {            emitChange(value){                this.$emit('change', value);            }        }    }复制代码

当然了,作为一个完整的 select 组件,上面的示例其实是很简陋的。

完整的 select 组件代码可以看 , Demo 可以看。

done

最后,团队为了招聘方便,整了个公众号,主要是一些招聘信息,团队信息,所有的技术文章在公众号里也可以看到,对了,如果你想去美团其他团队,我们也可以帮你内推哦 ~

二维码

转载地址:http://spizx.baihongyu.com/

你可能感兴趣的文章
工作中如何做好技术积累
查看>>
怎么用sysLinux做U盘双PE+DOS??
查看>>
Spring Transactional
查看>>
shell脚本实例
查看>>
我的友情链接
查看>>
Windows Phone 7 隔离存储空间资源管理器
查看>>
Microsoft Excel 2000/2003修复工具
查看>>
apache安装报错undefined reference ssl
查看>>
关于爱情只有一句忠告
查看>>
CentOS 7下安装部署Oracle11g图文教程
查看>>
F#初学笔记06
查看>>
实战:将企业域名解析委派给企业DNS服务器
查看>>
在Lync 2013环境部署Office Web Apps
查看>>
微软大会Ignite,你准备好了么?
查看>>
读书笔记-高标管事 低调管人
查看>>
Master带给世界的思考:是“失控”还是进化
查看>>
用户和开发者不满苹果iCloud问题多多
查看>>
java.lang.UnsatisfiedLinkError:no dll in java.library.path终极解决之道
查看>>
我的工具:文本转音频文件
查看>>
【许晓笛】从零开始运行EOS系统
查看>>