美文网首页
17.组件的v-model

17.组件的v-model

作者: 静昕妈妈芦培培 | 来源:发表于2021-08-21 08:12 被阅读0次

input的数据的双向绑定

我们在input中可以使用v-model来完成数据的双向绑定:

  • 这个时候往往会非常方便,因为v-model默认帮助我们完成了两件事;
  • v-bind:value的数据绑定和@input的事件监听;
<template>
  <div>
    <input v-model="message" />
    <!--v-model其实是下面的简写-->
    <input :value="message" @input="message = $event.target.value" />
  </div>
</template>

<script>
import Home from "./Home.vue";
export default {
  components: {
    Home,
  },
  data() {
    return {
      message: "今天天气不错",
    };
  },
  methods: {},
};
</script>

<style scoped></style>

组件的v-model

如果我们现在封装了一个组件HyInput.vue,其他地方在使用这个组件时,是否也可以使用v-model来同时完成这两个功能呢?

  • 也是可以的,vue也支持在组件上使用v-model;

App.vue

<template>
  <div>
    <h1>App:{{ message }}</h1>
    <hy-input v-model="message" />
    <!--组件的v-model是下面的简写,默认绑定的属性是modelValue-->
    <hy-input :modelValue="message" @update:modelValue="message = $event"/>
  </div>
</template>

<script>
import HyInput from "./Hy-input.vue";
export default {
  components: {
    HyInput,
  },
  data() {
    return {
      message: "今天天气不错",
    };
  },
  methods: {},
};
</script>

<style scoped></style>

HyInput.vue

<template>
  <div>
    <h1>hy-input:{{ modelValue }}</h1>
    <button @click="btnClick">按钮</button>
  </div>
</template>

<script>
export default {
  props: {
    modelValue: {//组件的v-model默认绑定的属性名为modelValue
      type: String,
      default: "",
    },
  },
  emits: ["update:modelValue"],
  data() {
    return {};
  },
  methods: {
    btnClick() {
      this.$emit("update:modelValue", "明天有暴雨");
    },
  },
};
</script>

<style scoped></style>

点击按钮,App.vue中变量message的值改变了,HyInput中的modelValue的值也改变了


image.png

HyInput.vue内部绑定modelValue的值的是input输入框

那么,为了我们的HyInput组件可以正常的工作,这个组件内的 <input> 必须:

  • 将其 value attribute 绑定到一个名叫 modelValue 的 prop 上;
  • 在其 input 事件被触发时,将新的值通过自定义的 update:modelValue 事件抛出;
<template>
  <div>
    <input :value="modelValue" @input="onChange" />
  </div>
</template>

<script>
export default {
  props: {
    modelValue: {
      //组件的v-model默认绑定的属性名为modelValue
      type: String,
      default: "",
    },
  },
  emits: ["update:modelValue"],
  data() {
    return {};
  },
  methods: {
    onChange(e) {
      this.$emit("update:modelValue", e.target.value);
    },
  },
};
</script>

<style scoped></style>

image.png

computed实现

我们依然希望在组件内部按照双向绑定的做法去完成,应该如何操作呢?我们可以使用计算属性的setter和getter来完成。

HyInput.vue

<template>
  <div>
    <input v-model="value" />
  </div>
</template>

<script>
export default {
  props: {
    modelValue: {
      //组件的v-model默认绑定的属性名为modelValue
      type: String,
      default: "",
    },
  },
  emits: ["update:modelValue"],
  computed: {
    value: {
      get() {
        return this.modelValue;
      },
      set(newVal) {
        this.$emit("update:modelValue", newVal);
      },
    },
  },
};
</script>

<style scoped></style>

组件的v-model绑定多个属性

组件的v-model默认绑定的属性名为modelValue,我们可以通过v-model:属性名的方式,制定v-model绑定的属性名
App.vue

<template>
  <div>
    <h1>App:{{ title }}</h1>
    <div>App:{{ message }}</div>
    <hy-input v-model="message" v-model:modelTitle="title"/>
  </div>
</template>

<script>
import HyInput from "./Hy-input.vue";
export default {
  components: {
    HyInput,
  },
  data() {
    return {
      message: "今天天气不错",
      title: "天气情况"
    };
  },
  methods: {},
};
</script>

<style scoped></style>

HyInput.vue

<template>
  <div>
    <input v-model="title" />
    <input v-model="message" />
  </div>
</template>

<script>
export default {
  props: {
    modelValue: {
      //组件的v-model默认绑定的属性名为modelValue
      type: String,
      default: "",
    },
    modelTitle: {
      //自定义v-model绑定的属性名为modelTitle
      type: String,
      default: "",
    },
  },
  emits: ["update:modelValue", "update:modelTitle"],
  computed: {
    title: {
      get() {
        return this.modelTitle;
      },
      set(newVal) {
        this.$emit("update:modelTitle", newVal);
      },
    },
    message: {
      get() {
        return this.modelValue;
      },
      set(newVal) {
        this.$emit("update:modelValue", newVal);
      },
    },
  },
};
</script>

<style scoped></style>

image.png

此文档主要内容来源于王红元老师的vue3+ts视频教程

相关文章

网友评论

      本文标题:17.组件的v-model

      本文链接:https://www.haomeiwen.com/subject/cxmtiltx.html