如何快速入門VUE3.0:進入學習
在傳統的OptionsAPI中我們需要將邏輯分散到以下六個部分。【相關推薦:】
OptionsAPI
components
props
data
computed
methods
lifecycle methods
最佳的解決方法是將邏輯聚合就可以很好的程式碼可讀性。
這就是我們的CompositionAPI語法能夠實現的功能。CompositionAPI是一個完全可選的語法與原來的OptionAPI並沒有衝突之處。他可以讓我們將相同功能的程式碼組織在一起,而不需要散落到optionsAPI的各個角落
Vue2中的跨元件重用程式碼,我們大概會有四個選擇
1、Mixin - 混入
缺點
2、Mixin Factory - 混入工廠
返回一個
✅程式碼重用方便
✅繼承關係清洗
3、ScopeSlots - 作用域插槽
❌可讀性不高
❌設定複雜 - 需要再模板中進行設定
❌效能低 - 每個插槽相當於一個範例
4、CompositionApi - 複合API
✅程式碼量少
✅沒有引入新的語法,只是單純函數
✅異常靈活
✅工具語法提示友好 - 因為是單純函數所以 很容易實現語法提示、自動補償
✅更好的Typescript支援
✅在複雜功能元件中可以實現根據特性組織程式碼 - 程式碼內聚性, 比如:
排序和搜尋邏輯內聚
✅元件間程式碼複用
對基本資料型別資料進行裝箱操作使得成為一個響應式物件,可以跟蹤資料變化。
可維護性明顯提高
這個地方實在沒什麼好講的,和Vue2沒變化
<template> <div> <div>Capacity: {{ capacity }}</div> <p>Spases Left: {{ sapcesLeft }} out of {{ capacity }}</p> <button @click="increaseCapacity()">Increase Capacity</button> </div> </template> <script> import { ref, computed, watch } from "vue"; export default { setup(props, context) { const capacity = ref(3); const attending = ref(["Tim", "Bob", "Joe"]); function increaseCapacity() { capacity.value++; } const sapcesLeft = computed(() => { return capacity.value - attending.value.length; }); return { capacity, increaseCapacity, attending, sapcesLeft }; }, }; </script>
之前reactive 的 Ref 去宣告所有的響應式屬性
import { ref,computed } from 'vue' export default { setup(){ const capacity = ref(4); const attending = ref(["Tim","Bob","Joe"]); const spacesLeft = computed(()=>{ return capacity.value - attending.value.length }) function increaseCapacity(){ capacity.value ++;} return { capacity,increaseCapacity,attending,spacesLeft} } }
但是有另一個等效的方法用它去代替 reactive 的Ref
import { reactive,computed } from 'vue' export default { setup(){ const event = reactive({ capacity:4, attending:["Tim","Bob","Joe"], spacesLeft:computed(()=>{ return event.capacity - event.attending.length; }) }) } }
過去我們用vue2.0的data來宣告響應式物件,但是現在在這裡每一個屬性都是響應式的包括computed 計算屬性
這2種方式相比於第一種沒有使用.
接下來 我們再宣告method 這2種語法都ok,取決於你選擇哪一種
setup(){ const event = reactive(){ capacity:4, attending:["Tim","Bob","Joe"], spacesLeft:computed(()=>{ return event.capacity - event.attending.length; }) function increaseCapacity(){event.capacity++} //return整個物件 return {event,increaseCapacity} } }
<p>Spaces Left:{{event.spacesLeft}} out of {{event.capacity}}</p> <h2>Attending</h2> <ul>> <li v-for="(name,index) in event.attending" :key="index"> {{name}} </li> </ul> <button @click="increaseCapacity()"> Increase Capacity</button>
在這裡我們使用物件都是.屬性的方式,但是如果 這個結構變化了,event分開了程式設計了一個個片段,這個時候就不能用.屬性的方式了
//在這裡可以使用toRefs import {reactive,computed,toRefs} from 'vue' export default{ setup(){ const event = reactive({ capacity:4, attending:["Tim","Bob","Joe"], spacesLeft:computed(()=>{ return event.capacity -event.attending.length; }) }) function increaseCapacity(){ event.capacity ++ } return {...toRefs(event),increaseCapacity} } }
如果沒有 increaseCapacity() 這個方法 直接可以簡化為
return toRefs(event)
完整程式碼
<div> <p>Space Left : {{event.spacesLeft}} out of {{event.capacity}} </p> <h2>Attending</h2> <ul> <li v-for="(name,index)" in event.attending :key="index">{{name}} </li> </ul> <button @click="increaseCapacity">Increase Capacity</button> </div> </template> <script> //第一種 import {ref,computed } from 'vue' export default { setup(){ const capacity = ref(4) const attending = ref(["Tim","Bob","Joe"]) const spaceLeft = computed(()=>{ return capacity.value - attending.value.length; }); function increaseCapacity(){ capacity.value++; } return {capacity,increaseCapacity,attending,spaceLeft} } } //返回一個響應式函數 第二種 import { reactive,computed } from 'vue' export default { setup(){ const event = reactive({ capacity:4, attending:["Tim","Bob","Joe"], spaceLeft:computed(()=>{ return event.capacity - event.attending.length; }) }) //我們不再使用.value function increaseCapacity() { event.capacity++; } //把這個event放入到template中 return { event,increaseCapacity} } } </script>
使用CompositionAPI的兩個理由
1、可以按照功能組織程式碼
2、元件間功能程式碼複用
Vue2 | Vue3 |
---|---|
beforeCreate | ❌setup(替代) |
created | ❌setup(替代) |
beforeMount | onBeforeMount |
mounted | onMounted |
beforeUpdate | onBeforeUpdate |
updated | onUpdated |
beforeDestroy | onBeforeUnmount |
destroyed | onUnmounted |
errorCaptured | onErrorCaptured |
- | ?onRenderTracked |
- | ?onRenderTriggered |
setup中呼叫生命週期勾點
import { onBeforeMount,onMounted } from "vue"; export default { setup() { onBeforeMount(() => { console.log('Before Mount!') }) onMounted(() => { console.log('Before Mount!') }) }, };
// 所有依賴響應式物件監聽 watchEffect(() => { results.value = getEventCount(searchInput.value); }); // 特定響應式物件監聽 watch( searchInput, () => { console.log("watch searchInput:"); } ); // 特定響應式物件監聽 可以獲取新舊值 watch( searchInput, (newVal, oldVal) => { console.log("watch searchInput:", newVal, oldVal); }, ); // 多響應式物件監聽 watch( [firstName,lastName], ([newFirst,newLast], [oldFirst,oldlast]) => { // ..... }, ); // 非懶載入方式監聽 可以設定初始值 watch( searchInput, (newVal, oldVal) => { console.log("watch searchInput:", newVal, oldVal); }, { immediate: true, } );
編寫一個公共函數usePromise函數需求如下:
import { ref } from "vue"; export default function usePromise(fn) { const results = ref(null); // is PENDING const loading = ref(false); const error = ref(null); const createPromise = async (...args) => { loading.value = true; error.value = null; results.value = null; try { results.value = await fn(...args); } catch (err) { error.value = err; } finally { loading.value = false; } }; return { results, loading, error, createPromise }; }
應用
import { ref, watch } from "vue"; import usePromise from "./usePromise"; export default { setup() { const searchInput = ref(""); function getEventCount() { return new Promise((resolve) => { setTimeout(() => resolve(3), 1000); }); } const getEvents = usePromise((searchInput) => getEventCount()); watch(searchInput, () => { if (searchInput.value !== "") { getEvents.createPromise(searchInput); } else { getEvents.results.value = null; } }); return { searchInput, ...getEvents }; }, };
我們考慮一下當你載入一個遠端資料時,如何顯示loading狀態
通常我們可以在模板中使用v-if
但是在一個元件樹中,其中幾個子元件需要遠端載入資料,當載入完成前父元件希望處於Loading狀態時我們就必須藉助全域性狀態管理來管理這個Loading狀態
這個問題在Vue3中有一個全新的解決方法。
這就是Suspense Component,懸念元件。
<template> <div> <div v-if="error">Uh oh .. {{ error }}</div> <Suspense> <template #default> <div> <Event /> <AsyncEvent /> </div> </template> <template #fallback> Loading.... </template> </Suspense> </div> </template> <script> import { ref, onErrorCaptured, defineAsyncComponent } from "vue"; import Event from "./Event.vue"; const AsyncEvent = defineAsyncComponent(() => import("./Event.vue")); export default { components: { Event, AsyncEvent, }, setup() { const error = ref(null); onErrorCaptured((e) => { error.value = e; // 阻止錯誤繼續冒泡 return true; }); return { error }; }, }; </script>
類似React中的Portal, 可以將特定的html模板傳送到Dom的任何位置
通過選擇器QuerySelector設定
<template> <div> <teleport to="#end-of-body" :disabled="!showText"> <!-- 【Teleport : This should be at the end 】 --> <div> <video src="../assets/flower.webm" muted controls="controls" autoplay="autoplay" loop="loop"> </video> </div> </teleport> <div>【Teleport : This should be at the top】</div> <button @click="showText = !showText">Toggle showText</button> </div> </template> <script> import { ref } from "vue"; export default { setup() { const showText = ref(false); setInterval(() => { showText.value = !showText.value; }, 1000); return { showText }; }, }; </script>
更多程式設計相關知識,請存取:!!
以上就是【整理總結】詳解Vue3的11個知識點的詳細內容,更多請關注TW511.COM其它相關文章!