準備工作
- 編輯器和插件
編輯器:vscode
插件:live server,自動搭建一個簡易的本地服務器,可以從服務器訪問頁面
或者可以在VSCode搭建Vue環境可以參考以前的文章鏈接
- vue是什麼?
vue的官網:https://cn.vuejs.org/
vue是一個漸進式的javascript框架
漸進式:vue可以和其他傳統(比如jquery)前端技術融合,這意味着你可以向已有工程中逐步植入vue,而無須全部重寫
javascript框架:基於JS語言書寫而成的框架,框架是一種升級版的庫,它具有約束力,即必須按照框架所規定的方式組織代碼結構
基本原理
創建vue工程
創建vue工程有三種方式:
- 和傳統工程一樣,創建頁面,引入
vue.js
即可 - 使用構建工具(
webpack
)搭建工程 - 使用腳手架(
vue-cli
)搭建工程
創建vue實例
先在頁面中放置一個div
<!-- 這個div將會被vue控制 -->
<div id="app"></div>
vue.js
提供了一個構造函數Vue
,通過下面的代碼即可創建一個vue實例:
new Vue({ //配置對象
el: "#app",
data: {
title: "商品和庫存管理"
},
template: `
<h1>{{title}}</h1>
`
})
配置對象中出現了三個屬性:
- el: 表示vue實例將控制頁面中的哪個元素(要掛載的元素)。該元素將被vue控制,元素之外的其他區域不受影響。
- data:一個對象,可以配置任何與顯示相關的數據。這是非常重要的一個配置,它爲被vue控制的區域提供需要顯示的信息,至於如何顯示,則由
template
的內容決定 - template:渲染模板。它描述了要顯示到頁面上的內容,該內容經過一系列流程後,最終將替換掉
el
元素。- 值得注意的是,vue要求模板必須有唯一的根節點。
- 如果沒有配置
template
,vue將使用el
元素的outerHTML
作爲模板
數據響應式
vue的數據是響應式的。
所謂響應式,是指當數據發生變化的時候,vue會重新渲染
vue2實現響應式的方式,是深度遍歷配置中的data
,將遇到的每一個屬性用Object.defineProperty
的方式重新定義,於是,每當讀取屬性或給屬性賦值時,vue可以收到通知,從而渲染界面
不僅如此,爲了對數組進行響應,vue還重寫了大部分改變數組的方法,例如push、slice、splice、pop、shift、unshift等
,於是,對數組的操作也具有了響應式。
但是,如果直接通過索引改動數組的某個元素是不具有響應式的,但可通過
實例.$set(target, prop, value)
實現設置
爲了方便操作數據,vue還會將配置中的一些信息提取到vue實例中
我們把添加數據響應式功能,以及提取到vue實例的過程稱之爲注入
@startuml
start
:深度遍歷數據;
:實現數據響應式;
:將信息提取到vue實例;
stop
@enduml
注入流程
由於注入流程發生在最開始的時候,如果之後動態的增加數據,由於注入流程已經結束,增加的數據無法獲得響應式
模板的編譯
如果每次重新渲染都完全替換頁面中的元素,將導致效率極其低下
對真實DOM的操作非常昂貴
vue爲了提高渲染效率,使用虛擬DOM的方式來映射真實的DOM。
虛擬DOM實際上就是一個普通的JS對象。當需要重新渲染的時候,vue首先檢查這些虛擬DOM哪些是需要更改的,從而根據實際情況,用最小的代價更新真實DOM。
模板字符串變成虛擬DOM的過程,稱之爲模板的編譯
模板的編譯是一個複雜的過程,要完全理解它的原理,需要熟悉源碼和一些算法
在模板中,我們可以使用所有vue實例中的屬性和方法
模板和配置
模板
插值
在所有文本節點的位置,都可以使用Mustache
語法進行插值
{{ 任何JS表達式 }}
指令
在所有元素節點的屬性位置,都可以使用各種指令來完成不同的操作
指令的完整語法是:指令名:指令描述.指令修飾符
可以把指令想象成某個函數,指令描述和指令修飾符是函數的一些參數,用於告知函數一些具體的信息
如果要查看所有的指令,參閱官網API文檔
- v-on
通過該指令,可以爲節點註冊事件
<!-- 點擊後執行某段JS代碼 -->
<button v-on:click="JS代碼">按鈕</button>
<!-- 點擊後執行某段JS代碼,並阻止默認行爲 -->
<a href="" v-on:click.prevent="n++">鏈接</a>
由於使用頻繁,v-on:
可以速寫成@
在v-on
指令內部,可以使用$event
獲取獲取事件參數
- v-bind
通過該指令,可以爲元素綁定屬性
<!-- img元素的圖片地址來自於數據:url -->
<img v-bind:src="url">
<!-- div元素的類樣式來自於一個判斷 -->
<div v-bind:class="phone?'container-phone':'container'"></div>
由於使用頻繁,v-bind:
可以速寫成:
- v-if
這裏涉及三個指令v-if、v-else-if、v-else
,類似於js的if、else if、else
<p v-if="score<60">不及格</p>
<p v-else-if="score<80">及格</p>
<p v-else>優秀</p>
v-if決定該元素是否參與渲染
- v-show
該指令接收一個boolean
表達式,用於決定該元素是否隱藏
<p v-show="score<60">不及格</p>
<p v-show="score<80 && score>=60">及格</p>
<p v-show="score>=90">及格</p>
- v-html
通過該指令可以設置元素的innerHTML
<p v-html="`<a href=''>鏈接</a>`">內部的內容不再有效</p>
- v-for
通過該指令,可以循環渲染元素
<!-- nums: ["a","b","c"] -->
<ul>
<!-- -->
<li v-for="(n i) in nums" :key="i">{{i}}, {{n}}</li>
</ul>
渲染後
<ul>
<li>0, a</li>
<li>1, b</li>
<li>2, c</li>
</ul>
key值的設置是爲了提高渲染效率,通常在循環渲染一個元素時設置,設置的值必須唯一,通常設置爲數據的id
在重新渲染時,vue底層需要對比新舊兩棵虛擬DOM樹,key值的存在可以讓vue更加精準的比較,從而減少對真實DOM的操作
- v-model
該指令用於對數據進行雙向綁定
<!-- 文本框顯示txt的內容 -->
<!-- 當文本框觸發input事件時,會更改txt的內容 -->
<input type="text" v-model="txt">
<!-- 上面的代碼等同於 -->
<input type="text" :value="txt" @input="txt=$event.target.value">
配置
- el
要掛載的元素 - data
要渲染的數據 - template
要編譯的模板 - methods
methods
中可以配置一些函數,這些函數會被提取到vue實例,因此:
- 函數中的this指向的是vue實例
- 模板中可以調用函數
- 可以將函數設置到事件
new Vue({
//...
data:{
n: 0
},
methods:{
add(number){
this.n += number;
},
reduce(number){
this.n -= number;
}
}
})
在模板中可以使用這些方法
<button @click="reduce(2)"> 減2 </button>
{{n}}
<button @click="add(3)"> 加3 </button>
- computed
computed中可以配置一些方法,這些方法稱之爲計算屬性
var app = new Vue({
el: "#app",
data: {
products:[
{name: "小米手機",stock:10},
{name: "華爲手機",stock:20},
{name: "iphone",stock:5},
],
isDark: false,
newProduct:{ //新產品
name:"",
stock: 0
}
},
computed: {
totalStock(){ //總庫存
var sum = 0;
for(var i = 0; i < this.products.length; i++){
var prod = this.products[i];
sum += prod.stock;
}
return sum;
}
},
計算屬性也會提取到vue實例,因此:
- 方法中this指向vue實例
- 模板中可以直接使用計算屬性,使用時當作普通屬性使用即可,不能當作方法調用
<p>總計{{totalStock}}</p>
計算屬性和方法的最大區別,在於計算屬性會進行緩存,只要依賴不變,計算屬性的方法無須重新運行