vue3.0新特性盤點
宏偉的事業(yè),是靠實實在在的微不足道的一步步的積累,獲得的。

前言
雖然vue3還沒有正式發(fā)版,但是各大培訓(xùn)機構(gòu)均把它作為一個"噱頭",來吸引流量。相比vue2,寫法有一個很大變動,也越來越符合"解藕"的思想。目前在vue3的使用方面有兩種方式:
一種是通過下載vue@next,直接使用vue3。
另一種是通過vue-compisition-api來使用Vue3的一些特性。

沒有this
export default {
????data() {
????????return {
????????????title: "foo",
????????}
????},
????methods: {
????????//title:"foo"
????????getTitle() {
????????????this.title = "";
????????????//這里的this不應(yīng)該是methods這個對象嗎
????????}
????}
}
import { defineComponent, ref } from "vue";
export default defineComponent({
????setup() {
????????const title = ref("vue3");
????????console.log(count);
????????// ? ? ?{
????????// ? ? ? ?value: "vue3",
????????// ? ? ? ?__v_isRef: true
????????// ? ? ?}
????????return {
????????????title,
????????};
????},
});
更好的tree-shaking支持
import {
????ref,
????reactive,
????defineComponent,
????onMounted,
????computed
} from "vue";
//更好的tree-shaking支持
tree-shaking有一個兩個要求:
一個是必須是import導(dǎo)入。
另一個是必須是單個函數(shù)或常量導(dǎo)出。
如果導(dǎo)出的是一個對象,那也無法用tree-shaking。
export const add=()=>{
????//...
}
export const handleClick=()=>{
????//...
}
//不要這樣導(dǎo)出
export default {
????add,
????handleClick
}
webpack中需要開啟:
optimization: {
????usedExports: true, //用到使用
????minimize: true, //壓縮
},
數(shù)據(jù)的不可逆性
<template>
????<div>
????????<button>加加button>
????????<div>count:{{ obj.count }}div>
????div>
template>
<script>
import { defineComponent, ref } from "vue";
export default defineComponent({
????setup() {
????????const obj = {
????????????count: 0,
????????};
????????const handleClick = () => {
????????????obj.count++;
????????????console.log(obj);
????????};
????????return {
????????????obj,
????????????handleClick,
????????};
????},
});
script>
以上代碼中,頁面數(shù)據(jù)會跟著變嗎?不會,雖然打印出來的obj中的count會變化,但是在vue3中它是不可變的,想要變化,使用vue3提供的ref或reactive。
這樣做的意義是為了防止原數(shù)據(jù)被意外的改變,可以想想vue2中this,如果用this來實現(xiàn)響應(yīng)式,那么很容易出現(xiàn)的問題就是我可以通過this改變vue實例下的任意數(shù)據(jù)。
所以vue3數(shù)據(jù)的響應(yīng)其實就是拷貝來一份數(shù)據(jù)來實現(xiàn)頁面數(shù)據(jù)更新。
setup() {
????let count = ref(0);
????//常用來響應(yīng)基本數(shù)據(jù)類型
????const state = reactive({
????????title: "Hello,Vue.js 3.0!",
????});
????//常用來響應(yīng)引用數(shù)據(jù)類型
????return {
????????count,
????????state,
????//...
????};
}
組件傳值
//父組件
<template>
????<div>
????????<div>count:{{ count }}div>
????????<Button @outClick="onOutClick" text="Foo">Button>
????div>
template>
<script>
import {
????ref,
????reactive,
????defineComponent,
????onMounted,
????computed
} from "vue";
import Button from "./components/Button.vue";
export default defineComponent({
????components: {
????????Button,
????},
????setup() {
????????let count = ref(0);
????????const onOutClick = (now) => {
????????????console.log("子組件觸發(fā)向父組件觸發(fā)事件與傳值:", now);
????????};
????????return {
????????????count,
????????????onOutClick,
????????};
????},
});
script>
通過setup的參數(shù)prop、SetupContext實現(xiàn)父子組件通信。
//子組件
export default {
????props: {
????????text: String,
????},
????setup(props, { emit }) {
????????const onClick = () => {
????????????emit("outClick", Date.now());
????????};
????????return {
????????????props,
????????????onClick,
????????};
????},
}
生命周期鉤子函數(shù)和computed等也寫在setup函數(shù)中。
import {
????ref,
????reactive,
????defineComponent,
????onMounted,
????computed
} from "vue";
export default defineComponent({
????setup() {
????????let count = ref(0);
????????// Vue2.x 中的 mounted 生命周期函數(shù)
????????onMounted(() => {
????????????console.log("mounted");
????????});
????????// 計算屬性
????????const zerosCount = computed(() => {
????????????return new Array(10000)
????????????????????.fill("")
????????????????????.map((value, index) => index + 1)
????????????????????.join("")
????????????????????.match(/0/g).length;
????????});
????????return {
????????????count,
????????????zerosCount,
????????};
????},
})
邏輯復(fù)用
// mixin混入文件
import {
????ref,
????onMounted,
????onUnmounted
} from "vue";
export default () => {
????const width = ref(window.innerWidth);
????const height = ref(window.innerHeight);
????const update = (e) => {
????????width.value = window.innerWidth;
????????height.value = window.innerHeight;
????};
????onMounted(() => {
????????window.addEventListener("resize", update);
????});
????onUnmounted(() => {
????????window.removeEventListener("resize", update);
????});
????return { width, height};
}
這樣寫,就可以明確知道原數(shù)據(jù)的出處。
import { defineComponent, ref } from "vue";
import windowSize from "../mixin.js";
export default defineComponent({
????setup() {
????????const count = ref(0);
????????const {
????????????width = window.innerWidth,
????????????height
????????} = windowSize();
????????return {
????????????count,
????????????width,
????????????height,
????????????//...
????????};
????},
});
??愛心三連擊
1.看到這里了就點個在看支持下吧,你的「點贊,在看」是我創(chuàng)作的動力。
2.關(guān)注公眾號
程序員成長指北,回復(fù)「1」加入Node進階交流群!「在這里有好多 Node 開發(fā)者,會討論 Node 知識,互相學(xué)習(xí)」!3.也可添加微信【ikoala520】,一起成長。
“在看轉(zhuǎn)發(fā)”是最大的支持
