Vue3 實用部分(I)
本章節主要是給稍微了解vue,或是有寫過其他框架,會跑基本迴圈與判斷v-if , v-for等概念的人,可以進一步了解vue的特殊實用部分。主要會介紹
- Vue 3 CreateApp: 了解vue是如何產生並附著在html的基本概念
- Vue App註冊component
- Vue children: <slot>
- 特殊tag <keep-alive> <teleport>
Vue 3 CreateApp()
使用框架或套件,我們常常看了教學影片或文章,套用的過程中發現有畫面、資料就直接開發下去了。團隊中通常也有人已經把開發環境建好,我們只要直接開發即可。也因此我們忽略了框架的原則原理,沒有基本的原理認知,很多時候畫面出不來時debug自然時間就會拖很長。今天主要介紹vue app是如何讓web運作的
不可或缺的兩個檔案
- public/index.html : vue在渲染html的入口檔案
- src/main.js: 透過main.js 找到渲染的節點並渲染App
PS: 左邊是使用vue cli的預設結構,右邊是精簡化的檔案結構
實作createApp
使用vue cli 產出檔案後把檔案刪成剩下右邊模樣,只剩
/node_modules
/public
index.html /src
main.js 空的檔案
- 新增入口App
在src中新增App.vue
2. createApp
/src/App.vueimport { createApp } from 'vue'
import App from './App.vue'createApp(App).mount('#app')
我們也可以把createApp與mount分開寫
/src/App.vueimport { createApp } from 'vue'import App from './App.vue'const app = createApp(App);app.mount('#app')
3. 加入 component
app.component(<模組名稱>) 可直接在App中加入模組
import { createApp } from 'vue'import App from './App.vue'import ActiveUser from './components/ActiveUser.vue'
const app = createApp(App);
app.component(ActiveUser); // 也可使用 app.component('active-user', ActiveUser);app.mount('#app')
在App.vue裡面使用active-user
PS: 這邊也可以採取另一種做法,直接在App.vue import ,就不需要在main.js 中app.component了
然而,看到這邊你可能會有一個疑問。
那就是如果有100個模組是否就要在main.js裡面加入?
如果加了100個,所有頁面都能直接使用非常方便,但卻犧牲了效能。可能某些模組只被使用過一次,但其他不相干的頁面卻需要將這些模組初始化。
因此需要釐清global 與local 模組的概念
Global & Local component!
Global: 全域,意味著所有其他子模組都可以使用
Local: 區域,表示只在特定檔案檔案才使用到該模組。
將global 改成local: 1. 引入=> 2. 註冊=> 3. 使用
其中components的寫法有非常多種,挑一種適合自己的。推薦指數由高到低(上到下),大家看下方程式碼就知道為什麼了。
components: {
UserInfo, // UserInfo: UserInfo // "user-info": UserInfo, => 這種寫法在使用上只能用<user-info> 不能用大駝峰UserInfo (React寫法)
}
後續在main.js就可以把該模組拿掉了
Slot
寫過react的人可以直接把slot想成是react的children。當模組要調用父層所包的html tag時。
//React <ChildComponent>
{props.children}
</ChildComponent>//Vue<ChildComponent>
<slots></slots>
</ChildComponent>
接著我們來看實際使用起來的程式碼
新增一個BaseCard.vue 的模組
後續把slot引入並包在BaseCard裡面
此時可以看到user-info被夾在BaseCard的slots裡面了。
Multiple Slots
// Parenetcomponent
<ChildComponent> <template v-slot:{slot名稱}></template> {其他地方會進入default slot中 (可不寫(包)template)}</ChildComponent>// ChildComponent<template> <slot name="slot名稱"></slot> <slot></slot> // 預設的slot 可不給名稱</template>
$slots => 在mounted的時候可以查看接收到的slot
mounted(){ console.log(this.$slots.<slotname>);
}
Scope Slots
使用情境:需要child component的資料,但需要父層客製化template
概念圖
// ChildCompo<template> <ul>
<li v-for="goal in goals" : key="goal">
<slot :item="goal"></slot>
</li>
</ul></template><script>
export default{
}</script>
// ParentCompo<ChildCompo> <template #default="slotProps"> <h1> {{ slotProps.item }}</h1>
<p> {{ slotProps['another-prop'] }}</p> </template></ChildCompo>
動態模組(Dynamic Components)
當切換不同模組可以使用v-if 並根據目前狀態來判斷要產生哪種狀態。
概念如下
App.vue
<button @click="setAliveCompo('a-component')">show a-compo</button><button @click="setAliveCompo('b-component')">show b-compo</button>
<a-component v-if="aliveComponent === 'a-component' "></a-component><b-component v-if="aliveComponent === 'b-component' "></b-component>
<script>data(){ return{ aliveComponent: 'a-component';
};
}methods:{ setAliveCompo(aliveCompo) { this.aliveComponent = aliveCompo
}
}</script>
這種方式可以,不過太過冗長,Vue有提供Dynamic component 能夠支援切換不同的component
App.js
<a-component v-if="aliveComponent === 'a-component' "></a-component><b-component v-if="aliveComponent === 'b-component' "></b-component>----------------------- 上面這兩行修改成如下 ------------------------<component :is="aliveComponent"></component>
然而實際操作時,會發現component在切換時,會把原本的component 移除,因此如果不想要移除,可以再多加一<keep-alive>的tag。如此一來就不會被移除了。
<keep-alive> <component :is="aliveComponent"></component></keep-alive>
將模組插入特定dom元素 <teleport to=”${dom}”>
開始寫vue才發現有這個神奇的功能。一般我們在使用popup window 時,基本上都會把window(modal)寫在<body>底下,不會寫在vue的app tag中。
但在vue app.vue的架構中,都一定會被包在<div id=”app”></div>裡面。而vue可以簡單幫我們達成這個需求。
<teleport to="body"> <modal-compo v-if="showModal"></modal-compo> </teleport>
此時當modal-compo出現時就會被塞到<body> 中。
當然我們也可以讓to=”#app” 或是其他css的class中。有點類似jquery selector的方式。
以上就先介紹到這邊,基本上有了上述概念,在開發vue上會顯得更得心應手。之後的章節會再進一步介紹其他常用部分。