#0 為甚麼要用vuejs框架? -30天學會vue系列文 | seansie blog
大概如果初入網頁設計領域的人都聽說過html、css跟javascript,分別對應 內容 **樣式 跟互動。**如此看來,網站的基本元素應該湊齊了阿,幹嘛還要加上框架,增加複雜度呢?。
那好,且聽我娓娓道來。
重複元素
舉google搜尋下面的按鈕為例,你看已經分別重複8次跟10次了,如果僅使用 javascript
的話,難道要重複8次跟10次嗎?
雖然是可以用迴圈+ Inner html
啦,但是非常難以維護,尤其是一旦專案複雜度很高的時候。
// Create a container element (you can replace this with your existing container)
const container = document.createElement('div');
document.body.appendChild(container);
// Create and append 8 buttons with innerHTML
for (let i = 1; i <= 8; i++) {
const button = document.createElement('button');
button.innerHTML = `Button ${i}`;
container.appendChild(button);
}
如下圖所示,這還只是產生8個按鈕的時候喔,別忘了還有樣式,而且你看上圖旁邊還有一個放大鏡icon要插入,這樣搞下來恐怕是一場災難,可能還要穿梭在 html
標籤之中,大概是不會來去自如而是寫出義大利麵程式碼,就是互相呼叫,毫無邏輯,基本上無法維護,想要修改就只能重寫的程式碼。筆者已經無法想像這種慘況了。
此外, inner html
還有 XSS
的風險,例如你打算插入一個 <p>使用者輸入內容 </p>
的標籤進入,可是有心的使用者輸入了 <script> alert("you are hacked")</script>
,這樣使用者瀏覽器就會彈出 you are hacked的對話框,這只是示範,既然能讓使用者彈出對話框,當然也可以 **執行任何程式碼 (ACE),**這可是非常危險的,但是如果是手工進行安全防護,費時費力,不如讓框架代勞。
最後,有時候在渲染樹狀結構(例如資料夾)的時候,剛剛的範例還需要加上遞迴,
function renderFolderTree(folder, parentElement) {
const li = document.createElement("li");
li.textContent = folder.name;
li.classList.add(folder.type); // Add class for styling
if (folder.type === "folder") {
li.addEventListener("click", (event) => {
event.stopPropagation(); // Prevent event bubbling to parent folders
li.classList.toggle("active"); // Toggle visibility of children
});
const ul = document.createElement("ul");
if (folder.items) {
folder.items.forEach((item) => {
renderFolderTree(item, ul); // Recursive call for nested items
});
}
li.appendChild(ul);
}
parentElement.appendChild(li);
}
const folderTreeContainer = document.getElementById("folderTree");
renderFolderTree(folderData, folderTreeContainer);
真的蠻難懂的吧
而這時元件可以自我引用的優勢就出現了,元件有點像是專為html設計的函數,只要把元件自我引用,然後加上終止條件,就可以輕鬆實現這種效果了,反觀上面的 純 js實現還要處理比較底層的 DOM(html標籤)細節。
<template>
<ul>
<li v-for="item in items" :key="item.name" :class="item.type">
<span @click="toggle(item)">
{{ item.name }}
</span>
<folder-tree v-if="item.type === 'folder' && item.isOpen" :items="item.items" />
<! 終止條件>
</li>
</ul>
</template>
狀態管理
網站是事件導向的程式,有事件才會有動作。而人看不到狀態,需要被渲染到螢幕上人才能看到,如果不用框架大概長這樣
<!DOCTYPE html>
<html>
<head>
<title>Button Click Counter</title>
</head>
<body>
<button id="myButton">Click Me</button>
<p>Clicked <span id="countDisplay">0</span> times</p>
<script>
let count = 0; // 狀態儲存在全域變數
const button = document.getElementById('myButton');
const countDisplay = document.getElementById('countDisplay');
// 這邊其實都可以讓框架代勞
button.addEventListener('click', () => {
count++;
countDisplay.textContent = count; // 手動更新 DOM
});
// 這邊其實都可以讓框架代勞
</script>
</body>
</html>
如果是簡單的網站,手動使用 DOM API來操作可能還算是一個權宜之計,但是這個前提是你要知道何時何地如何更新阿,如果專案一大基本上常人沒辦法掌握,根本搞不清楚到底甚麼時候要更新,如此一來恐怕是BUG連環爆。
不過雖然也有一些 getter
代理物件 手動事件 訂閱模式等等比較進階的技巧可以實現等效框架功能,但是軟體界有一句話 不要重新發明輪子,既然已經有經過時間考驗的解決方案,而且又是MIT可商用授權的,幹嘛不要直接用。
而在 vuejs
的作法是如下
<template>
<div>
<button @click="handleClick">Click Me</button>
<p>Clicked {{ count }} times</p> {/* Vue 會自動更新 DOM */}
</div>
</template>
<script>
export default {
data() {
return {
count: 0, // 使用 data 屬性管理狀態
};
},
methods: {
handleClick() {
this.count++; // 通過 this.count 更新狀態
},
},
};
</script>
有看到 <template>
標籤之下有個 {{count}}
語法嗎,那個就是表示 data()
中裡面的 count
變數的站位字元,而這裡厲害之處就是他是基於虛擬DOM來渲染的,效能比普通的DOM操作更高,此外, {{count}}
這個地方只要 count
變數有更改,他就會在畫面用新的資料同步渲染。
例如如果原本 count=1
那前端畫面就會顯示 Click 1 times,而如果 count變數突然變成2了,前端畫面也會跟著變成 click 2 times。
這個非常方便的功能就像一個秘書一樣,幫忙處理 **把資料渲染到前端畫面上 ,**這種看似無聊但是很重要、需要細心注意何時何地怎麼渲染的瑣事。
身為開發者,如果使用框架就能像老闆一樣,應該是只要專心在業務邏輯上就好,把資料送到變數上面,就會自動地被渲染出來,如一來可以大大提升開發效率。而不是專心在跟自己沒關係的東西上面,例如訂機票之類的。
為甚麼推薦vue
因為 vue
是漸進式框架,漸進式,顧名思義,僅取所需,也代表他的學習曲線低。
而且就算你可能 javascipt
語法不熟甚至根本不會, 都還蠻有機會學會 vue
的。
此外它的設計真的是新手友善的,建立一個元件有點像是填表格,把 <template>
<style>
跟 <script>
依樣畫葫蘆,分別對應內容、樣式跟互動,而元件的邏輯(也就是如何定義互動方式,在這裡通常會叫他邏輯),也是遵循這種風格的
<script> // 有複數個用逗點隔開
export default{
data(){
return {
你的變數 : "helloVue"
}
}
},
methods:{
你的函數(){
函數內容
}
}
</script>
元件邏輯在 export default的 {}
中定義,有點像是元件的入口。
裡免有許多清楚的元件邏輯函數,列舉如下(用法如上)
- data() 定義 資料(名詞) 可以在
<template>
透過雙大括號語法讓他同步渲染 - method() 定義方法(函數) 就像是動詞
- create()定義建立時的初始化操作 (有點像是前處理)
等等
反觀react光是要宣告元件資料,就用了一個 useState
這種需要許多 js
知識的機制,這個恐怕會勸退許多初學者
此外 angular
是強制使用 typescript
的,也就是開發者需要明確知道 js
物件的資料型態,並且把它標住在旁邊,提供編譯器檢查,好處是錯誤很少啦,但是壞處也是顯而易見,就是學習曲線高,畢竟新手可能連 js
都有點搞不定了,遑論 typesctipt
。
總結
隨著前端日益複雜,簡單的 javascript
已經無法滿足開發者對於效率的追求了,因此才會出現這麼多框架來解決問題,而 vuejs
我覺得是個對新手友善的框架,得益於他漸進式的特性而學習曲線平坦,非常推薦大家學習。
<script>
Vue.createApp({
data(){
return{
msg: "Vuejs"
}
},
}).mount(".app")
</script>