本篇主要是透過線上課程:HiSKIO、w3school及網路上搜尋資源所學習的。
實例 Instance
- 元素掛載($mount)、模板(template)
- 狀態(data)
- 方法(method)
- 計算屬性(computed)
- 偵聽(watch)
- 生命週期(life cycle hooks)
元素掛載、模板
宣告 vue 實例(new Vue)後要連結 html 元素,el 是元素 element 的縮寫,可以使用 CSS selector 的方式也可以用 JS 獲取名稱,要注意不能同時掛載多個相同的元素,只會掛載第一個符合的元素。
元素掛載的部分也可以在宣告實例後,有需要用到再去掛載。
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 
 | <div id="app"><h1>{{msg}}</h1>
 </div>
 
 <script>
 
 
 
 
 const vm = new Vue({
 el: "#app",
 
 
 template: "<div><h2>{{msg}}{{msg}}</h2></div>",
 data: {
 msg: "Hello!!"
 }
 });
 
 
 
 </script>
 
 | 
狀態-data
vue 實例的狀態,或者是說資料,本身是物件。
data 的宣告也可以在實例外面,在實例中再去取用該名稱,也可以重新給值。
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 
 | <div id="app">{{a+b}}</div>
 <script>
 const data = {
 a: 1,
 b: 2
 };
 const vm = new Vue({
 el: "#app",
 
 
 
 
 data
 });
 
 vm.a = 3;
 console.log(data.a);
 console.log(vm.$data === data);
 </script>
 
 | 
方法-methods
methods 也是物件,要宣告實例中會用到的 function,在 html 則是要用 v-on:來綁定事件。
也可以在 methods 的其中一個函式用 this.函式名稱去執行另一個 methods 中的函式,但要注意 data 的屬性名稱跟 methods 中函式名稱不能一樣。
在 methods 中不要去使用到箭頭函式,在 methods 中的 this 是指導 vue 實例本身,如果用箭頭函式 this 則會指到 window。
| 12
 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
 
 | <div id="app"><h1>{{count}}</h1>
 <button v-on:click="add1">+1</button>
 <br />
 <button v-on:click="add2">+{{step}}</button>
 <br />
 <button v-on:click="add3">+{{step}}</button>
 </div>
 
 <script>
 const vm = new Vue({
 el: "#app",
 
 data: {
 count: 0,
 step: 1
 },
 
 methods: {
 add1() {
 this.count += 1;
 },
 add2() {
 this.count += this.step;
 this.step += 1;
 },
 add3() {
 this.add2();
 }
 }
 });
 </script>
 
 | 
計算屬性-computed
computed 也是物件,裡面可以宣告成函式,也可以宣告為物件。
物件中可以宣告 get、set 函式,在取用這個物件的時候,程式就會直接執行 get 這個函式。當要改變物件名稱的值的時候就會去執行 set 函式。
宣告函式與宣告物件中的 get 都需要 return。
用 input 相加的結果來記錄說明

| 12
 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
 
 | <div id="app"><input type="number" v-model="a" />
 +
 <input type="number" v-model="b" />
 =
 
 <input type="number" v-model="answer" />
 <br />
 {{a}}+{{b}}={{answer}}
 </div>
 
 <script>
 const vm = new Vue({
 el: "#app",
 data: {
 a: 0,
 b: 0
 },
 
 computed: {
 
 
 
 
 
 answer: {
 get() {
 return parseInt(this.a) + parseInt(this.b);
 },
 
 set(val) {
 this.b = parseInt(val) - parseInt(this.a);
 }
 }
 }
 });
 </script>
 
 | 
偵聽-watch
watch 顧名思義就是要監聽,型態同樣是物件,裡面可以宣告函式,也可以宣告成物件。
宣告的名稱需要跟 data 或是 computed 裡面的屬性名稱是相同的。
宣告為函式時,()中第一個參數是現在的值,第二個參數是上一個舊的值。
| 12
 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
 
 | <div id="app"><input type="text" v-model="value" />
 <span>{{valuex2}}</span>
 </div>
 
 <script>
 const vm = new Vue({
 el: "#app",
 data: {
 value: 0
 },
 methods: {},
 computed: {
 valuex2() {
 return parseInt(this.value) * 2;
 }
 },
 
 watch: {
 value(val, oldVal) {
 console.log(`${oldVal} -> ${val}`);
 },
 valuex2(val, oldVal) {
 console.log(`${oldVal} -> ${val}`);
 }
 }
 });
 </script>
 
 | 
宣告為物件時,裡面要有一個 handler 函式,還有兩個屬性
- immediate: ture or false
- deep: ture or false
immediate為一初始化就跑一次 watch
deep偵聽對象只能是「屬性的內容」為陣列或是物件
不能濫用 watch
像這個案例 input - a+b=c
a 與 b 在 watch 要分開偵聽,實效能差,且不符合聲明,實務上用 computed 直接偵聽 c 即可。
| 12
 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
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 
 | <div id="app">
 
 
 
 <input type="text" v-model="a" />+ <input type="text" v-model="b" />=
 <input type="text" v-model="c" />
 </div>
 
 <script>
 const vm = new Vue({
 el: "#app",
 data: {
 
 
 
 a: 0,
 b: 0,
 c: 0
 },
 methods: {},
 computed: {
 
 c() {
 return parseInt(this.a) + parseInt(this.b);
 }
 },
 watch: {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 a(val) {
 this.c = parseInt(val) + parseInt(this.b);
 },
 b(val) {
 this.c = parseInt(val) + parseInt(this.a);
 }
 }
 });
 </script>
 
 | 
生命週期
以下六種都在 client side rendering
- beforeMount
 當決定 render 的時候會執行,掛載修改的內容(模板)
 
- Mounted
 掛載後才執行這個函式
 最常用的,ajax 或偵聽事件元素或 window 等等
 
- beforeUpdate
 資料變更先跑這個
 
- updated
 資料變更後會跑 updated 函式
 
- beforeDestroy
 呼叫 vm.$destroy 摧毀前會先執行
 
- destroyed
 呼叫 vm.$destroy,全部 vue 摧毀
 取消偵聽等等
 

實作-密碼強度檢查
會員註冊時,即時的檢查,如密碼太短,只用數字不夠強等等。
- v-model雙向綁定data
- computed計算密碼強度(長度),包含用正規表達式判斷大小寫數字等等。
| 12
 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
 
 | <div id="app"><input type="password" v-model="password" />
 <p>{{strength}}</p>
 </div>
 
 <script>
 const vm = new Vue({
 el: "#app",
 data: {
 password: ""
 },
 computed: {
 strength() {
 let score = this.password.length;
 
 if (/[A-Z]/.test(this.password)) score *= 1.25;
 if (/[a-z]/.test(this.password)) score *= 1.25;
 if (/[0-9]/.test(this.password)) score *= 1.25;
 if (/[^A-Za-z0-9]/.test(this.password)) score *= 1.25;
 
 if (score > 40) return "Perfect";
 if (score > 20) return "Great";
 if (score > 10) return "Good";
 return "Weak";
 }
 }
 });
 </script>
 
 | 
補充
Single source of truth
資料來源只能有一個
- html中用- :checked跟- @change測試,vue中的data中包含selected:空陣列- [],搭配methods:select()來判斷index後,進行push或是splice
 
- 延續第一點,data中seleted空陣列改在computed中,methods中則以簡單一行處理 
- 實務上html中會用v-model,computed中用簡短一行,filter處裡,methods則全部不用 
附上程式碼:
| 12
 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
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 
 | <div id="app">
 
 
 
 
 
 
 
 
 
 
 
 
 
 <label>
 <input type="checkbox" v-model="a">
 <span>a</span>
 </label>
 <label>
 <input type="checkbox" v-model="b">
 <span>b</span>
 </label>
 <label>
 <input type="checkbox" v-model="c">
 <span>c</span>
 </label>
 <br>
 <span>{{selected}}</span>
 </div>
 
 <script>
 new Vue({
 el:"#app",
 data:{
 a:false,
 b:false,
 c:false,
 
 },
 computed:{
 
 
 
 
 
 
 
 
 
 
 selected(){
 return ['a', 'b', 'c'].filter(item => this[item]);
 },
 },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 });
 </script>
 
 |