官網:https://cn.vuejs.org/v2/guide/index.html
Vue.js 的核心是一個允許采用簡潔的模板語法來聲明式地將數據渲染進 DOM 的系統。
視頻教程:https://scrimba.com/g/glearnvue
- 介紹
- 實例
- 模版語法template
- computed, watch
- v-if, v-show
- v-for, 一個組件的v-for.
查看我的codepen案例: https://codepen.io/chentianwei411/pen/EemeMg?editors=1010
基礎
關鍵知識點:
- JS中 new Vue({el: '#id', data: { message: "Hello Vue!"}})
- v-bind:property #property可以是自定義特性也可以是HTML特性。用於在DOM上應用響應式行為
- v-if="xxx" 條件: xxx的結果是true/false
- v-for="xxx in xxxs" 循環: ⚠️寫法
- v-on:click='methods_name' 這是類似addEventListener()添加事件監聽v-on
- v-model='message' 用於實現表單輸入input和應用狀態之間的雙向綁定
- 等同於用vailina javascript: 使用oninput事件 (點擊見案例)
- ⚠️ oninput, 和onchange有區別:
- oninput專門用於<input>,<textarea>tag,輸入即變化
- onchange用於當元素的value發生變化且元素失去focus后執行。
-
Vue.component('todo-item', {
template: '<li>這是個待辦項</li>'
}) - 一個組件本質上是一個擁有預定義選項的一個 Vue 實例,上面定義的主機todo-item可以用在DOM中了。
- props: ['todo'], props用於定義組件特性property,類似HTML元素的特性。
- ⚠️如果組件和new Vue寫在一個腳本內,則注意,先寫組件,再寫new Vue
組件和自定義元素的關系:
- 類似但有區別,兼容所有瀏覽器。
- Vue.component比純自定義元素有優勢,如跨組件數據流、自定義事件通信以及構建工具集成。
Vue實例
一個 Vue 應用由一個通過 new Vue
創建的根 Vue 實例,以及可選的嵌套的、可復用的組件樹組成。舉個例子,一個 todo 應用的組件樹可以是這樣的:
根實例 |
new Vue({
//options;
})
數據屬性 data 和 method
當一個 Vue 實例被創建時,它向 Vue 的響應式系統中加入了其 data
對象中能找到的所有的屬性。當這些屬性的值發生改變時,視圖將會產生“響應”,即匹配更新為新的值。
注意: 只有當實例被創建時 data
中存在的屬性才是響應式的, 后添加的屬性不是響應式的。
var obj = {
foo: 'bar'
}
Object.freeze(obj)
new Vue({
el: '#app',
data: obj
})
Object.freeze()阻止修改現有的屬性,也意味着響應系統無法再追蹤變化。
Vue 實例還暴露了一些有用的實例屬性與方法。它們都有前綴 $
,以便與用戶定義的屬性區分開來。例如:
var data = { a: 1 } |
鈎子函數
如 created, mounted
、updated
和 destroyed
。生命周期鈎子的 this
上下文指向調用它的 Vue 實例。
不要在選項屬性或回調上使用箭頭函數
模版語法
Vue 將模板編譯成虛擬 DOM 渲染函數。
如果你熟悉虛擬 DOM 並且偏愛 JavaScript 的原始力量,你也可以不用模板,直接寫渲染 (render) 函數,使用可選的 JSX 語法。
插值
Mustache 即{{}}用雙大括號,綁定數據, 數據轉換為普通文本。
v-html 接受原始html元素。但盡量別用,容易遭到xss攻擊。
Mustache 語法不能作用在 HTML 特性上,遇到這種情況應該使用 v-bind 指令
Vue.js 都提供了完全的 JavaScript 表達式支持
{{ number + 1 }}
{{ ok ? 'YES' : 'NO' }} #支持三元語法,但不能用if,這是控制流。
{{ message.split('').reverse().join('') }}
<div v-bind:id="'list-' + id"></div>
⚠️,不能聲明變量,聲明變量是語句,不是表達式。
指令v-
預期值是單個js表達式。v-for是例外。
指令的職責是,當表達式的值改變時,將其產生的連帶影響,響應式地作用於 DOM。
參數
部分指令可以接收參數(HTML特性,自定義特性)
<a v-bind:href= 'url'>...</a>, 這里的參數是href,v-bind將元素a的href特性和表達式url的值綁定。
修飾符
以半角句號 .
指明的特殊后綴,用於指出一個指令應該以特殊方式綁定。
.prevent
會調用event.preventDefault();
<form v-on:submit.prevent="onSubmit">...</form> |
縮寫
v-bind: 縮寫是:
v-on 縮寫是@
計算屬性和偵聽器
computed
由模版語法{{}}擴展而來,比較復雜的表達式,由於不方便維護,所以產生了computed屬性。
注意⚠️ 用到return
計算屬性的功能也可以用method屬性方法實現,但有本質區別:
- computed的結果是緩存的。
- ethod在每次重新觸發渲染后都會從新執行函數。
methods: {
reversedMessage: function(){
return this.message.split('').reverse().join("")
}
}
插值加上括號(): {{ reversedMessage() }}
計算屬性的setter
計算屬性默認只有 getter ,不過在需要時你也可以提供一個 setter :
在表達式內使用get和set函數:
運行 vm.fullName = 'John Doe'
時,setter 會被調用,vm.firstName
和 vm.lastName
也會相應地被更新。
watch 偵聽屬性
用於觀察和響應 Vue 實例上的數據變動 。
然而,通常更好的做法是使用計算屬性而不是命令式的 watch
回調。
大多數時候computed時候,有時候也需要用自定義的watch。當需要在數據變化時執行異步或開銷較大的操作時,這個方式是最有用的。
Class 與 Style 綁定
在將 v-bind
用於 class
和 style
時,Vue.js 做了專門的增強。表達式結果的類型除了字符串之外,還可以是對象或數組。
綁定class
對象語法:
問題?見下面2圖,無法產效果。
數組語法:
綁定內聯樣式:
數組語法:
CSS 屬性名可以用駝峰式 (camelCase) 或短橫線分隔 (kebab-case,記得用單引號括起來) 來命名
如: fontSize 或 'font-size'
HTML:
<div id="app" v-bind:style="{ color: activeColor, fontSize: fontSize + 'px' }">你好</div>
JS:
new Vue({
el: "#app",
data: {
activeColor: 'red',
fontSize: 50
}
})
對象語法:
問題: 不明白:用綁定一個樣式對象的方法在codepen上不成功,不知道原因。
問題???無論是
條件渲染 v-if="", v-else , v-else-if=""
HTML:
<div id="h1">
<h1 v-if='ok'>Welcome to Beijing</h1>
<h1 v-else>Sorry, Closed</h1>
</div>
JS:
new Vue({
el: '#h1',
data: {
ok: false
}
})
解釋: ok 可以是判斷表達式。如ok: Math.random() > 0.5
template可以當作不可見包裹元素和 v-if一起使用。
用 key 可以區別復用的元素
V-show: 簡單地切換元素的 CSS 屬性 display
。沒有其他作用。不支持<template>元素。
v-show vs v-if
v-if
是“真正”的條件渲染,因為它會確保在切換過程中條件塊內的事件監聽器和子組件適當地被銷毀和重建。
- 只有當v-if條件為真時,才會渲染。
- 而用v-show, 總會渲染,條件只是控制css#display
v-if with v-for
同node下,v-for的優先級比v-if高。除非,把v-if放在父節點。
<ul v-if="todos.length">
<li v-for="todo in todos">
{{ todo }}
</li>
</ul>
<p v-else>No todos left!</p>
具體看列表渲染: https://cn.vuejs.org/v2/guide/list.html#v-for-with-v-if
列表渲染
用v-for 把一個數組對應為一組元素
v-for
指令需要使用 item in items
形式的特殊語法。
items
是源數據數組。item
是數組元素迭代的別名。
在 v-for
塊中,我們擁有對父作用域屬性的完全訪問權限。
v-for
還支持一個可選的第二個參數為當前項的索引。v-for="(item, index) in items"- index是隱藏索引,從0開始
可以使用of替代in, v-for="(item, index) of items"
一個對象(就是hash)的 v-for
對象可以有三個參數, v-for="value, key, index in object"
注意第二個參數是 key
key
建議盡可能在使用 v-for
時提供 key。
在用數組時,這么寫:<div v-for='item in items' :key='item.id'></div>
注意: Vue不能檢查這兩個數組的變化:
- 當你利用索引直接設置一個項時,例如:
vm.items[indexOfItem] = newValue
- 當你修改數組的長度時,例如:
vm.items.length = newLength
替代:
-
Vue.set(vm.items, indexOfItem, newValue)
-
vm.items.splice(newLength)
對象更改檢測注意事項
var vm = new Vue({
data: {
userProfile: {
name: 'Anika'
}
}
})
1.Vue 不能檢測對象屬性的添加或刪除
2.對於已經創建的實例,Vue 不能動態添加根級別的響應式屬性。
但是,可以使用 Vue.set(object, key, value)
方法向嵌套對象添加響應式屬性
Vue.set(vm.userProfile, 'age', 27)
3.Vue為一個對象增加多個新的響應式屬性:
用Object.assign(target, ...source) 為對象target分配新的屬性...source。(點擊看API)
需要這么用: 用兩個對象的屬性生成一個新的對象,然后賦值給原對象。
vm.userProfile = Object.assign({}, vm.userProfile, {
age: 27,
favoriteColor: 'Vue Green'
})
顯示過濾/排序結果
顯示一個數組的過濾或排序副本,而不實際改變或重置原始數據。
在這種情況下,可以創建返回過濾或排序數組的計算屬性。
在計算屬性不適用的情況下 (例如,在嵌套 v-for
循環中) 你可以使用一個 method 方法:
<li v-for="n in even(numbers)">{{ n }}</li> |
也可以取整數:v-for='n in 10'
v-for可以使用<template> tag
<ol id='app'>
<template v-for="item in items">
<li>{{ item.msg }}</li>
</template>
</ol>