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

相关推荐
qq_3901617713 分钟前
防抖函数--应用场景及示例
前端·javascript
John.liu_Test42 分钟前
js下载excel示例demo
前端·javascript·excel
Yaml41 小时前
智能化健身房管理:Spring Boot与Vue的创新解决方案
前端·spring boot·后端·mysql·vue·健身房管理
PleaSure乐事1 小时前
【React.js】AntDesignPro左侧菜单栏栏目名称不显示的解决方案
前端·javascript·react.js·前端框架·webstorm·antdesignpro
哟哟耶耶1 小时前
js-将JavaScript对象或值转换为JSON字符串 JSON.stringify(this.SelectDataListCourse)
前端·javascript·json
getaxiosluo1 小时前
react jsx基本语法,脚手架,父子传参,refs等详解
前端·vue.js·react.js·前端框架·hook·jsx
理想不理想v1 小时前
vue种ref跟reactive的区别?
前端·javascript·vue.js·webpack·前端框架·node.js·ecmascript
知孤云出岫1 小时前
web 渗透学习指南——初学者防入狱篇
前端·网络安全·渗透·web
贩卖纯净水.1 小时前
Chrome调试工具(查看CSS属性)
前端·chrome
栈老师不回家2 小时前
Vue 计算属性和监听器
前端·javascript·vue.js