项目升级
旧的vite项目升级
npm i vue
npm i @vue/compiler-sfc -D
script setup写法升级
旧的SFC script setup语法发生不少变化:
- 废除
useContext
// 废除
import { useContext } from 'vue'
const ctx = useContext()
ctx.emit('xxx')
- 新增
defineExpose
// 不需要导入
defineExpose({
someMethod() {
console.log("some message from HelloWorld");
},
});
- 定义属性
defineProps
、事件defineEmits
// 不需要导入
defineProps({
msg: String,
});
// 不需要导入
const emit = defineEmits(["my-click"]);
emit('my-click')
- 新增
useSlots
和useAttrs
import { useAttrs, useSlots } from "vue";
console.log(useAttrs());
console.log(useSlots());
Web Components应用
在vite+vue3
项目中使用web components
需要三步:
- 定义
web components
- 注册
web components
- 配置vite自定义组件白名单
定义web components,main.js
:
import { defineCustomElement } 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
customElements.define("my-vue-element", MyVueElement);
配置vite自定义元素白名单,vite.config.js
export default defineConfig({
plugins: [
vue({
template: {
compilerOptions: {
// vue将跳过my-vue-element解析
isCustomElement: (tag) => tag === "my-vue-element",
},
},
}),
],
});
使用web components:跟vue组件并没有什么区别
<my-vue-element foo="foo"></my-vue-element>
服务端渲染
@vue/server-renderer
包提供一个ES模块创建,并与node.js解耦。
我们来验证一下,main.js
import { createSSRApp } from "vue";
import { renderToString } from "@vue/server-renderer";
const app = createSSRApp({
data: () ({ msg: "hello" }),
// template: `<div>{{ msg }}</div>`,
render() {
return h('div', this.msg)
}
});
(async () => {
const html = await renderToString(app);
console.log(html);
})();
Effect Scope API
新的Effect Scope API
可以直接控制响应式副作用的释放时间。
import { watch, watchEffect } from "@vue/runtime-core";
import { effectScope, computed, ref } from "@vue/reactivity";
const counter = ref(1)
setInterval(() {
counter.value++
}, 1000);
const scope = effectScope()
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);