Lala Code

Lala 的前端大補帖,歡迎一起鑽研前端技術😊

0%

Vue3基本操作-2

computed

範例 1: 自動長出 menu 高度

計算屬性

1
2
3
4
<a @click="HandListShow" class="title">菜單</a>
<ul class="box" :style="{height: toggleH}">
<li v-for="(list, idx) in listArr" :key="list">{{list.name}}</li>
</ul>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
const { ref, reactive, computed } = Vue;
const App = {
setup() {
const isOpen = ref(true);
const listArr = reactive([
{ name: "蛋糕", money: 3200 },
{ name: "紅茶拿鐵", money: 100 },
{ name: "義大利麵", money: 500 },
{ name: "玉米濃湯", money: 300 },
{ name: "海鮮燉飯", money: 1600 },
{ name: "夏威夷披薩", money: 900 },
{ name: "牛肉麵", money: 2000 },
{ name: "法國麵包", money: 1800 },
]);

const HandListShow = () => {
isOpen.value = !isOpen.value;
};

const toggleH = computed(() => {
return isOpen.value ? `${listArr.length * 40}px` : 0;
});

return {
isOpen,
listArr,
HandListShow,
toggleH,
};
},
};

Computed 跟 Methods

computed

會依據計算的資料進行緩存,只要你的資料沒有重新被更改,你的 computed 不會被重新計算執行,如不須傳入參數,建議都使用 computed 計算

methods

雖可以達到一樣的效果,但 methods不會進行緩存,每次都會重新執行 ,可以傳入參數進行處理

範例 2: 計算資料

利用 computed 取得資料

1
2
3
4
<a @click="HandListShow" class="title">菜單</a>
<ul class="box" :style="{height: toggleH}">
<li v-for="(list, idx) in newMenu" :key="list.menu">{{list.menu}}</li>
</ul>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
const { ref, reactive, computed } = Vue;
const App = {
setup() {
const isOpen = ref(true);
const listArr = reactive([
{ name: "蛋糕", money: 3200 },
{ name: "紅茶拿鐵", money: 100 },
{ name: "義大利麵", money: 500 },
{ name: "玉米濃湯", money: 300 },
{ name: "海鮮燉飯", money: 1600 },
{ name: "夏威夷披薩", money: 900 },
{ name: "牛肉麵", money: 2000 },
{ name: "法國麵包", money: 1800 },
]);

const HandListShow = () => {
isOpen.value = !isOpen.value;
};

const toggleH = computed(() => {
return isOpen.value ? `${listArr.length * 40}px` : 0;
});

const newMenu = computed(() => {
const map = listArr.map((item) => {
return { menu: `${item.name}, $: ${item.money}` };
});
return map;
});

return {
isOpen,
newMenu,
HandListShow,
toggleH,
};
},
};

範例三: 資料篩選 Data Filter

v-for 跟 v-if 官方不推薦一起使用,會有優先順序的問題,v-if 會先執行,v-for 的值會變 undefined
正確的做法應該要先透過 computed 把資料篩選出來後再進行 v-for
只要被 computed 重新包裝過後,須使用.value取得資料

1
2
3
4
5
6
<a @click="HandListShow" class="title">課程列表</a>
<ul class="box" :style="{height: BoxHeight}">
<li v-for="(list, idx) in filterData" :key="list.money">
{{idx + 1}}. {{list.name}} => ${{list.money}}
</li>
</ul>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
const { ref, reactive, computed } = Vue;
const App = {
setup() {
const isOpen = ref(true);
const listArr = reactive([
{ name: "蛋糕", money: 3200 },
{ name: "紅茶拿鐵", money: 100 },
{ name: "義大利麵", money: 500 },
{ name: "玉米濃湯", money: 300 },
{ name: "海鮮燉飯", money: 1600 },
{ name: "夏威夷披薩", money: 900 },
{ name: "牛肉麵", money: 2000 },
{ name: "法國麵包", money: 1800 },
]);

const filterData = computed(() => {
const filter = listArr.filter((item) => item.money > 500);
console.log(filter);
return filter;
});

const BoxHeight = computed(() => {
// 被 computed 重新包裝過後,須使用`.value`取得資料
return isOpen.value ? `${filterData.value.length * 40}px` : "0px";
});

const HandListShow = () => {
isOpen.value = !isOpen.value;
};

return {
isOpen,
filterData,
HandListShow,
BoxHeight,
};
},
};

watch

資料監控
可帶入兩個參數,如資料被改變會自動執行 callback

1
watch(要監控的資料, (新資料, 舊資料) => {});

監控 ref

1
2
3
4
5
6
7
8
9
10
11
12
13
const { ref, reactive, watch } = Vue;
const App = {
setup() {
const idx = ref(0);
watch(idx, (newIdx, oldIdx) => {
console.log("newIdx:", newIdx, "oldIdx:", oldIdx);
});
setInterval(() => {
idx.value++;
}, 1000);
return {};
},
};

監控 reactive

watch 監控的值為 getter,只能被讀取的值,需透過函式回傳 reactive 的值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
const { ref, reactive, watch } = Vue;
const App = {
setup() {
const data = reactive({ idx: 0 });
watch(
() => data.idx, // watch監控的值為getter,只能被讀取的值
(newIdx, oldIdx) => {
console.log("newIdx:", newIdx, "oldIdx:", oldIdx);
}
);
setInterval(() => {
data.idx++;
}, 1000);
return {};
},
};

監控整個 Array 或 object

ref 不能監控整個物件的變動,只能監控單一值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
const { ref, reactive, watch } = Vue;
const App = {
setup() {
const refObj = ref({ idx: 0 });
const reactiveObj = reactive({ idx: 0 });
watch(refObj, (newIdx) => {
console.log("ref", refObj);
});
watch(reactiveObj, (newIdx) => {
console.log("reactiveObj", reactiveObj);
});
setTimeout(() => {
refObj.value.idx++;
reactiveObj.idx++;
});
return { refObj, reactiveObj };
},
};

如需使用 ref 做深層監控,可以使用 deep,但非常耗效能,不建議使用,建議監控單一值就好

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
const { ref, reactive, watch } = Vue;
const App = {
setup() {
const data = ref({ user: {} });

watch(
data,
(newVal) => {
console.log(newVal);
},
{ deep: true }
);

setTimeout(() => {
data.value.user["name"] = "波比";
}, 1000);

return {};
},
};

watchEffect

不須傳入要監控的值,值在還沒變動時就會開始監控
有寫進 watchEffect 的資料都會被讀取,即使是沒有改變的值也會再被 show 出來

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
const { ref, reactive, watchEffect } = Vue;
const App = {
setup() {
const num = ref(0);
const numData = reactive({ idx: 0 });

watchEffect(() => {
console.log(num.value);
});
setTimeout(() => {
num.value++;
numData.idx++;
}, 1000);

return {};
},
};

停止 watchEffect 的監控

給 watchEffect 自定義一個變數,並執行,將會停止 watchEffect

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
const { ref, reactive, watchEffect } = Vue;
const App = {
setup() {
const num = ref(0);
const numData = reactive({ idx: 0 });
let timer = null;
const stop = watchEffect(() => {
console.log(num.value);
if (num.value >= 4) {
stop(); // 停止watchEffect
clearInterval(timer); // watchEffect關閉後不會停止setTimeout,需要再clearInterval
}
});
timer = setTimeout(() => {
num.value++;
numData.idx++;
}, 1000);
return {};
},
};

如果這篇筆記有幫助,麻煩請幫我按五下 Liker,給我一點鼓勵唷!按讚是免錢滴 😀



🚀實體工作坊分享

玩轉 Web頁面的前端技術(HTML/CSS/JS) 一日體驗課

最近時賦學苑開了實體體驗課,即使你對程式碼沒有概念也能上手!Lala 會帶你一起做出一個個人品牌形象網站,帶你快速了解前端的開發流程,快跟我們一起玩轉 Web 吧!



🚀線上課程分享

線上課程可以加速學習的時間,省去了不少看文件的時間XD,以下是我推薦的一些課程
想學習更多關於前後端的線上課程,可以參考看看。

Hahow

Hahow 有各式各樣類型的課程,而且是無限次數觀看,對學生或上班族而言,不用擔心被時間綁住



六角學院

如果你是初學者,非常推薦六角學院哦!
剛開始轉職也是上了六角的課,非常的淺顯易懂,最重要的是,隨時還有線上的助教幫你解決問題!


Udemy

Udemy 裡的課程非常的多,品質普遍不錯,且價格都滿實惠的,CP值很高!
也是很多工程師推薦的線上課程網站。
❤️