Vue3.2 新特性
升级 Vue3.2
升级 node,到 14 以上吧,安装下 vite,然后运行 npm init @vitejs/app 然后一路选择 vue 或 vue-ts,如果要用 ts 的话
现有 Vue 项目升级 3.2 版本
1
2
3
4
5
6
7
8
9
10
11npm i vue // 升级到 3.2
npm i @vue/compiler-sfc -D // 满足 Vite 工具对 SFC(就是平常所说的 .vue 文件) 的编译需求
// 升级后查看 package.json 配置信息
"dependencies": {
"vue": "^3.2.20"
},
"devDependencies": {
"@vue/compiler-sfc": "^3.2.20",
"vite": "^1.0.0-rc.13"
}
Vue3.2 新特性
script setup 写法升级
- 废除 useContext,其功能被新增 API 替代了
- 新增 defineExpose,暴露接口供外界使用,不需要导入,在代码中直接用
1
2
3
4
5defineExpose({
someMethos() {
console.log("Some message from HelloWorld");
}
}) - 定义属性 defineProps (定义输入)、事件 defineEmits (定义输出)
1
2
3
4
5
6
7// 均不再需要导入
defineProps({
msg: String,
})
const emit = defineEmits(["my-click"]);
emit('my-click'); - 插槽信息和属性信息,新增 useSlots 和 useAttrs
1
2
3
4import { useAttrs, useSlots } from "vue"; // 用 use 开头的是需要明确引入的
console.log(useAttrs()); // 输出组件的非属性信息
console.log(useSlots()); // 输出组件的插槽信息
Web Components 应用
在 vite + vue3 项目中使用 web components 需要三步:- 定义 web components,main.js
1
2
3
4
5
6
7
8
9
10
11import { defineCustomElement, h } from 'vue';
// 返回值是构造函数
const MyVueElement = defineCustomElement({
// 通用 vue 组件选项
props: ["foo"],
render() {
return h("div", "my-vue-element:" + this.foo);
},
// 仅适用于 defineCustomElement: CSS 将被注入到 shadow root
styles: [`div { border: 1px solid green }`],
}) - 注册 web components,main.js
1
customElements.define("my-vue-element", MyVueElement); // 定义这个后意味着浏览器会接管 my-vue-element 这个元素,浏览器接管,Vue 就要取消接管,进行步骤三
- 配置 vite 自定义组件白名单,vite.config.js
1
2
3
4
5
6
7
8
9
10
11
12export default defineConfig({
plugins: [
vue({
template: {
compilerOptions: {
// vue 将跳过 my-vue-element 解析
isCustomElement: (tag) => tag === "my-vue-element",
}
}
})
]
})使用 web components:跟 vue 组件并没有什么区别
1
<my-vue-element foo="foo"></my-vue-element>
- 定义 web components,main.js
服务端渲染
@vue/server-renderer 包提供一个 ES 模块创建,并与 node.js 解耦,这样有可能让服务端可以运行在不是 node 的环境中
验证一下, main.js1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18import { createSSRApp } from "vue";
// 2、安装 @vue/server-renderer 库,npm i @vue/server-renderer -S
import { renderToString } from "@vue/server-renderer";
// 1、创建一个 SSR 应用程序实例
const app = createSSRApp({
data: () => ({ msg: "白醭飙尘" }),
render() {
return h('div', this.msg)
}
})
// renderToString 返回一个 promise,用 async 方式去写
(async () => {
// 3、把 SSR 实例渲染成一个 html 字符串,前端就可以把这个字符串设置成某个页面内容的 innerHTML 显示出来,这样就完成了服务端渲染
const html = await renderToString(app);
console.log(html);
})();注:npm i -S 等同于 npm i –save, 在运行命令的目录中下载指定的包到 node_modules, 如果 package.json 存在的话, 同时写入到 package.json 的 dependencies 字段;
npm i -D 等同于 npm i –save-dev, 在运行命令的目录中下载指定的包到 node_modules, 如果 package.json 存在的话, 同时写入到 package.json 的 devDependencies 字段。Effect Scope API
新的 Effect Scope API 可以直接控制响应式副作用的释放时间,在用到响应式时,可能会有副作用耗内存,影响性能1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22import { watch, watchEffect } from "@vue/runtime-core";
import { effectScope, computed, ref } from "@vue/reactivity";
const counter = ref(1)
setInterval(() => {
counter.value++
}, 1000);
// 创建一个 scope 作用域
const scope = effectScope()
// 通过 scope.run() 将其中执行的代码产生的副作用进行收集,比如每隔一秒计算 couter 在计算属性中占用内存
scope.run(() => {
const doubled = computed(() => counter.value * 2)
watch(doubled, () => console.log(doubled.value))
watchEffect(() => console.log('Count: ', doubled.value))
})
// 把 scope 中的所有副作用一次性全部释放
setTimeout(() => {
scope.stop()
}, 5000);
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 白醭飙尘!
评论
ValineDisqus