Vue
-
模板
<div id="app">\{\{ message }}</div>
-
資料與方法
<script> var app = new Vue({ el: "#app", data: { message: "Hello Vue!", }, }); </script>
模板語法
- v—text 顯示文字
- 或是 {{}} 也可以顯示文字
- {{ dataname }}
- 可以運算 {{ count + 1 }}
- 若為條件式,只能用三元 {{ ok? “yes” : “no” }}
- {{ mes.spilt(“”).reverse().join(“”) }}
- 或是 {{}} 也可以顯示文字
- v—html 顯示 HTML
- v-if、v-else、v-elseif、v-show
- v-if 切換時,真的會新增或移除 DOM,
- v-show 僅是套用樣式,false 時套用
display: none
- 如果條件常常改變,用 v-show 比較好
-
v-for
<li v-for="n in 10">\{\{n}}</li>
<li v-for="todo in todo_list">\{\{todo}}</li>
-
object
- 一定要先寫 value 再寫 key
<li v-for="(value, key) in todo_list">\{\{key}} : \{\{value}}</li>
-
Vue 1 的 track-by => key
- 如果只用 for 沒有用 key 的話,如果裡面有 input 之類的,會有問題,原因是因為沒有綁定 id
-
-
v-bind 屬性綁定、class、style
v-bind:class="{is_finished: todo.is_finished}
- v-bind 可以簡寫為
:
:style="{color: mycolor , fontSize: myFontSize }"
:href="url"
-
v-model 雙向綁定某個 data
-
只用在 input、select、textarea
<input v-model="new_todo_text" />
-
.lazy 提高頁面處理效能,整個輸入完才更新值 (預設類似 onkeyup,用 lazy 之後類似 onchange)
<input v-model.lazy="username" />
-
.number 轉為數值
<input v-model.number="age" type="number" />
-
.trim 自動過濾前後的空格
<textarea v-model.trim="content" col="55" row="8">
-
- v-on 事件綁定
v-on:click="delete_todo(todo)"
- v-on 可以簡寫為
@
@click="delete_todo(todo)"
- 取消冒泡或預設行為
event.stopPropagation()
event.preventDefault()
v-on:submit.stop.prevent="delete_todo(todo)"
- 鍵盤事件
v-on:keyup.enter="delete_todo(todo)"
template
最外層只能有一個根節點
<body>
<div id="app">
<my-component></my-component>
</div>
<script>
Vue.component("my-component", {
template: '<div class="component"> <span> \{\{count}} </span> </div>',
props: ["count"],
});
new Vue({
el: "#app",
data: {
counts: 0,
},
});
</script>
<body></body>
</body>
或是
<body>
<div id="app">
<my-component></my-component>
</div>
<script type="text/x-template" id="my-component">
<span> \{\{count}} </span>
</script>
<script>
Vue.component("my-component", {
template: "#my-component",
props: ["count"],
});
new Vue({
el: "#app",
data: {
counts: 0,
},
});
</script>
<body></body>
</body>
資料與方法
- data 放資料
-
methods 放 function
-
用 this 來讀取 data 資料
var myapp = new Vue({ el: '#app', data: { message: 'abc', } methods: { reverseMessage: function() { return this.message.spilt("").reverse().join(""); } } });
-
- computed 資料變動時,某個資料也會變動時
- computed 是在監控資料更動後,重新運算結果呈現於畫面上,一般來說不會修改資料,只會回傳用於畫面呈現的資料
- methods 就是互動的函式,需要觸發才會運作,會用來修改資料內容
- 如果資料量大,computed 自然會比較慢,只要資料變動就會觸發,無形之中執行次數也會增加,因此在大量資料時,會建議透過 methods 減少不必要的運算喔
- watch 資料變動時,會 call 的 function
- 常用在監聽滾動事件 scroll
-
filters 過濾器
<div id="app"> <p>\{\{ msg | touppercase }}</p> <p></p> <p>\{\{ num | topercetage }}</p> <p></p> </div> <script> var myapp = new Vue({ el: '#app', data: { msg: 'abc', num: 0.3 } filters: { touppercase: function(value){ return value.toUpperCase(); }, topercetage: function(value){ return value * 100 + '%'; } } }); </script>
元件
- 使用元件來避免共用資料
- data 必須是一個 function
-
Vue.component 定義全局元件
<div> <count-component></count-component> <count-component></count-component> <count-component></count-component> </div> <script> Vue.component("count-component", { template: "<button @click="add">8</button>", data: function() { return { count: 0, }; }, methods: { add: function() { this.count++; } } }); const app = new Vue({ el: '#app' }); </script>
-
也可以使用 component 定義區域元件
new Vue({ el: "#app", components: { "component-a": ComponentA, "component-b": ComponentB, }, });
-
在 ComponentB 可以使用 ComponentA,但 ComponentA 不可以使用 ComponentB
var ComponentA = { /* ... */ }; var ComponentB = { components: { "component-a": ComponentA, }, // ... };
- props、emit event
- 資料從爸爸來 => props
- 資料要給爸爸 => emit event
- $.on 綁定監聽事件
- $.emit 向上發送事件
生命週期
event bus 同層去傳遞資料
- 小心同名事件
:is 動態指定
- 用來切換 tab 很方便
<div id="app">
<div id="left">
<button @click:"currentChannel = channel-1">channel-1</button>
<button @click:"currentChannel = channel-2">channel-2</button>
<button @click:"currentChannel = channel-3">channel-3</button>
</div>
<div id="right">
<componet :is="currentChannel"></componet>
</div>
</div>
<script>
Vue.component('channel-1', {
template: '<div class="channel">1</div>',
});
Vue.component('channel-2', {
template: '<div class="channel">2</div>',
});
Vue.component('channel-3', {
template: '<div class="channel">3</div>',
});
new Vue({
el: '#app',
data: {
currentChannel: 'channel-1'
}
});
</script>
<keep alive> 保持狀態
- 會保留在記憶體,但是在頁面不會顯示,避免重新渲染
- 呈上 :is 一起運用,就可以用來保持狀態
- 被呼叫到的,hook 是 activated()
slot
- 在子元件挖個洞,讓外層的塞
Vue.set
- 如果某個資料還沒被宣告,需要動態加入的話,可以使用 Vue.set
<div id="app">
<button @click="work">work</button>
<div v-for="person in people">\{\{person.name}}} - \{\{person.age}}}</div>
</div>
<script>
var app = new Vue({
el: "#app",
data: {
people: [
{
name: "elaine",
age: 20,
},
{
name: "nick",
age: 70,
},
],
},
methods: {
work: function() {
// this cannot work
// this.people[0] = {
// name: "amy",
// age: 18,
// };
Vue.set(this.people, 0, {
name: "amy",
age: 18,
});
},
},
});
</script>
表單
-
true-value、false-value
<input v-model="gender" true-value="male" false-value="female" /> <script> var app = new Vue({ el: "#app", data: { gender: "male", }, }); </script>
其他
- 一個頁面可以有多個 Vue 的實例
- Vue 的實例無法巢狀
- js 裡面是無法有
-
,所以background-img
要改成backgroundImg
- 樣式的方法有
- 物件
:class="{'active': isActive, 'bg-danger': boxColor}"
- 陣列
:class="['active', 'bg-danger']"
- 行內樣式
:style="{backgroundColor: 'red', color: 'white'}"
:style="[backgroundColor: 'red', color: 'white']"
- Vue 會自動加上 prefix
- 物件
- v-for 注意事項
- 物件的 index 是物件的屬性、陣列的 index 是從 0 開始的正數字
- 有 input 的時候特別注意
- 因為 Vue 並不會完全置換 DOM 物件,所以會有該 input 不會跟從原 DOM 的問題
- 解決方法只要綁上
:key
就可以了
- 直接操作陣列
- 直接將陣列長度 = 0,並不會運行
- 直接修改陣列 index,例如
array[2]=true
,並不會運行- 需要用
Vue.set(array,2,true)
此方法,才能讓 Vue 重新監控
- 需要用
- 因為只能回傳一個節點,可以使用
<template v-for="...">
來協助輸出 - 當 v-for 和 v-if 寫在同一個,會先執行 v-for 再執行 v-if
- 如果我們要透過 Ajax 讀取資料,至少到 create 階段才能正確運作,常用 mounted 也可以
- 必須要一開始就定義好 data 的格式,Vue 才有辦法追蹤資料來改變 DOM 節點