马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
×
媒介
在 Vue 中,v-model 是一个常用的指令,用于实现表单位素和组件之间的双向绑定。当我们利用原生的表单位素时,直接利用 v-model 是很方便的,但是对于自界说组件来说,要实现类似的双向绑定功能就须要一些额外的处置惩罚。
本篇文章将先容几种在自界说组件中实现 v-model 的方式,紧张如下:
- 利用 v-model 属性:实用于表单位素
- 界说 model 属性:实用于非表单位素
除了以上的两种方式外,另有我们通常利用的`.sync` 修饰符[1](2.3.0+ 新增),紧张区别在于利用方式的差别,前者直接利用 v-model,后者利用 .sync 修饰符举行绑定
一. 单向数据流
全部的 prop 都使得其父子 prop 之间形成了一个单向下行绑定:父级 prop 的更新会向下运动到子组件中,但是反过来则不可。如许会防止从子组件不测变动父级组件的状态,从而导致你的应用的数据流向难以明白。
注意:每次父级组件发生变动时,子组件中全部的 prop 都将会革新为最新的值。这意味着你不应该在一个子组件内部改变 prop。固然可以,但是假如你如许做了,Vue 会在欣赏器的控制台中发出告诫。
二. 底子原理浅析
v-model 实际上就是 props:value 和 $emit('input') 的组合语法糖,简朴来说,v-model 的利用实在做了两个比力紧张的利用,明白这两个利用,我们就可以轻松实现组件的自界说 v-model
- v-bind 绑定 value 属性的值 - props:value;
- v-on 绑定 input 变乱监听到函数中,函数会获取最新的值赋值到绑定的属性中 - $emit('input');
三. 实现 v-model 的两种方式
1. 直接利用 v-model 属性
实用于表单位素,大概原组件已经实现了 v-model,须要我们举行二次封装
以 input 表单位素为例,在 vue 中,我们可以直接利用 v-model 举行绑定命据,当我们在实现自界说组件custom-component举行封装 input 时,我们的组件对外袒露时也须要利用 v-model,看下面我们应该怎样实现:
在自界说组件中,我们可以通过在组件内部利用 value 属性和手动触发 input 变瞎搅实现 v-model 的双向绑定效果。详细实现如下:
- <template>
- <input v-model="newValue" />
- </template>
- <script>
- export default {
- props: {
- value: {
- type: Boolean,
- default: false,
- },
- },
- computed: {
- newValue: {
- get() {
- return this.value;
- },
- set(val) {
- this.$emit("input", val);
- },
- },
- },
- };
- </script>
复制代码 利用custom-component
- <custom-component v-model="newValue" />
复制代码 在上述代码中,我们通过 value 属性吸收父组件传入的值,而且利用 computed 的 set 属性用来监听值的更新,手动触发 $emit('input', value) 来将新值转达给父组件,从而实现双向绑定的效果。
2. 界说 model 属性
实用于非表单位素,完全非表单位素自界说的组件
Vue 答应我们在界说组件中通过界说 model 属性来简化 v-model 的利用。通过界说 model 属性,我们可以指定组件中哪个属性的值应该作 v-model 的值。
假如我们实现一个计数器的组件custom-counter,在页面中体现两个按钮,点击按钮可以举行数值的加减利用,详细示比方下:
- <template>
- <div>
- <button @click="increment">+</button>
- <span>{{ value }}</span>
- <button @click="decrement">-</button>
- </div>
- </template>
- <script>
- export default {
- // 当 model 为默认值时,可以将其省略
- model: {
- prop: "value", // 默认是 value
- event: "input", // 默认是 input
- },
- props: {
- value: {
- type: Number,
- default: 0,
- },
- },
- methods: {
- increment() {
- this.$emit("input", this.value + 1);
- },
- decrement() {
- this.$emit("input", this.value - 1);
- },
- },
- };
- </script>
复制代码 提示:当 model 为默认值时,可以将其省略
父组件中利用custom-counter
- <template>
- <div>
- <custom-counter v-model="count"></custom-counter>
- <p>计数器的值为:{{ count }}</p>
- </div>
- </template>
- <script>
- import CustomCounter from "./CustomCounter.vue";
- export default {
- components: {
- CustomCounter,
- },
- data() {
- return {
- count: 0,
- };
- },
- };
- </script>
复制代码 演示效果如下图所示:
在上面的示例中,CustomCounter组件吸收一个value属性来吸收父组件转达的值,并在点击按钮时修改value属性的值。通过调用this.$emit('input', newValue)触发input变乱,将新的value值转达给父组件举行更新。
在父组件中,利用v-model将父组件中的count属性绑定到CustomCounter组件的value属性上,绑定 input 变乱监听到函数中,从而实现了数据的双向绑定。
model 是答应 vue 自界说组件利用 v-model 的关键,固然偶然我们不显性的利用它,也不影响我们在自界说组件中利用 v-model 指令,这只是由于被设置默认值。而有的时间,体现的利用,并自界说 model 的 prop 和 event 会有益。
注意:答应一个自界说组件在利用 v-model 时定制 prop 和 event。默认环境下,一个组件上的 v-model 会把 value 用作 prop 且把 input 用作 event,但是一些输入范例比如单选框和复选框按钮大概想利用 value prop 来到达差别的目的。利用 model 选项可以回避这些环境产生的辩论。
四. .sync 修饰符
实用于提供于多个双向绑定的 prop,机动提供你想要绑定的 property 名
在有些环境下,我们大概须要对一个 prop 举行 “双向绑定”。但是,真正的双向绑定会带来维护上的标题,由于子组件可以变动父组件,且在父组件和子组件两侧都没有显着的变动泉源。
这也是为什么我们保举以 update:myPropName 的模式触发变乱取而代之。
举个例子,还是上面的计数器的例子,在一个包罗 count prop 的计数组件中,我们可以用以下方法表达对其赋新值的意图:
- this.$emit("update:count", newCount);
复制代码 然后父组件可以监听谁人变乱并根据须要更新一个本地的数据 property。比方:
- <custom-counter v-bind:count="count" v-on:update:count="count = $event" />
复制代码 我们为这种模式提供一个缩写,即 .sync 修饰符,如下:
- <custom-counter :count.sync="count"></custom-counter>
复制代码 以上的两种写法是等价的
注意:带有 .sync 修饰符的 v-bind 不能和表达式一起利用 (比方 v-bind:count.sync=”count + 1” 是无效的)。取而代之的是,你只能提供你想要绑定的 property 名,类似 v-model。
五. 总结
本篇文章先容了在 Vue 自界说组中实现 v-model 的几种方式,包罗界说 model 属性和利用 v-model 属性。通过以上案例实际分析,信任各人都已经相识这几种方式的创建以及应用场景,以便更加机动地应用到实际项目中。
以上面两种方式为例,我们可以机动地根据自己的需求选择符合的方式来实现自界说组件 v-model。假如是表单位素,可以直接利用 v-model 属性;假如黑白表单位素,可以通过界说 model 属性指定组件中哪个属性的值应该作 v-model 的值。
除此之外,利用 .sync 修饰符也是举行自界说组件双向绑定的精良选择,因此在实际开发中,选择恰当自己项目需求的方式是最紧张的。
参考资料
Prophttps://v2.cn.vuejs.org/v2/guide/components-props.html
自界说变乱https://v2.cn.vuejs.org/v2/guide/components-custom-events.html
.sync 修饰符https://v2.cn.vuejs.org/v2/guide/components-custom-events.html#sync-%E4%BF%AE%E9%A5%B0%E7%AC%A6
|