体验一下vue3.3发布的船新版本

最近 vue 发布了 3.3 版本,新增了不少宏和语法糖以及改进了一些过往的写法以提高开发者的体验,下面带领大家体验一下 Vue3.3 版本。本篇文章将使用 vite 进行演示。

注意,当我们使用npm create vite的时候 vue 默认的版本还是 3.2 版本,所以我们需要手动将 vue 以及其它改成如下版本在进行 install

安装完毕我们便可以体验最新 3.3.4 版本了

宏函数 defineOptions

或许有的同学在做需要为组件命名的时候见过这个函数,但是是通过unplugin-vue-define-options插件实现的,而在 3.3 版本中它已经被纳入了 Vue 中

现在开发 vue3 项目基本都是用的 setup 语法的形式,这种形式在以前如果想要给组件命名则还需要写一个 script 标签或者使用插件,譬如

  • 额外的 script 标签
js 复制代码
<script>
export default {
  name: 'MyComponent',
}
</script>

<script setup>
...
</script>

这种显然不是很美观

  • 使用插件unplugin-vue-define-options
js 复制代码
//vite.config.ts
import DefineOptions from 'unplugin-vue-define-options/vite'

export default defineConfig({
  plugins: [
    DefineOptions(),
  ]
})

//setup 中
<script setup>
defineOptions({
  name: 'mycomponent'
})
</script>

而在 3.2 中则可以直接使用,当然传入的属性也不止 name 一种,比如有在 setup 中不能使用的beforeCreate生命周期等

js 复制代码
defineOptions({
  name: "mycomponent",
  beforeCreate() {
    console.log(123);
  },
});

便捷的 defineEmits

在 3.3 之前使用 defineEmits 向父组件发送一个 sendMsg 事件的时候写法如下

js 复制代码
defineEmits<{
  (e: 'sendMsg', value: string): void
}>()

第一个参数代表事件名,后面的参数表示传递的事件传递的参数,看起来不是很直观,所有 vue3.3 增加了语法糖

js 复制代码
defineEmits<{
  'sendMsg': [value:string]
}>()

提高类型导入体验

在 3.3 之前组件类型的引入只能引入本地的类型,不同从其它文件中导入,比如如下写法在 3.3 之前是不支持的,而在 vue3.3 版本得到了支持

js 复制代码
import type { Props } from './types'
defineProps<Props>()

并且还支持了一些复杂的类型,比如你想让组件接收一个额外的类型 name 你可以这样写

js 复制代码
defineProps<Props & { name?: string }>()

泛型组件 Generic

vue3.3 中泛型组件主要是用来约束组件接收的参数,比如想接收一个 name 为 string 类型的对象,它的写法如下

js 复制代码
<script lang='ts' setup generic="T extends { name:string }">
defineProps<T>()
</script>

reactive 解构

这个功能可以让我们结构 props 并且不会失去响应式,比如

js 复制代码
<script lang='ts' setup generic="T extends { name:string }">
const { name } = defineProps<T>()
</script>

其中的 name 变量依然是响应式的。 这个功能是实验性 的,如果要使用需要在vite.config.ts中配置

js 复制代码
export default {
  plugins: [
    vue({
      propsDestructure: true,
    }),
  ],
};

defineModel

在以前如果想要组件支持 v-model,我们需要这样写

  • 子组件

先声明 props,当想要更新 props 的时候,emit 一个update:modelValue事件

js 复制代码
<template>
    <div @click="sendMsg">按钮</div>
</template>

<script lang='ts' setup>
const props = defineProps<{ modelValue: string }>()
const emit = defineEmits<{ (e: 'update:modelValue', value: string): void }>()
const sendMsg = () => emit('update:modelValue', '222')
</script>
  • 父组件

v-model='msg'其实是:modelValue='msg' @update:modelValue='msg=$event'的语法糖,此时我们点击按钮 msg 就会更新为 222

js 复制代码
<template>
  <div>
    <Comp v-model="msg" />
  </div>
  <div>{{ msg }}</div>
</template>

<script lang='ts' setup>
import Comp from './App2.vue'
import { ref } from 'vue';
const msg = ref('')
</script>

这种写法是不是很麻烦,而使用了 defineModel 宏就会变得很简单,只需要定义一个 modelValue 即可

  • 子组件
js 复制代码
<template>
    <div @click="sendMsg">点击</div>
</template>

<script lang='ts' setup>
const modelValue = defineModel()
const sendMsg = () => {
    modelValue.value = '222'
}
</script>

这样就能实现同样的功能,同样的 defineModel 也是一个实验性的功能,如果想用它则需要在vite.config.ts中进行定义

js 复制代码
export default defineConfig({
  plugins: [
    vue({
      script: {
        defineModel: true,
      },
    }),
  ],
});

defineSlots

defineSlots 可以定义一个插槽的类型,比如子组件

js 复制代码
<template>
    <div>
        <div>
            <slot name="a" foo="yueyue" :bar="1" />
        </div>
        <div>
            <slot name="b" :option="{ name: '小月', age: 18 }" />
        </div>
    </div>
</template>

<script lang='ts' setup>
defineSlots<{
    a(props: { foo: string; bar: number }): any,
    b(props: { option: { name: string, age: number, sex?: string } }): any
}>()
</script>

它包含了两个插槽分别为 a 和 b,同时我们用defineSlots给他们定义了类型,然后我们可以在父组件中使用

js 复制代码
<template>
  <div>
    <Comp>
      <template #a="{ foo, bar }">
        {{ foo }} is string,{{ bar }} is number
      </template>
      <template #b="{ option }">
        {{ option.name }}
      </template>
    </Comp>
  </div>
</template>

<script lang='ts' setup>
import Comp from './App2.vue'
</script>

有了 defineSlots 用户就能更好地确定自己该怎么用某个 scopeSlot 了。

除了这些 Vue3.3 还做了性能的优化和一些小的改动这里就不再列举,更多细节大家可以点击这里查看

相关推荐
子兮曰6 小时前
Bun v1.3.14 深度解析:Image API、HTTP/3、全局虚拟存储与五十项变革
前端·后端·bun
kyriewen7 小时前
今天,百年巨头一次砍了9200人,而一个离职科学家的实话让全网睡不着觉
前端·openai·ai编程
问心无愧05137 小时前
ctf show web 入门42
android·前端·android studio
kyriewen8 小时前
老板逼我上AI,我偷偷在浏览器里跑LLaMA,省下20万API费
前端·react.js·llm
Beginner x_u8 小时前
前端八股整理(手写 02)|数组转树、数组扁平化、随机打乱一个数组
前端·数组·数组转树·数组扁平化
KaMeidebaby8 小时前
卡梅德生物技术快报|禽类成纤维细胞 FISH 实验:鸟类性别染色体基因定位技术实现与数据验证
前端·数据库·其他·百度·新浪微博
天若有情6738 小时前
前端高阶性能优化:跳出传统懒加载与预加载,基于用户行为做轻量预判加载
前端·性能优化
小小小小宇8 小时前
前端转后端:SQL 是什么
前端
张元清9 小时前
React Observer Hooks:7 种监听 DOM 而不写样板代码的方式
前端·javascript·面试
广州华水科技9 小时前
单北斗GNSS变形监测是什么?主要有怎样的应用与优势?
前端