Vue3 模板中的变化

Vue3 模板中的变化

vue3 模板中的变化主要有以下变化:

  • 模板必须是单根节点
  • 双向绑定的变化
  • v-if 与 v-for 优先级与 key 值的变化

1.Fragment

vue2 中组件的模板必须是单根节点,出现多个根节点会报错。

而如果 vue3 组件的模板中出现多个根节点时,会自动将这些节点用fragment包裹,所以 vue3 模板可出现多个根节点

2.v-model 双向绑定的变化

vue2 中提供了两种双向绑定:v-model.sync,但在 vue3 中,去掉了.sync修饰符,只能使用v-model进行双向绑定。

但为了让v-model更好的针对多个属性进行双向绑定,vue3 作出了以下变化:

  1. 当对自定义组件使用v-model指令时,绑定的默认属性名由原来的value变为modelValue,默认事件名由原来的input变为update:modelValue
<!-- vue2 默认props属性为value 默认emit事件为input-->
<ChildComponent :value="title" @input="title = $event" />
<!-- 简写为 -->
<ChildComponent v-model="title" />

<!-- vue3 默认props属性为modelValue 默认emit事件为update:modelValue -->
<ChildComponent :modelValue="title" @update:modelValue="title = $event" />

<!-- 简写为 -->
<ChildComponent v-model="title" />
  1. 去掉了.sync修饰符,它原本的功能由v-model的参数替代
<!-- vue2 -->
<ChildComponent :title="title" @update:title="title = $event" />
<!-- 简写为 -->
<ChildComponent :title.sync="title" />

<!-- vue3 -->
<ChildComponent :title="title" @update:title="title = $event" />
<!-- 简写为 -->
<ChildComponent v-model:title="title" />
  1. v-model 在组件之间使用时,vue2 中子组件可通过model配置属性与事件名,但在 vue3 中移除了model配置属性

  2. 允许自定义v-model修饰符(vue2 无此功能)

image-20201008163021918

使用案例:自定义 v-model 修饰符capitalize,它会自动将 v-model 绑定输入的字符串值第一个字母转为大写:

<!-- 父组件 -->
<MyComponent v-model.capitalize="myText" />

当 v-model 不存在参数时,子组件通过modelModifiers这个 prop 属性名访问自定义修饰符,它默认值是一个空对象。

当 v-model 存在参数时,子组件的 prop 名将是{ {arg}}+Modifiers,子组件将通过该属性名访问修饰符。如:父组件为<MyComponent v-model:title.capitalize="myText">时,此时 prop 名为titleModifiers

<!-- 子组件 -->
<template>
  <input type="text" :value="modelValue" @input="emitValue" />
</template>

<script>
import {defineProps,defineEmits} from 'vue';
setup(){
  //声明相应的属性与事件名
  const props = defineProps({
    modelValue: String,
    modelModifiers: { default: () => ({}) }
  })
  const emit = defineEmits(['update:modelValue'])

  function emitValue(e) {
    let value = e.target.value
    //props.modelModifiers.capitalize = true 表示自定义v-model修饰符capitalize 存在
    if (props.modelModifiers.capitalize) {
      value = value.charAt(0).toUpperCase() + value.slice(1)
    }
    emit('update:modelValue', value)
  }
}
</script>

3.v-if v-for key

3.1 v-if 与 v-for 的变化

vue2 中v-for的优先级高于 v-if,如果同时使用这两个指令可能会影响性能,为此我们必须做一些操作来避免性能上的损失。

  1. 情况一:v-if 不需要使用 v-for 循环内的 item 进行判断时
    • 在外层先套一个<template>标签,并在该标签上使用 v-if 进行判断,<template>标签内部再使用 v-for 进行渲染。
  2. 情况二:v-if 需要使用 v-for 循环内的 item 进行判断时
    • 先使用 computed 计算属性代替 v-if 对 数据 进行过滤,再将过滤后的数据使用 v-for 进行渲染。

所以为了避免这个设计缺陷, vue3 中v-if 的优先级高于 v-for,并且同时使用这两个指令会导致报错。

3.2 key

vue2 中,不能给<template>标签添加 key 属性,有时要给<template>标签的每一个子节点中,会给开发者带来一定的麻烦。

而 vue3 中,当使用<template>进行v-for循环时,只需要把key值放到<template>中,而不是它的子元素中

当使用v-if v-else-if v-else分支的时候,不再需要指定key值,因为 vue3 会自动给予每个分支一个唯一的key,即便要手工给予key值,也必须给予每个分支唯一的key不能因为要重用分支而给予相同的 key

结语

这是我目前所了解的知识面中最好的解答,当然也有可能存在一定的误区。

所以如果对本文存在疑惑,可以在评论区留言,我会及时回复的,欢迎大家指出文中的错误观点。

最后码字不易,觉得有帮助的朋友点赞、收藏、关注走一波。

猜你喜欢

转载自blog.csdn.net/forward_xx/article/details/127338698