이 기사는 Vue3 학습 노트를 요약하고 공유하며 Vue3의 11가지 지식 포인트에 대한 심층적인 이해를 제공합니다. 모두에게 도움이 되기를 바랍니다!
기존 OptionsAPI에서는 로직을 다음 6개 부분으로 나누어야 합니다. [관련 권장 사항: vue.js 비디오 튜토리얼]
OptionsAPI
컴포넌트
components
props
data
computed
methods
lifecycle methods
props
data
계산
CompositionAPI를 사용하여 문제를 해결하는 방법가장 좋은 해결책은 logic 코드를 매우 읽기 쉽게 만들 수 있습니다.메서드
수명 주기 메서드
이것이 우리의 CompositionAPI 구문이 달성할 수 있는 것입니다. CompositionAPI는 완전히 선택적인 구문이며 원래 OptionAPI와 충돌하지 않습니다. optionsAPI
단점
속성 이름 충돌을 피할 수 없음
상속 관계가 명확하지 않음2. - Mixin Factory
Return one
✅코드 재사용이 편리함✅상속 관계 정리3.ScopeSlots - 스코프 슬롯❌가독성이 좋지 않음
❌구성이 복잡합니다. template
❌낮은 성능 - 각 슬롯은 인스턴스와 동일합니다
4. CompositionApi - 복합 API
2. 설정 및 참조
import {watch} from "vue" export defalut { props: { name: String }, setup(props) { watch(() => { console.log(props.name) }) } }
setup (props,context) { const {attrs,slots,parent,root,emit} = context }로그인 후 복사
기본 데이터 유형 데이터를 설치하려면 Box 작업을 통해 데이터 변경 사항을 추적할 수 있는 반응형 개체로 만듭니다.
🎜🎜요약🎜🎜🎜🎜🎜🎜유지관리성이 대폭 향상되었습니다🎜这个地方实在没什么好讲的,和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가지 지식 포인트에 대한 자세한 설명의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!