全域
const router = createRouter({ ... })
router.beforeEach((to, from) => {
...
})
說明 | |
---|---|
beforeRouteLeave | 離開目前路由 (元件) |
beforeEach | 開始進入新路由之前 (全域) |
beforeEnter | 開始進入新路由之前 (路由) |
beforeRouteEnter | 路由尚未進入該元件時 (元件) |
beforeResolve | 路由與所搭配的元件已被解析 (全域) |
afterEach | 當路由跳轉結束後 (全域) |
beforeCreate | 元件實體建立前 (Vue Hook) |
setup | 元件實體已建立 (Vue Hook) |
beforeMount | 元件實體掛載前 (Vue Hook) |
onMounted | 元件實體掛載完成 (Vue Hook) |
beforeRouteEnter | next() 回呼函式 |
beforeRouteUpdate | 當路由更新時 (僅限同屬一個元件的情況,也可能完全不會發生) |
Vuex 是專為 Vue.js 應用程式開發的狀態管理模式(State Management Pattern)。它採用集中式存儲管理應用的所有組件的狀態,並以相應的規則保證狀態以一種可預測的方式發生變化。
const Counter = {
// state
data () {
return {
count: 0
}
},
// view
template: `
<div>{{ count }}</div>
`,
// actions
methods: {
increment () {
this.count++
}
}
}
createApp(Counter).mount('#app')
這個狀態管理應用包含以下幾個部分:
以下是一個表示"單向數據流"理念的簡單示意:
對於問題一,傳遞參數的方法對於多層嵌套的組件將會非常繁瑣,對於兄弟組件之間的狀態傳遞無能為力。對於問題二,我們經常會採用父子組件直接引用或者通過事件來更改和同步狀態的多份拷貝。以上的這些模式非常脆弱,通常會導致難以維護的程式碼。
因此,為什麼不將組件的共享狀態抽取出來,以一個全局單例模式管理呢?在這種模式下,我們的組件樹構成了一個巨大的“視圖”,不論在樹的哪個位置,任何組件都能獲取狀態或者觸發行為!
通過定義和隔離狀態管理中的各種概念並通過強制規則維持視圖和狀態間的獨立性,我們的程式碼將會變得更結構化且易於維護。
這就是 Vuex 背後的基本思想,借鑒了 Flux、Redux 和 The Elm Architecture。與其他模式不同的是,Vuex 是專門為 Vue.js 設計的狀態管理庫,以利用 Vue.js 的細粒度數據響應機制來進行高效的狀態更新。
Flux:FLUX是一個由Facebook提出來的開發架構(FLUX 是一個Pattern 而不是一個正式的框架),目的是在解決所謂的MVC在大型商業網站所存在的問題,把沒有條理跟亂七八糟的架構做一個流程規範的定義。
Redux:Redux一個用於應用程式狀態管理的開源JavaScript庫。Redux經常與React搭配運用,但其也可以獨立使用。
官方說明文件:https://vuex.vuejs.org/zh/
元件系統 (components system) 是 Vue.js 一個重要的概念與核心功能。
實作一個數字加減
Vue 使用了 Template,使開發者能以直觀的方式來編寫 UI 結構。而 React 選擇使用 JSX,這是一種 JavaScript 的語法擴展。
React
import React, { useState } from 'react';
function Counter() {
const [count, setCount] = useState(0);
return (
<div>
<p>Count: {count}</p>
<button onClick={() => setCount(count + 1)}>
Increase
</button>
<button onClick={() => setCount(count - 1)}>
Decrease
</button>
</div>
);
}
VUE
<template>
<div>
<p>Count: {{ count }}</p>
<button @click="increase">
Increase
</button>
<button @click="decrease">
Decrease
</button>
</div>
</template>
<script>
import { ref } from 'vue';
export default {
setup() {
const count = ref(0);
const increase = () => {
count.value++;
};
const decrease = () => {
count.value--;
};
return {
count,
increase,
decrease
};
}
}
</script>
React 採用單向數據流,而 Vue 使用的是雙向綁定
React 遵循單向數據流,需要開發者明確地定義數據如何改變。而 Vue 的 v-model 指令使雙向數據綁定變得更簡單,但可能會使數據流動的方向變得不那麼明確。
React
import { useState } from "react";
function InputComponent() {
const [value, setValue] = useState("");
const handleChange = (event) => {
setValue(event.target.value);
};
return (
<>
<input
type="text"
placeholder="請輸入文字"
value={value}
onChange={handleChange}
/>
<p>你輸入的文字是 {value}</p>
</>
);
}
export default InputComponent;
VUE
<template>
<input type="text" v-model="value" placeholder="請輸入文字" />
<p>你輸入的文字是 {{ value }}</p>
</template>
<script>
import { ref } from "vue";
export default {
name: "InputDemo",
setup() {
const value = ref("");
return {
value,
};
},
};
</script>
Vite(法文意為"快速的",發音/vit/,發音同"veet")是一種新型前端建構工具,能夠顯著提升前端開發體驗。
是近幾年前端業界熱門的建構工具 (build tool),它大幅地簡化了前端建構的流程與時間。
它主要由兩個部分組成:
HMR (hot module replacement)
當有任何的改動後,Vite 的熱模塊更新會以非常快的速度重新渲染本地的頁面,同時會保留當下的任何狀態 (state)
假如有用過 Webpack 在大型專案的開發者,可能會有類似的經驗,就是在改動某部分程式碼後,要等數十秒才能看到畫面渲染新的版本,特別是專案中有用 TypeScript 時,每次的等待時間都讓開發體驗非常的差。
而 Vite 的出現就是要解決這類問題。Vite 不管在本地專案的冷啟動,或是專案改動時的熱模組更新,速度都非常的快。每次修改後不用等個數十秒才能看到新的畫面。這讓開發者的體驗更好,試想假如做某個專案,每次改動完都要等半分鐘,很可能讓開發者失去耐心。除此之外,這也讓回饋循環 (feedback loop speed) 更加快速,對於專案開發也是助益良多。
延伸閱讀:https://hackmd.io/@Jui-Cheng/SJCDBNZYj
MVVM 中的 VM 指的是 ViewModel,一樣負責接收從 View 傳來的使用者操作事件,並使用 Model 提供的方法來處理資料。
最主要的差異在於由數據來驅動 View 的更新,當資料改變時,UI 自動更新(一般用觀察者模式實現)。
資料改變時 UI 自動更新的現象,舉一個生活上的例子大家會很有感覺:
MVVM 架構有幾個主要的優點:
Vue 是以資料狀態操作畫面,
他扮演 MVVM 架構當中的 ViewModel,
可以有效的將負責視圖的 HTML 與負責資料狀態的 JavaScript 做一個切割。
能讓開發者專注於解決版面顯示的問題,
或是資料邏輯的 JavaScript 的問題。
例如:
使用者在畫面上(View)看到了 皮卡丘 與一個按鈕,
當使用者按下按鈕之後,
會觸發 Vue 的 changeName 方法(ViewModal),
將 pokemon 的值修改為 噴火龍(Modal),
因爲 ViewModal 與 View 是 Binding 的關係,
讓 View 的值顯示為 噴火龍。
<body>
<div id="app">
<div>{{ pokemon }}</div>
<button @click="changeName">就決定是你了</button>
</div>
<script>
var app = new Vue({
data: {
pokemon: '皮卡丘',
},
methods: {
changeName() {
this.pokemon = '噴火龍';
},
},
});
</script>
</body>
Object.defineProperty()語法
Object.defineProperty( Obj, 'name', {
enumerable: true, //可列舉
configurable: true, //可配置
// writable:true, //跟可配置不能同時存在
// value:'name', //可寫死直
get: function () {
return def
},
set: function ( val ) {
def = val
}
} )
Proxy的語法
//兩個引數,物件,13個配置項
const handler = {
get: function(obj, prop) {
return prop in obj ? obj[prop] : 37;
},
set:function(){ },
...13個配置項
};
const p = new Proxy({}, handler);
p.a = 1;
p.b = undefined;
console.log(p.a, p.b); // 1, undefined
console.log('c' in p, p.c); // false, 37
defineProperty只能繫結首次渲染時候的屬性,Proxy需要的是整體,不需要關心裡面有什麼屬性,而且Proxy的配置項有13種,可以做更細緻的事情,這是之前的defineProperty無法達到的
Props是一種用於將數據從父組件傳遞到子組件的機制。通常,父組件可以將數據作為屬性傳遞給子組件,子組件可以通過props接收這些屬性。
<template>
<ChildComponent :message="parentMessage" />
</template>
<script>
import ChildComponent from './ChildComponent.vue';
export default {
components: {
ChildComponent,
},
data() {
return {
parentMessage: 'Hello from parent!',
};
},
};
</script>
<template>
<div>
<p>{{ message }}</p>
</div>
</template>
<script>
import { defineComponent, PropType } from 'vue';
export default defineComponent({
props: {
message: {
type: String as PropType<string>,
required: true,
},
},
});
</script>
Emit是一種用於在子組件中觸發事件,並由父組件捕獲的機制。通常,當子組件中的某些操作需要通知父組件時,可以通過$emit方法觸發一個自定義事件。
<template>
<button @click="sendMessage">Click me!</button>
</template>
<script>
import { defineComponent, ref } from 'vue';
export default defineComponent({
setup() {
const sendMessage = () => {
emit('message-clicked', 'Hello from child!');
};
return {
sendMessage,
};
},
});
</script>
<template>
<ChildComponent @message-clicked="handleMessageClick" />
</template>
<script>
import ChildComponent from './ChildComponent.vue';
import { defineComponent } from 'vue';
export default defineComponent({
components: {
ChildComponent,
},
methods: {
handleMessageClick(message) {
console.log(message); // 輸出: Hello from child!
},
},
});
</script>
指令是 Vue 的一個基本面,充當範本語法中的特殊標記,指示框架對 DOM(文件物件模型)元素執行某些操作。它們以 v- 為前綴,表示它們是 Vue 提供的特殊屬性。指令提供了一種使用自訂行為擴充 HTML 的強大方法,對於使用 Vue 建立動態、互動式 Web 應用程式至關重要。
Vue有重複使用DOM節點的特點,在新增程式後,Vue會利用虛擬DOM比較上次DOM和這次DOM的差別,只渲染增加的部分,不會整個畫面重新渲染
更詳細了解虛擬DOM:https://ithelp.ithome.com.tw/articles/10233588
https://excalidraw.com/#json=ZiHLTcM9Mzpr2VBo8kY88,EeL25P8qw_7QLmUrO47z8g