Vue 自定义组件使用v-model
2017-07-20 10:19
1031 查看
正常的业务需求中,我们需要封装一些常用的组件。现在有一个最简单的需求,封装一个有特定样式的input框,够简单吧? 好,我们来这样封装:
字符串模板文件命名为 CInput.vue:
ok,我们在父组件中引用此组件,父组件的data函数长这样:
父组件里面引用子组件的代码长这样:
加载页面,ok,完全正常,但是我们在输入框体里面输入值,修改name的值的时候:
会出现警告:
警告的意思是说,不应该直接将父元素传递给子元素的属性直接挂在到子组件上面【双向绑定】。应该在子组件的data或者计算属性里面基于这个属性来初始化数据。 参考资料:单向数据流
当父组件的属性变化时,将传导给子组件,但是不会反过来。这是为了防止子组件无意修改了父组件的状态——这会让应用的数据流难以理解。
子组件修改父组件数据,最好是通过 eventHub or vuex来实现。当然特定场景使用简单粗暴的this.$parent.xx来修改吧。
回到正题,现在这样来做是肯定不行的,所以后来,我瞎X尝试【当然这个方法本身是不可取的,请不要采用这个办法】,将父组件中的name的值,默认设置为一个对象,而不是null.
代码长这样
然后将子组件的v-model不是绑定name 而是绑定name.value,代码长这样:
这样我们在界面上修改值的时候,就不会报警告了。【我们拿错误的实验得到了正确的结果】。 实际上可以点击上面关于单向数据流的链接,可以知道,不应该直接改变父组件的数据,项目复杂度上去之后,难以维护,你根本不知道是谁改变了父组件里面的数据。但是特定场景是需要直接修改父元素的数据,请使用.sync修饰符
然而为什么不用v-model来用于我们自己的组件呢,v-model对数据进行双向绑定实际上是一个语法糖。比如我们对于一个input实现双向绑定。
代码长这样:
实际上是语法糖:
input上有一个Input事件,值变化的时候,会将值绑定给这个变量data。
在vue版本2.2.0之后,v-model可以配置:
1,组件定一个属性 value
2, 在有新的值触发或者说值发生变化时,触发input事件 like this:
好,现在我们来修改上面的代码:
binggo! 这样的话,就不会有⚠️了
这样也不会报错了!
当然如果子组件里面还有 第三层其他的自定义组件(父亲->子组件->孙子组件),你可能需要监听在子组件里面的v-model=”data” 的data值,使用
字符串模板文件命名为 CInput.vue:
<template> <input type="text" class="your-custom-class-name" v-model="name" > </template> <style lang="scss"> .your-custom-class-name { ... } </style> <script> export default { props: { name: String } } </script>
ok,我们在父组件中引用此组件,父组件的data函数长这样:
data () { return { name: null, ... //other data } }
父组件里面引用子组件的代码长这样:
加载页面,ok,完全正常,但是我们在输入框体里面输入值,修改name的值的时候:
会出现警告:
警告的意思是说,不应该直接将父元素传递给子元素的属性直接挂在到子组件上面【双向绑定】。应该在子组件的data或者计算属性里面基于这个属性来初始化数据。 参考资料:单向数据流
当父组件的属性变化时,将传导给子组件,但是不会反过来。这是为了防止子组件无意修改了父组件的状态——这会让应用的数据流难以理解。
子组件修改父组件数据,最好是通过 eventHub or vuex来实现。当然特定场景使用简单粗暴的this.$parent.xx来修改吧。
回到正题,现在这样来做是肯定不行的,所以后来,我瞎X尝试【当然这个方法本身是不可取的,请不要采用这个办法】,将父组件中的name的值,默认设置为一个对象,而不是null.
代码长这样
data () { return { name: { value: null } } }
然后将子组件的v-model不是绑定name 而是绑定name.value,代码长这样:
<input type="text" class="your-custom-class-name" v-model="name.value" >
这样我们在界面上修改值的时候,就不会报警告了。【我们拿错误的实验得到了正确的结果】。 实际上可以点击上面关于单向数据流的链接,可以知道,不应该直接改变父组件的数据,项目复杂度上去之后,难以维护,你根本不知道是谁改变了父组件里面的数据。但是特定场景是需要直接修改父元素的数据,请使用.sync修饰符
然而为什么不用v-model来用于我们自己的组件呢,v-model对数据进行双向绑定实际上是一个语法糖。比如我们对于一个input实现双向绑定。
代码长这样:
<input v-model="data">
实际上是语法糖:
<input v-bind:value="data" v-on:input="data = $event.target.value">
input上有一个Input事件,值变化的时候,会将值绑定给这个变量data。
在vue版本2.2.0之后,v-model可以配置:
1,组件定一个属性 value
2, 在有新的值触发或者说值发生变化时,触发input事件 like this:
this.$emit('input', newValue)
好,现在我们来修改上面的代码:
<template> <input type="text" :value="currentValue" @input="handleInput"> </template> <script> export default { data () { return { currentValue: this.value //不直接绑定prop,而是在data 或者 computed 里面根据prop初始化自己领域的值 } }, props: { value: [String, Number] // key code }, methods: { handleInput() { const value = event.target.value this.currentValue = value this.$emit('input', value) // key code } } } </script>
binggo! 这样的话,就不会有⚠️了
//父元素的data长这样
data () { return { name: null, ... //other data } }
//引用子组件
<c-input v-model="name"> </c-input>
这样也不会报错了!
当然如果子组件里面还有 第三层其他的自定义组件(父亲->子组件->孙子组件),你可能需要监听在子组件里面的v-model=”data” 的data值,使用
watch,如果这个值发生了变化,调用
this.$emit('input', newValue)。
相关文章推荐
- vue如何在自定义组件中使用v-model
- 使用vue的v-model自定义 checkbox组件
- vue 自定义组件使用v-model
- Vue 自定义组件使用v-model
- Vue之自定义组件的v-model
- vue 自定义全局方法,在组件里面的使用介绍
- 自定义vue全局组件use使用、vuex的使用详解
- vue组件化挖矿之旅(三):vue-cli 自定义过滤器的使用
- 利用vue组件自定义v-model实现一个Tab组件方法示例
- 自定义vue全局组件use使用、vuex的使用
- 自定义vue全局组件use使用
- 详解VUE自定义组件中用.sync修饰符与v-model的区别
- vue--自定义全局方法,在组件里面使用
- 浅析Vue自定义组件的v-model
- vue2.x自定义组件上使用v-model指令
- 浅谈 Vue v-model指令的实现原理 - 如何利用v-model设计自定义的表单组件
- vue--自定义全局方法,在组件里面使用
- 浅谈vue自定义全局组件并通过全局方法 Vue.use() 使用该组件
- 自定义vue全局组件use的使用
- vue 自定义组件 v-model双向绑定、 父子组件同步通信