Vue 自界说组件完成 v-model 的几种方法

前语

在 Vue 中,v-model 是一个常用的指令,用于完成表单元素和组件之间的双向绑定。当咱们运用原生的表单元素时,直接运用 v-model 是很便利的,可是对于自界说组件来说,要完成相似的双向绑定功能就需求一些额外的处理。

本篇文章将介绍几种在自界说组件中完成 v-model 的方法,首要如下:

  • 运用 v-model 特点:适用于表单元素

  • 界说 model 特点:适用于非表单元素

除了以上的两种方法外,还有咱们通常运用的.sync 修饰符(2.3.0 新增),首要区别在于运用方法的不同,前者直接运用 v-model,后者运用 .sync 修饰符进行绑定

一. 单向数据流

一切的 prop 都使得其父子 prop 之间形成了一个单向下行绑定:父级 prop 的更新会向下流动到子组件中,可是反过来则不可。这样会防止从子组件意外改变父级组件的状态,然后导致你的运用的数据流向难以了解。

留意:每次父级组件发生改变时,子组件中一切的 prop 都将会刷新为最新的值。这意味着你不应该在一个子组件内部改变 prop。尽管能够,可是如果你这样做了,Vue 会在浏览器的控制台中宣布警告。

二. 根底原理浅析

v-model 实践上就是 props:value$emit('input') 的组合语法糖,简单来说,v-model 的运用其实做了两个比较重要的操作,了解这两个操作,咱们就能够轻松完成组件的自界说 v-model

  1. v-bind 绑定 value 特点的值 – props:value;

  2. v-on 绑定 input 事情监听到函数中,函数会获取最新的值赋值到绑定的特点中 – $emit(‘input’);

三. 完成 v-model 的两种方法

1. 直接运用 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 进行 “双向绑定”。可是,真正的双向绑定会带来维护上的问题,由于子组件能够改变父组件,且在父组件和子组件两侧都没有明显的改变来历。

这也是为什么咱们引荐以 update:myPropName 的模式触发事情取而代之。

举个例子,还是上面的计数器的例子,在一个包含 countprop 的计数组件中,咱们能够用以下方法表达对其赋新值的意图:

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 修饰符也是进行自界说组件双向绑定的优秀挑选,因此在实践开发中,挑选合适自己项目需求的方法是最重要的。

参考资料

Prop

自界说事情

.sync修饰符