從零開始的vue學習筆記(二)
- 2019 年 10 月 10 日
- 筆記
數據與方法
- 當一個 Vue 實例被創建時,它將 data 對象中的所有的屬性加入到 Vue 的響應式系統中。data的數據和視圖同步更新。
- 實例創建後添加一個新的屬性,對這個屬性的的改動將不會觸發任何視圖的更新。
- 如果需要一個屬性,但是一開始它為空或不存在,僅需要設置一些初始值。
- Object.freeze()方法可以阻止修改現有的屬性
- 除了數據屬性,Vue 實例還包含實例屬性與方法,前綴為
$
,例如:vm.$data,vm.$el,vm.$watch()(這裡假設vm是某個實例名),詳情可以參考API
實例生命周期鉤子
Vue實例有自己的生命周期,提供了一些鉤子函數給我們寫自己的邏輯程式碼:
- beforeCreate
- created
- beforeMount
- mounted
- beforeUpdate
- updated
ps:不要在選項屬性或回調上使用箭頭函數,即這些鉤子函數不要用箭頭函數的寫法,因為他們沒有this
生命周期圖
模板語法
-
文本
數據綁定最常見的形式就是使用「Mustache」
語法 (雙大括弧) 的文本插值<span>Message: {{ msg }}</span>
v-once 指令,你也能執行一次性地插值,當數據改變時,插值處的內容不會更新
<span v-once>這個將不會改變: {{ msg }}</span>
-
原始 HTML
v-html 指令輸出真正的html,而不是字元串<p>Using mustaches: {{ rawHtml }}</p> 輸出字元串 <p>Using v-html directive: <span v-html="rawHtml"></span></p> 輸出rawHtml變數代表的HTML
-
使用 JavaScript 表達式
所有的數據綁定,Vue.js 都提供了完全的 JavaScript 表達式支援{{ number + 1 }} {{ ok ? 'YES' : 'NO' }} {{ message.split('').reverse().join('') }} <div v-bind:id="'list-' + id"></div>
-
指令
常見有v-if,v-on,v-bind,v-for。
參數:<a v-bind:href="url">...</a>
在這裡 href 是參數,告知 v-bind 指令將該元素的 href 特性與表達式 url 的值綁定
動態參數:<a v-bind:[attributeName]="url"> ... </a>
這裡的 attributeName 會被作為一個 JavaScript 表達式進行動態求值,求得的值將會作為最終的參數來使用
修飾符:<form v-on:submit.prevent="onSubmit">...</form>
修飾符 (modifier) 是以半形句號 . 指明的特殊後綴,用於指出一個指令應該以特殊方式綁定,例子的
.prevent
就是修飾符
縮寫:<!-- 完整語法 --> <a v-bind:href="url">...</a> <!-- 縮寫 --> <a :href="url">...</a> <!-- 完整語法 --> <a v-on:click="doSomething">...</a> <!-- 縮寫 --> <a @click="doSomething">...</a>
計算屬性和偵聽器
模板一般不要加入過多的邏輯,只是用來渲染會職責分明一些,把邏輯處理防盜計算屬性,會更加合理;
<p>Computed reversed message: "{{ reversedMessage }}"</p>
var vm = new Vue({ el: '#example', data: { message: 'Hello' }, computed: { // 計算屬性的 getter reversedMessage: function () { // `this` 指向 vm 實例 return this.message.split('').reverse().join('') } } })
這裡的reversedMessage
就是計算屬性,可以逆序一個字元串。
定義一個方法,能夠達到同樣的效果:
<p>Reversed message: "{{ reversedMessage() }}"</p>
<p> // 在組件中 methods: { reversedMessage: function () { return this.message.split('').reverse().join('') } }
兩者區別:計算屬性是基於它們的響應式依賴進行快取的,方法總會再次執行函數;在不同場景下選擇不同的方式吧~
tips:使用計算屬性,而不是偵聽屬性(watch里定義的方法);計算屬性默認只有 getter ,不過在需要時你也可以提供一個 setter;自定義的偵聽器watch在數據變化時執行非同步或開銷較大的操作時是最有用的
Class 與 Style 綁定
v-bind 用於 class 和 style,表達式結果的類型除了字元串
之外,還可以是對象
或數組
先介紹Class綁定
-
綁定對象
<div class="static" v-bind:class="{ active: isActive, 'text-danger': hasError }"> </div> data: { isActive: true, hasError: false }
當 isActive 或者 hasError 變化時,class 列表將相應地更新,也可以讓綁定對象不內聯定義在模板里,結果也是一致的:
<div v-bind:class="classObject"></div> data: { classObject: { active: true, 'text-danger': false } }
綁定
計算屬性
也可以更靈活的展現(不舉例子了) -
綁定數組
<div v-bind:class="[activeClass, errorClass]"></div> data: { activeClass: 'active', errorClass: 'text-danger' }
-
綁定組件(語法和前面完全類似)
Style綁定
v-bind:style 的對象語法
-
綁定對象
<div v-bind:style="{ color: activeColor, fontSize: fontSize + 'px' }"></div> data: { activeColor: 'red', fontSize: 30 }
或者直接寫
<div v-bind:style="styleObject"></div> data: { styleObject: { color: 'red', fontSize: '13px' } }
-
綁定數組
<div v-bind:style="[baseStyles, overridingStyles]"></div>
條件渲染
v-if、v-else-if、v-else可以配合使用:
<div v-if="type == 'A'"> A </div> <div v-else-if="type == 'B'"> B </div> <div v-else="type == 'C'"> C </div> data : { type : "B" }
在<template>
元素上使用 v-if 條件渲染分組,顯示多個元素
<template v-if="ok"> <h1>Title</h1> <p>Paragraph 1</p> <p>Paragraph 2</p> </template>
用key管理重複元素
<template v-if="loginType === 'username'"> <label>Username</label> <input placeholder="Enter your username" key="username-input"> </template> <template v-else> <label>Email</label> <input placeholder="Enter your email address" key="email-input"> </template>
使用key標示元素後,Vue不會採用偷懶的復用,而會重新渲染元素
v-show:只有顯示和不顯示兩種
<h1 v-show="ok">Hello!</h1>
v-if vs v-show:需要非常頻繁地切換,則使用 v-show 較好;如果在運行時條件很少改變,則使用 v-if 較好
列表渲染
v-for用於列表渲染
-
迭代數組
<ul id="example-2"> <li v-for="(item, index) in items"> {{ parentMessage }} - {{ index }} - {{ item.message }} </li> </ul> var example2 = new Vue({ el: '#example-2', data: { parentMessage: 'Parent', items: [ { message: 'Foo' }, { message: 'Bar' } ] } })
ps:index從0開始,
in
可以替換為of
-
迭代對象
<div v-for="(value, name, index) in object"> {{ index }}. {{ name }}: {{ value }} </div>
new Vue({ el: '#v-for-object', data: { object: { title: 'How to do lists in Vue', author: 'Jane Doe', publishedAt: '2016-04-10' } } })
-
使用唯一key配合v-for保證渲染正確(刪除、排序、過濾等場景用得到)
<div v-for="item in items" v-bind:key="item.id"> <!-- 內容 --> </div>
-
數組變異方法 (mutation method)
push()、pop()、shift()、unshift()、splice()、sort()、reverse(),例子:example1.items.push({ message: 'Baz' })
這些方法會直接改變數組本身
-
非變異 (non-mutating method) 方法
filter()、concat()、slice()example1.items = example1.items.filter(function (item) { return item.message.match(/Foo/) })
這些方法不會改變傳入的數組本身,但是方法的
返回值
是一個新數組
,可以把這個數組賦值給原來的數組達到同樣的效果 -
注意事項
數組的一些錯誤寫法:var vm = new Vue({ data: { items: ['a', 'b', 'c'] } }) vm.items[1] = 'x' // 不是響應性的 vm.items.length = 2 // 不是響應性的
正確寫法:
//第一個問題 // Vue.set Vue.set(vm.items, indexOfItem, newValue) // Array.prototype.splice vm.items.splice(indexOfItem, 1, newValue) //實例寫法 vm.$set(vm.items, indexOfItem, newValue) //第二個問題 vm.items.splice(newLength)
對象的一些錯誤寫法:
var vm = new Vue({ data: { a: 1 } }) // `vm.a` 現在是響應式的 vm.b = 2 // `vm.b` 不是響應式的
對於已經創建的實例,Vue 不允許動態添加
根級別
的響應式屬性,但是,可以使用 Vue.set(object, propertyName, value) 方法向嵌套對象添加響應式屬性:var vm = new Vue({ data: { userProfile: { name: 'Anika' } } }) Vue.set(vm.userProfile, 'age', 27) //或者 vm.$set(vm.userProfile, 'age', 27)
表單輸入綁定
v-model指令在表單 <input>
、<textarea>
及 <select>
元素上創建雙向數據綁定,本質上是語法糖。
-
文本
<input v-model="message" placeholder="edit me"> <p>Message is: {{ message }}</p>
-
多行文本
<span>Multiline message is:</span> <p style="white-space: pre-line;">{{ message }}</p> <br> <textarea v-model="message" placeholder="add multiple lines"></textarea>
tips: (
<textarea>{{text}}</textarea>
) 並不會生效,應用 v-model 來代替。 -
複選框
多個複選框,綁定到同一個數組,例子:<div id='example-3'> <input type="checkbox" id="jack" value="Jack" v-model="checkedNames"> <label for="jack">Jack</label> <input type="checkbox" id="john" value="John" v-model="checkedNames"> <label for="john">John</label> <input type="checkbox" id="mike" value="Mike" v-model="checkedNames"> <label for="mike">Mike</label> <br> <span>Checked names: {{ checkedNames }}</span> </div>
new Vue({ el: '#example-3', data: { checkedNames: ['Jack'] } })
-
單選按鈕
<div id="example-4"> <input type="radio" id="one" value="One" v-model="picked"> <label for="one">One</label> <br> <input type="radio" id="two" value="Two" v-model="picked"> <label for="two">Two</label> <br> <span>Picked: {{ picked }}</span> </div>
new Vue({ el: '#example-4', data: { picked: 'Two' } })
-
選擇框
單選:<div id="example-5"> <select v-model="selected"> <option disabled value="">請選擇</option> <option>A</option> <option>B</option> <option>C</option> </select> <span>Selected: {{ selected }}</span> </div>
new Vue({ el: '...', data: { selected: 'A' } })
多選時 (綁定到一個數組):
<div id="example-6"> <select v-model="selected" multiple style="width: 50px;"> <option>A</option> <option>B</option> <option>C</option> </select> <br> <span>Selected: {{ selected }}</span> </div>
new Vue({ el: '#example-6', data: { selected: ['A','B'] } })
v-for顯示下拉框例子:
<select v-model="selected"> <option v-for="option in options" v-bind:value="option.value"> {{ option.text }} </option> </select> <span>Selected: {{ selected }}</span>
new Vue({ el: '...', data: { selected: 'A', options: [ { text: 'One', value: 'A' }, { text: 'Two', value: 'B' }, { text: 'Three', value: 'C' } ] } })
- 值綁定
單選按鈕,複選框及選擇框的選項,v-model 綁定的值通常是靜態字元串,有時我們可能想把值綁定到 Vue 實例的一個動態屬性上,這時可以用 v-bind 實現,並且這個屬性的值可以不是字元串(不舉例子了) - 修飾符
- .lazy
在默認情況下,v-model 在每次 input 事件觸發後將輸入框的值與數據進行同步,你可以添加 lazy 修飾符,從而轉變為使用 change 事件進行同步
<!-- 在「change」時而非「input」時更新 --> <input v-model.lazy="msg" >
- .number
如果想自動將用戶的輸入值轉為數值類型,可以給 v-model 添加 number 修飾符
<input v-model.number="age" type="number">
- .trim
如果要自動過濾用戶輸入的首尾空白字元,可以給 v-model 添加 trim 修飾符:
<input v-model.trim="msg">
- .lazy