体验一下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 还做了性能的优化和一些小的改动这里就不再列举,更多细节大家可以点击这里查看

相关推荐
liuyouzhang10 分钟前
将基于Archery的web数据库审计查询平台封装为jdbc接口的可行性研究(基于AI)
前端·数据库
码事漫谈6 小时前
大模型输出的“隐性结构塌缩”问题及对策
前端·后端
这儿有一堆花6 小时前
前端三件套真的落后了吗?揭开现代 Web 开发的底层逻辑
前端·javascript·css·html5
.Cnn7 小时前
JavaScript 前端基础笔记(网页交互核心)
前端·javascript·笔记·交互
醉酒的李白、7 小时前
Vue3 组件通信本质:Props 下发,Emits 回传
前端·javascript·vue.js
anOnion7 小时前
构建无障碍组件之Window Splitter Pattern
前端·html·交互设计
小眼哥7 小时前
SpringBoot整合Vue代码生成exe运行程序以及windows安装包
vue.js·windows·spring boot
NotFound4867 小时前
实战分享Python爬虫,如何实现高效解析 Web of Science 文献数据并导出 CSV
前端·爬虫·python
徐小夕8 小时前
PDF无限制预览!Jit-Viewer V1.5.0开源文档预览神器正式发布
前端·vue.js·github
WangJunXiang68 小时前
Haproxy搭建Web群集
前端