前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Vue2和3模板指令有何不同?

Vue2和3模板指令有何不同?

原创
作者头像
iwhao
发布2024-07-26 09:32:59
420
发布2024-07-26 09:32:59

Vue3作为Vue2的升级版本,带来了许多新特性和改进,这篇文章主要讲下vue3的模板指令方面,Vue模板指令是Vue框架中用于实现数据绑定和条件渲染的重要机制。在Vue3中,模板指令经历了一系列的优化和更新,使得模板编写更加灵活、高效

v-model

v-model语法糖,有两个修改和两个新增

  • 第一个修改 在自定义组件时,v-model 的 prop 和事件的默认名称发生了更改: prop 由“value”变为“modelValue”; 事件由“input”变为“update\:modelValue”;
  • 第二个修改 v-bind 的.sync 修饰符以及组件的 model 选项已被移除,不过可以在 v-model 上添加一个参数来替代
  • 第一个新增 新增的功能是如今能够在同一个组件上运用多个 v-model 绑定

这两个修改和第一个新增,之前的文章有所总结,也有实际应用例子,这里就不展开说了,可以移步 Vue 3 组件通信方式总结

下面仔细说一下 第二个新增功能

第二个新增 现在可以对 v-model 修饰符进行自定义。

例如 v-model.capitalize,.capitalize就是自定义修饰符,然后可以通过 modifiers

对模型属性进行额外的处理或修改。例如,可以使用修饰符来限制输入的值、格式化输出的值、添加验证规则等

modifiers是什么?

modifiers 是defineModel函数返回的第二个参数,它是一个对象,用于定义模型属性的修饰符。

具体使用案例,

parent.vue中使用capitalize修饰符

代码语言:javascript
复制
<template>
  <div class="parent">
    <div class="title">
      <h1>父组件</h1>
    </div>
    <child v-model.capitalize="count"></child>
  </div>
</template>

<script setup>
import { ref } from 'vue';
import child from './child.vue'
let count = ref('')
</script>

<style scoped>
.parent {
  background-color: aqua;
  width: 100vw;
  height: 100vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: space-around;
}

.title {
  margin: 10px;
}
</style>

child中 defineModel拦截set事件,判断如果有capitalize修饰符,则强制修改value的第一个字母为大写

代码语言:javascript
复制
<template>
  <div class="child">
    <h1>子组件</h1>
    <input v-model="count" />
  </div>
</template>

<script setup>

let model = defineModel({
  set(value) {
    if (modifiers.capitalize) {
      return value.charAt(0).toUpperCase() + value.slice(1);
    }
    return value;
  },
});
const [count, modifiers] = model;

</script>

<style scoped>
.child {
  width: 500px;
  height: 200px;
  background-color: #fff;
  border-radius: 20px;
  color: black;
  padding: 20px;
}
</style>

效果图

telement标签被允许拥有key属性

在 Vue 2中,<template> 标签不能拥有 key。所以一般是为每个子节点分别设置 key,

但在 Vue 3中 key 被允许设置在<template> 标签上,并且这是官方推荐的写法

v-if 与 v-for 的优先级对比

先说结论

Vue 2 版本中在一个元素上同时使用 v-if 和 v-for 时,v-for 会优先作用。

但在Vue 3 版本中 v-if 总是优先于 v-for 生效。

不管再vue2中还是vue3中都都要避免同时使用v-if 和 v-for,可以用以下几种方法

  • 计算属性过滤的v-if所限制的条件
  • 初始化list数据时先用filter根据条件进行筛选过滤
  • 通过嵌套标签包裹,将v-for和v-if分别加在不同标签上

vue2

vue3

v-bind 合并行为

在vue2 中 v-bind 和 attribute,书写顺序无论先后,attribute总是覆盖v-bind而

而在vue3 中 v-bind 和 attribute 则是按顺序来执行,后面的会覆盖前面的。

vue2 中案例说明

代码语言:javascript
复制
<template>
  <div class="parent">
    <h1>父级组件</h1>
    <child name="hahahah" v-bind="obj" />
  </div>
</template>

<script>
// @ is an alias to /src
import child from "@/components/child.vue";
export default {
  components: {
    child,
  },
  data() {
    return {
      obj: {
        name: 'iwhao',
      }
    }
  }
};
</script>
代码语言:javascript
复制
<template>
  <div class="child">
    <h1>子组件</h1>
    <h1>{{ name }}</h1>
  </div>
</template>

<script>
export default {
  props: {
    name: String,
  },
};
</script>

vue3 中案例说明

父组件

代码语言:javascript
复制
<template>
  <div class="parent">
    <h1>父组件</h1>
    <child name="hahahah" v-bind="{name: name}" ></child>
  </div>
</template>

<script setup>
import { ref } from 'vue';
import child from './child.vue'
let name = ref('iwhao')
</script>

子组件

代码语言:javascript
复制
<template>
  <div class="child">
    <h1>子组件</h1>
    <p>父组件传过来的name: {{ name }}</p>
  </div>
</template>

<script setup>
defineProps(['name'])
</script>

如上代码,因为父组件中先写的 name 后写的 v-bind name,后面的v-bind会覆盖其那面的name,所以在子组件中接收的值 是 父组件中v-bind中 name:iwhao

如果把父组件中的name 和 v-bind的书写顺序换一下的话 如下 效果

代码语言:javascript
复制
...
<child v-bind="{name: name}" name="hahahah"></child>
...

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • v-model
    • modifiers是什么?
    • telement标签被允许拥有key属性
    • v-if 与 v-for 的优先级对比
    • v-bind 合并行为
      • vue2 中案例说明
        • vue3 中案例说明
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档