首页 > 其他分享 >v-model 在vu2和vue3的使用

v-model 在vu2和vue3的使用

时间:2023-03-07 18:57:35浏览次数:49  
标签:const ChildTpl default value vu2 vue3 组件 model

首先看到v-model,大多数小伙伴都会想到“响应式”、“双向绑定”,v-model 确实是实现了双向绑定数据,用过vue的人都比较熟悉。v-model 是 Vue 内置的指令,vue2和vue3中的v-model使用有点不太一样,那具体是哪里不一样呢?

在Vue2中v-model的使用

vue2的v-model官方使用

1.在组件上使用 v-model

相当于prop中添加 value属性 并触发 input 事件:

父组件

<template>
  <div>
    <div>父组件中的---------{{count}}</div>
    <ChildTpl v-model="count" />
    <!-- 等价于 -->
    <ChildTpl :value="count" @input="value = $event" />
  </div>
</template>

<script>
import ChildTpl from '@/components/ChildTpl.vue';
export default {
  components:{
    ChildTpl
  },
  data() {
    return {
      count:0,
    };
  }
};
</script>

子组件

<template>
  <div> 
    <span>{{value}}</span>
      <button @click="changeValue">count+1</button>
  </div>
</template>
 
<script>
export default {
  data() {
    return {
    }
  },
  props:{
    value:{
      default:0,
    }
  },
  methods: {
    changeValue(){
      this.$emit('input', this.value+1)
    }
  }
}
</script>

2.如果想要更改 prop属性或事件名称,

则需要在 ChildTpl 组件中添加 model 选项:
父组件

<template>
  <div>
    <div>父组件中的---------{{ count }}</div>
    <ChildTpl v-model="count" />
    <!-- 等价于 -->
    <ChildTpl :customParams="count" @change="count = $event" />
  </div>
</template>

<script>
import ChildTpl from "@/components/ChildTpl.vue";
export default {
  components: {
    ChildTpl,
  },
  data() {
    return {
      count: 0,
    };
  },
};
</script>

子组件

<template>
  <div>
    <span>{{ customParams }}</span>
    <button @click="changeValue">count+1</button>
  </div>
</template>

<script>
export default {
  data() {
    return {};
  },
  model: {
    prop: "customParams", // 将默认value属性改为customParams
    event: "change", // 将默认input事件改为change
  },
  props: {
    customParams: {
      type: Number,
      default: 0,
    },
  },
  methods: {
    changeValue() {
      this.$emit("change", this.customParams + 1);
    },
  },
};
</script>

 

3.使用.sync修饰符实现v-model

父组件

<template>
  <div>
    <div>父组件中的---------{{ count }}</div>
    <ChildTpl :num.sync="count" />
    <!-- 等价于 -->
    <ChildTpl :num="count" @update:num="count = $event" />
  </div>
</template>

<script>
import ChildTpl from "@/components/ChildTpl.vue";
export default {
  components: {
    ChildTpl,
  },
  data() {
    return {
      count: 0,
    };
  },
};
</script>

 

子组件

<template>
  <div>
    <span>{{ num }}</span>
    <button @click="changeValue">count+1</button>
  </div>
</template>

<script>
export default {
  data() {
    return {};
  },
  props: {
    num: {
      type: Number,
      default: 0,
    },
  },
  methods: {
    changeValue() {
      this.$emit("update:num", this.num + 1);
    },
  },
};
</script>

 

 

在Vue3中v-model的使用

vue3的v-model官方使用介绍

1.在组件上使用v-model

相当于在prop添加了modelValue属性 并接收抛出 update:modelValue 事件:

父组件

<template>
  <span>父组件中的---------{{ count }}</span>
  <ChildTpl v-model="count" />
  <!-- 等价于 -->
  <ChildTpl :modelValue="count" @update:modelValue="count = $event" />
</template>

<script setup lang="ts">
import { ref } from "vue";
import ChildTpl from "./components/ChildTpl.vue";
const count = ref(0);
</script>
<style scoped>

</style>

 

子组件

<template>
  <div>
    <span>{{ modelValue }}</span>
    <button @click="changeValue">count+1</button>
  </div>
</template>

<script lang="ts" setup>
const emits = defineEmits(["update:modelValue"]);
const props = defineProps({
  modelValue: {
    type: Number,
    default: 0,
  },
});
const changeValue = () => {
  emits("update:modelValue", props.modelValue + 1);
};
</script>

 

2.给 v-model 指定参数修改默认绑定的参数名

默认情况下,v-model 在组件上都是使用 modelValue 作为 prop,并以 update:modelValue 作为对应的事件。我们可以通过给 v-model 指定一个参数来更改这些名字:


父组件

<template>
  <span>{{ count }}</span>
  <ChildTpl v-model:num="count" />
  <!-- 等价于 -->
  <ChildTpl :num="count" @update:num="count = $event" />
</template>

<script setup lang="ts">
import { ref } from "vue";
import ChildTpl from "./components/ChildTpl.vue";
const count = ref(0);
</script>

<style scoped>

</style>

 

子组件

<template>
  <div>
    <span>{{ num }}</span>
    <button @click="changeValue">count+1</button>
  </div>
</template>

<script lang="ts" setup>
const emits = defineEmits(["update:num"]);
const props = defineProps({
  num: {
    type: Number,
    default: 0,
  },
});
const changeValue = () => {
  emits("update:num", props.num + 1);
};
</script>

 

Vue3的v-model多了哪些特性

1.Vue3移除了model选项和sync修饰符实现v-model

2.Vue3支持使用多个v-model

我们可以在单个组件实例上创建多个 v-model 双向绑定
组件上的每一个 v-model 都会同步不同的 prop,而无需额外的选项
父组件

<template>
  <div>
    <span>父组件-------first:{{ first }},last:{{ last }}</span>
  </div>
  
  <ChildTpl v-model:first-name="first" v-model:last-name="last" />
  <!-- 等价于 -->
  <ChildTpl
    :first-name="first"
    :last-name="last"
    @update:first-name="first = $event"
    @update:last-name="last = $event"
  />
</template>

<script setup lang="ts">
import { ref } from "vue";
import ChildTpl from "./components/ChildTpl.vue";
const first = ref("first");
const last = ref("last");
</script>
<style scoped></style>

 

子组件

<template>
  <div>
    <input
      type="text"
      :value="firstName"
      @input="$emit('update:firstName', $event.target.value)"
    />
    <input
      type="text"
      :value="lastName"
      @input="$emit('update:lastName', $event.target.value)"
    />
  </div>
</template>

<script lang="ts" setup>
const props = defineProps({
  firstName: {
    type: String,
    default: "",
  },
  lastName: {
    type: String,
    default: "",
  },
});
</script>

 

3.自定义v-model修饰符

我们知道了 v-model 有一些内置的修饰符,例如 .trim,.number 和 .lazy。在某些场景下,你可能想要一个自定义组件的 v-model 支持自定义的修饰符,以按需处理绑定值。

比如下面自定义capitalize修饰符实现首字母大写
组件的 v-model 上所添加的修饰符,可以通过 modelModifiers prop 在组件内访问到。在下面的组件中,我们声明了 modelModifiers 这个 prop,有了这个 prop,我们就可以检查 modelModifiers 对象的键,并编写一个处理函数来改变抛出的值。

父组件

<template>
  <div>
    <span>父组件-------myText:{{ myText }}</span>
  </div>
  <ChildTpl v-model.capitalize="myText" />
</template>

<script setup lang="ts">
import { ref } from "vue";
import ChildTpl from "./components/ChildTpl.vue";
const myText = ref("first");
</script>
<style scoped></style>

 

子组件

<template>
  <div>
    <input type="text" :value="modelValue" @input="emitValue" />
  </div>
</template>

<script lang="ts" setup>
import { onMounted } from "vue";
const emits = defineEmits(["update:modelValue"]);
const props = defineProps({
  modelValue: {
    type: String,
    default: "",
  },
  modelModifiers: {
    default: () => ({ capitalize: false }),//这里为了满足ts验证默认设为false
  },
});
onMounted(() => {
  console.log(props.modelModifiers); // { capitalize: true }
});
const emitValue = (e: any) => {
  let value = e.target.value;
  if (props.modelModifiers.capitalize) {
    value = value.charAt(0).toUpperCase() + value.slice(1);
  }
  emits("update:modelValue", value);
};
</script>

 

对于又有参数又有修饰符的 v-model 绑定,

生成的 prop 名将是 arg + "Modifiers"

父组件

<template>
  <div>
    <span>父组件-------myText:{{ myText }}</span>
  </div>
  <ChildTpl v-model:title.capitalize="myText" />
</template>

<script setup lang="ts">
import { ref } from "vue";
import ChildTpl from "./components/ChildTpl.vue";
const myText = ref("first");
</script>
<style scoped></style>

子组件

<template>
  <div>
    <input type="text" :value="title" @input="emitValue" />
  </div>
</template>

<script lang="ts" setup>
import { onMounted } from "vue";
const emits = defineEmits(["update:title"]);
const props = defineProps({
  title: {
    type: String,
    default: "",
  },
  titleModifiers: {
    type: Object,
    default: () => ({}),
  },
});
onMounted(() => {
  console.log(props.titleModifiers); // { capitalize: true }
});
const emitValue = (e: any) => {
  let value = e.target.value;
  value = value.charAt(0).toUpperCase() + value.slice(1);
  emits("update:title", value);
};
</script>

 

以上是我看了文档后的总结了,如有不意见,欢迎评论指正。

参考网址

https://blog.csdn.net/qq_28378665/article/details/128784126

标签:const,ChildTpl,default,value,vu2,vue3,组件,model
From: https://www.cnblogs.com/miangao/p/17189164.html

相关文章