Vue3.3 的新功能的一些体验
Vue3 在大版本 3.3 里面推出来了一些新功能(主要是语法糖),网上有各种文章,但是看起来似乎是一样的。
我觉得吧,有新特性了,不能光看,还要动手尝试一下。
DefineOptions 宏定义
先来一个简单的,以前我们有时候想设个name,有时候不想让组件自动继承属性,这时候需要单独设置一个script进行设置,现在简化了操作,直接使用 defineOptions 即可。
<script setup lang="ts">
defineOptions({
name: 'Foo',
inheritAttrs: false,
// ... 更多自定义属性
})
</script>
defineModel
defineModel 这是一个语法糖,目前需要手动开启,否则无法识别。
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
// https://vitejs.dev/config/
export default defineConfig({
plugins: [vue({
script: {
defineModel: true,
propsDestructure: true // 解构 props
}
})],
})
有人嫌弃 组件内部 v-model 的实现方式有点繁琐,所以就做了这个语法糖给大家减少代码量,我们也来体验一下。
const modelValue = defineModel()
console.log(modelValue)
我们看看 的结构
{__v_isRef: true}
value: (...)
__v_isRef: true
get value: ƒ value()
set value: ƒ value(value)
只是一个普通的对象看不出来有什么名堂,我们来看一下内部的实现方式:
function useModel(props, name, options) {
const i = getCurrentInstance();
if (process.env.NODE_ENV !== "production" && !i) {
warn(`useModel() called without active instance.`);
return ref();
}
if (process.env.NODE_ENV !== "production" && !i.propsOptions[0][name]) {
warn(`useModel() called with prop "${name}" which is not declared.`);
return ref();
}
if (options && options.local) {
const proxy = ref(props[name]);
watch(
() => props[name], // 监听外部组件的值的变化
(v) => proxy.value = v // 赋值给内部属性
);
watch(proxy, (value) => { // 监听内部属性的变化
if (value !== props[name]) {
i.emit(`update:${name}`, value); // 提交给外部组件
}
});
return proxy;
} else {
return {
__v_isRef: true,
get value() {
return props[name]; // 返回外部组件的值
},
set value(value) {
i.emit(`update:${name}`, value); // 内部组件赋值,提交给外部组件
}
};
}
}
前面各种判断,然后option模式下返回一个 ref,setup 模式下返回一个对象。取值的时候,返回 props[name]
Props 的响应式解构
我个人是不喜欢解构的,直接使用不香吗?其实vue表面上不让我们用,其实内部悄悄的在用,比如上面那个useModel 不就是嘛。
这个也是实验性的,想要体验需要手动设置,设置方法在上面。
const { name } = defineProps<{ name: string }>()
watchEffect(() => {
console.log(`name is: ${name}`)
})
const aa = computed(() => { return name + '响应'})
看打印效果,只是普通的string,那么是如何实现响应的呢?还得看看“编译后”的代码是什么样子的。
setup(__props, { expose: __expose }) {
__expose();
watchEffect(() => {
console.log(`name is: ${__props.name}`);
});
const aa = computed(() => {
return __props.name + "\u54CD\u5E94";
});
编译后会生成一个 setup 函数,props 通过 参数 __props 传入,需要监听的地方,会把 name 变成 __props.name,这样就实现响应性了。也就是说,还是一个语法糖。
从外部文件引入 props 的定义( 单文件组件类型导入)
从外部引入 props 的定义,这个功能非常实用,以前封装UI库,想实现共享属性定义的时候卡了好久,使用OptionAPI,还是使用CompositionAPI,都各有优缺点,最后只好折中一下。
现在支持外部导入那就方便多了。
比如我们先在一个ts文件里面定义一个接口:
export interface IFromItemProps {
/**
* 表单的 model
*/
model: {[key: string]: any},
/**
* 对应的字段名称
*/
colName: string,
/**
* 控件的备选项,单选、多选、等控件需要
*/
optionList?: Array<{
label: string,
value: string | number | boolean,
disabled: boolean
}>,
/**
* 是否显示可清空的按钮,默认显示
*/
clearable?: boolean,
/**
* 浮动的提示信息,部分控件支持
*/
title?: string,
/**
* 组件尺寸
*/
size?: string
}
text
然后我们可以 基于 el-input 做一个自己的 nf-text ,然后引入接口定义,还可以在 nf-list 等里面引入,这比以前使用的方式正规多了,也能更好的支持TS。
<template>
<el-input
v-model="model[colName]"
v-bind="$attrs"
:id="'c' + colName"
:name="'c' + colName"
:size="size"
:clearable="clearable"
>
</el-input>
</template>
<script setup lang="ts">
// 引入 类型定义
import type { IFromItemProps } from './base'
// 定义 props
const props = defineProps<IFromItemProps>()
console.log('props - text', props)
</script>
看看效果
Proxy {model: Proxy, colName: 'name', title: '姓名', size: 'small', clearable: true, …}
[[Handler]]: Object
[[Target]]: Proxy
[[Handler]]: Object
[[Target]]: Object
clearable: true
colName: "name"
model: Proxy {name: 'jyk', city: Array(0), time: ''}
optionList: undefined
size: "small"
title: "姓名"
[[Prototype]]: Object
[[IsRevoked]]: false
[[IsRevoked]]: false
list
你可能会觉得,这封装的有意义吗?只看一个确实没啥意思,不过表单里面不是只有文本框这一种,还需要其他类型,定义接口就是为了统一风格。
我们再封装一个select看看:
<template>
<el-select
v-model="model[colName]"
v-bind="$attrs"
:id="'c' + colName"
:name="'c' + colName"
:size="size"
:clearable="clearable"
:multiple="multiple"
>
<el-option
v-for="item in optionList"
:key="'select' + item.value"
:label="item.label"
:value="item.value"
:disabled="item.disabled"
>
</el-option>
</el-select>
</template>
这里处理了一下 el-option ,使用 v-for 创建 el-option。
<script setup lang="ts">
import type { IFromItemProps } from './base'
const props = defineProps<IFromItemProps & {multiple?: boolean}>()
console.log('props - list', props)
</script>
最后看一下使用情况
import nfText from './form/text.vue'
import nfList from './form/list.vue'
import nfDatetime from './form/datetime.vue'
const model = reactive({
name: 'jyk',
city: '',
time: ''
})
const myText = {
colName: 'name'
}
const myList = {
colName: 'city',
multiple: true,
optionList: [
{
label: '北京',
value: 1
},
{
label: '上海',
value: 2
}
]
}
<nf-text :model="model" v-bind="myText"></nf-text>
<nf-list :model="model" v-bind="myList"></nf-list>
...
封装之后,我们不用关心组件是否需要子组件(比如el-select需要设置 el-option),都是<nf-text v-bind="myText"></nf-text>这种简单粗暴的方式,而组件需要的属性,我们可以做成json的形式,这样更方便。
另外大家不要忘记 vue 提供的动态组件(component :is="xxx"),这样我们用 v-for 就可以把一个表单里的所有子组件都给遍历出来,不用一个一个的写了。
小结
目前只对这几个新特性感兴趣体验了一下,其他的还没来得及。还有一个 props 设置默认值的问题,可以使用 withDefaults:
const props = withDefaults(defineProps< IFromItemProps >(), {
clearable: true
})
只是好像 默认值的部分需要直接写进去。这个,等待以后更新吧,估计以后都会支持外部导入的方式吧。
参考文档
- Announcing Vue 3.3 | The Vue Point
- Vue 3.3 主要新特性详解 - 三咲智子 Kevin Deng
参考资料
[1] Generic component enhancements - Discussion #436: https://github.com/vuejs/rfcs/discussions/436
[2] unplugin-vue-define-options - npm: https://www.npmjs.com/package/unplugin-vue-define-options
[3] Announcing Vue 3.3 | The Vue Point: https://blog.vuejs.org/posts/vue-3-3
[4] Vue 3.3 主要新特性详解 - 三咲智子 Kevin Deng: https://xlog.sxzz.moe/vue-3-3
Vue3.3 的新功能的一些体验的更多相关文章
- 个人官网第8次升级(新功能、用户体验、修复bug、系统优化)
1.新功能. 操作日志和搜索日志的Excel报表下载. 2.用户体验. 如果是通过搜索,进入到一篇内容, 搜索关键词需要高亮. 比如,搜索"程序员"出现若干内容链接,打开链接的页面 ...
- win10 内测14352 加入了容器 和docker新功能,想体验的赶快升级
原来只在server2016上有,现在加入到win0内测版了windows 容器提供了两种级别的隔离技术,分别是Windows Server container 和Hyper-V Container ...
- VS2017十五项新功能体验
Visual Studio 2017十五项新功能体验 Visual Studio 2017正式已经于2017.3.7号正式发布,选在这一天发布也是为了纪念Visual Studio 二十周年.MVP ...
- 地图SDK全面升级 – 数十项新功能及优化等你来体验
腾讯位置服务地图SDK是一套提供多种地理位置服务的应用程序接口.通过调用该接口,开发者可以在自己的应用中加入地图相关的功能(如地图展示.标注.绘制图形等),轻松访问腾讯地图服务和数据,构建功能丰富.交 ...
- Tapdata Cloud 版本上新!新增TiDB等数据源支持,连接和任务功能增强,体验更优
Tapdata Cloud cloud.tapdata.net Tapdata Cloud 是国内首家异构数据库实时同步云平台,目前支持Oracle.MySQL.PG.SQL Server.Mongo ...
- 4.0 SDK Workshop 纪实:一起体验多人、多屏幕共享新功能
在本月初,声网发布了 RTC Native SDK 4.0 版本.该版本提供了更高的开发灵活度,可明显提升实时场景开发效率,并让第三方插件开发更容易.上周六(8月20日),我们组织了一场小型的线下 W ...
- Visual Studio 2017十五项新功能体验
Visual Studio 2017正式已经于2017.3.7号正式发布,选在这一天发布也是为了纪念Visual Studio 二十周年.MVP 2017技术峰会将于这个周末(3.17)在北京举办,由 ...
- 3.0.0 alpha 重磅发布!九大新功能、全新 UI 解锁调度系统新能力
2022 年 4 月 22 日,Apache DolphinScheduler 正式宣布 3.0.0 alpha 版本发布!此次版本升级迎来了自发版以来的最大变化,众多全新功能和特性为用户带来新的体验 ...
- 从淘宝 UWP 的新功能 -- 比较页面来谈谈 UWP 的窗口多开功能
前言 之前在 剁手党也有春天 -- 淘宝 UWP ”比较“功能诞生记 这篇随笔中介绍了一下 UWP 淘宝的“比较”新功能呱呱坠地的过程.在鲜活的文字背后,其实都是程序员不眠不休的血泪史(有血有泪有史) ...
- What's new in Windows 10 Enterprise with Microsoft Edge.(Windows 10 新功能)
What's new in Windows 10 Enterprise with Microsoft Edge --带有Edge浏览器的Windows 10 企业版的新功能 本文摘录自公司群发邮件, ...
随机推荐
- 车企-TSP系统通用架构设计
最近一年用于参与到了新能源车企的管理系统的开发,并且主要从事架构设计与重难点功能开发的工作,因此有了一些小心得,特此记录(PS:整体和甲方在需求上扯皮,以及协调所有供应商这些项目管理上的事情比做开发耗 ...
- 来自我的Moments-实用学习资源或网站
目录 计算机基础知识 操作系统原理 计算机网络 其他 计算机技术栈 电子技术和嵌入式 计算机专业工作和面试 软件工程师手册(华为资料) 机器人工程师学习计划-硬核-知乎文章 提升效率的工具 BIT T ...
- Serial port
前言 使用qt开发一款简易串口助手. 目标: 1. 实现正常串口通信. 2. 能够传输AT指令.(需要注意回车符) github仓库地址:shadow-wd/Serial-port-assis ...
- 关于js类的继承
原型链继承 特点:基于原型链,既是父类的实例,也是子类的实例. 缺点: 无法实现多继承. 构造继承 特点: 可以实现多继承. 缺点: 之能继承父类实例的属性和方法,不能继承原型上的属性和方法. 实例继 ...
- linux服务器qps查询,查看当前linux服务器的QPS
https://blog.csdn.net/weixin_42119281/article/details/116595205 QPS:每秒查询率(QPS,Queries-per-second)是对一 ...
- go微服务框架kratos学习笔记二(kratos demo 结构)
目录 api cmd configs dao di model server service 上篇文章go微服务框架kratos学习笔记一(kratos demo)跑了kratos demo 本章来看 ...
- lua快速入门~在js基础上,知道Lua 和 Js 的不同即可
lua 和 javaScript 差不多的,就是一些语法的细节不同,学过js,再注意一下下面的细节,就能上手了~ 快速入门,可以直接看一下菜鸟教程的lua:https://www.runoob.com ...
- 在 Kubernetes 集群上部署 VSCode
在 Kubernetes 集群上部署 VSCode Visual Studio Code Visual Studio Code 是一个轻量级但功能强大的源代码编辑器,可在您的桌面上运行,适用于 Win ...
- XmlSerializer 反射类型xxx时出错,反射属性xxx时出错。
在使用XmlSerializer将类序列化成XML时出错,看到InnerException的message可以知道是这个receiver里有错误,进入这个类查看一下代码发现有重名的类 NodeId类修 ...
- yolov5训练自己的数据集
1.安装cuda 可以先看看自己的 显卡信息,支持哪个cuda版本 cuda下载地址:https://developer.nvidia.com/cuda-toolkit-archive 我的RTX30 ...