[TOC]
Vue的基礎
Vue概述:2014/2 Vue.js正式發(fā)布;2015/10/27 正式發(fā)布1.0.0版本;2016/4/27 發(fā)布2.0預覽版本
- 漸進式JavaScript框架
- 聲明式渲染 => 組件系統(tǒng) => 客戶端路由 => 集中式狀態(tài)管理 => 項目構(gòu)建
- 官網(wǎng):https://cn.vuejs.org/v2/guide/
特性:
- 易用:熟悉HTML检号、CSS、JavaScript知識后,可快速上手Vue
- 靈活:在一個庫和一套完整框架之間自由伸縮
- 高效:20kb運行大小锈颗,超快虛擬DOM
Vue基本使用
<div id="app">{{msg}}<div>
<div>{{1 + 2}}</div>
<div>{{msg + '!!!'}}</div>
<!-- Vue基本使用步驟 -->
<script src="js/vue.js"></script>
<script>
/*
* 1. 提供標簽用于填充數(shù)據(jù)
* 2. 引入vue.js文件
* 3. 使用vue的語法實現(xiàn)功能
* 4. 把vue提供的數(shù)據(jù)填充到標簽中即可
*/
var vm = new Vue({
el: '#app', // 把數(shù)據(jù)填充到哪個位置
data: {
msg: 'Hello Vue'
}
});
</script>
- 實例參數(shù)分析
- el:元素的掛載位置(值可以是CSS選擇器或者DOM元素)
- data:模型數(shù)據(jù)(值是一個對象)
- 插值表達式用法
- 將數(shù)據(jù)填充到HTML標簽中
- 差值表達式支持基本的計算操作
- Vue代碼運行的原理
- 概述編譯過程的概念(Vue語法 => 原生語法)
Vue的模板語法
- 如何理解前端渲染?
- 把數(shù)據(jù)填充到HTML標簽中
- 前端渲染方式
- 原生js拼接字符
- 把數(shù)據(jù)以字符串的方式拼接到HTML標簽中
- 缺點:不同開發(fā)人員的代碼風格差別很大咪惠,隨著業(yè)務的復雜击吱,后期的維護變得逐漸困難起來
- 使用前端模板引擎
- 有自己的一套模板語法規(guī)范
- 優(yōu)點:遵循同樣的規(guī)范寫法代碼,代碼可讀性明顯提高了硝逢,方便后期的維護
- 缺點:沒有專門提供事件機制
- 使用Vue特有的模板語法
- 差值表達式
- 指令
- 事件綁定
- 屬性綁定
- 樣式綁定
- 分支循環(huán)結(jié)構(gòu)
- 原生js拼接字符
指令
- 什么是指令姨拥?
- 指令的本質(zhì)就是自定義屬性
- 指令的格式:以v開始(比如:v-cloak)
-
v-cloak
指令的用法- 差值表達式存在的問題:"閃動"
- 如何解決該問題:使用
v-cloak
指令 - 解決該問題的原理:先隱藏,替換好值之后再顯示最終的值
<!-- v-cloak指令的用法
1. 提供樣式
[v-cloak]{
display: none
}
2. 在插值表達式所在的標簽中添加v-cloak指令
原理:先通過樣式隱藏內(nèi)容渠鸽,然后在內(nèi)存中進行值的替換叫乌,替換好之后再顯示最終的結(jié)果
-->
<style>
[v-cloak]{
display: none
}
</style>
<div id="app" v-cloak>{{msg}}</div>
<script>
var vm = new Vue({
el: '#app', // 把數(shù)據(jù)填充到哪個位置
data: {
msg: 'Hello Vue'
}
});
</script>
- 數(shù)據(jù)綁定指令
-
v-text
填充純文本- 相比差值表達式更加簡潔
-
v-html
填充HTML片段- 存在安全問題,容易導致XSS攻擊
- 本網(wǎng)站內(nèi)部數(shù)據(jù)可以使用,來自第三方的數(shù)據(jù)不可以用
-
v-pre
填充原始信息- 顯示原始信息徽缚,跳過編譯過程(分析編譯過程)
-
<div id="app">
<div v-text="msg"></div>
<div v-html="msg1"></div>
<div v-pre>{{msg}}</div>
</div>
<script>
var vm = new Vue({
el: '#app',
data: {
msg: 'Hello Vue',
msg1: '<h1>HTML</h1>'
}
});
</script>
Vue使用
-
數(shù)據(jù)響應式
- 如何理解響應式憨奸?
- html5中的響應式(屏幕尺寸的變化導致樣式的變化)
- 數(shù)據(jù)的響應式(數(shù)據(jù)的變化導致頁面內(nèi)容的變化)
- 什么是數(shù)據(jù)數(shù)據(jù)綁定
- 數(shù)據(jù)綁定:將數(shù)據(jù)填充到標簽中
-
v-once
只編譯一次- 顯示內(nèi)容之后不再具有響應式功能
// v-once使用場景:如果顯示的信息后續(xù)不需要再修改,就可以使用v-once凿试,這樣可以提高性能
- 如何理解響應式憨奸?
-
雙向數(shù)據(jù)綁定
v-model
- 什么是雙向數(shù)據(jù)綁定
<input type="text" v-model="uname"/>
- MVVM設計思想(M(module) V(view) VM(View-Module))
- 什么是雙向數(shù)據(jù)綁定
-
事件綁定
- v-on指令用法
<input type="button" v-on:click="num++"/>
- v-on簡寫形式
<input type="button" @click="num++"/>
- v-on指令用法
-
事件函數(shù)的調(diào)用方式
- 直接綁定函數(shù)名稱
<button v-on:click='say'>Hello</button>
- 自帶事件對象
- 調(diào)用函數(shù)
<button v-on:click='say()'>Hello</button>
- 事件函數(shù)參數(shù)傳遞:普通參數(shù)和事件對象
<button v-on:click='say("hi", $event)'>Hello</button>
- 直接綁定函數(shù)名稱
-
事件修飾符
-
.stop
阻止冒泡<a v-on:click.stop="handle">跳轉(zhuǎn)</a>
-
.prevent
阻止默認行為<a v-on:click.prevent="handle">跳轉(zhuǎn)</a>
-
.self
只有當前元素自身觸發(fā)時才會觸發(fā)這個函數(shù)
-
-
按鍵修飾符
-
.enter
回車鍵<input v-on:keyup.enter="submit">
-
.delete
刪除鍵<input v-on:keyup.delete="handle">
-
-
自定義按鍵修飾符
- 全局
config.keyCodes
對象Vue.config.keyCodes.f1 = 112
- 規(guī)則:自定義修飾符的名字是自己定義的排宰,但是對應的值必須是案件對應的
event.keyCode
值
- 全局
-
Vue如何動態(tài)處理屬性似芝?
-
v-bind
指令用法<a v-bind:href='url'>跳轉(zhuǎn)</a>
- 縮寫形式
<a :href='url'>跳轉(zhuǎn)</a>
-
-
v-model
的底層原理分析<input v-bind="msg" v-on:input="msg=$event.target.value">
<div id="app"> <div>{{name}}</div> <input type="text" v-bind:value="name" v-on:input='handle'> <input type="text" v-bind:value="name" v-on:input='name=$event.target.value'> <input type="text" v-model="name"> </div> <script> let vm = new Vue({ el:'#app', data:{ name:"myVue" }, methods: { handle: function(event) { this.name = event.target.value; } } }); </script>
-
樣式綁定
- class樣式處理
- 對象語法
<div v-bind:class="{ active: isActive }"></div>
- 數(shù)組語法
<div v-bind:class="[activeClass, errorClass]"></div>
- 樣式相關(guān)語法細節(jié):
- 對象綁定和數(shù)組綁定可以結(jié)合使用
- class綁定的值可以簡化操作
- 默認的class如何處理
- 對象語法
- style樣式處理
- 對象語法
<div v-bind:style="{ color: activeColor, fontSize: fontSize }"></div>
- 數(shù)組語法
<div v-bind:style="[baseStyles, overridingStyles]"></div>
- 對象語法
- class樣式處理
```html
<style>
.active {
border: 1px solid red;
width: 100px;
height: 100px;
}
.error{
background-color: orange;
}
</style>
<div id="app">
<button v-on:click="handle">切換</button>
<div v-bind:class="{active: isActive,error: isError}">{{name}}</div>
</div>
<script>
let vm = new Vue({
el: '#app',
data: {
name: "myVue",
isActive: true,
isError:true
},
methods: {
handle: function () {
this.isActive=!this.isActive;
this.isError=!this.isError;
}
}
});
</script>
```
```html
<style>
.active {
border: 1px solid red;
width: 100px;
height: 100px;
}
.error{
background-color: orange;
}
</style>
<div id="app">
<button v-on:click="handle">移除</button>
<div v-bind:class="[activeClass, errorClass]">{{name}}<div>
</div>
<script>
let vm = new Vue({
el: '#app',
data: {
name: "myVue",
activeClass:'active',
errorClass:'error'
},
methods: {
handle: function () {
this.activeClass = '';
this.errorClass = '';
}
}
});
</script>
```
```html
<div id="app">
<button v-on:click='handle'>切換</button>
<div v-bind:style='{border: borderStyle, width: widthStyle, height: heightStyle}'>{{name}}</div>
<div v-bind:style='objStyle'></div>
<div v-bind:style='[objStyle, overrideStyle]'></div>
</div>
<script>
let vm = new Vue({
el: '#app',
data: {
name: "myVue",
borderStyle: '1px solid blue',
widthStyle: '100px',
heightStyle: '150px',
objStyle: {
border:'1px solid green',
width: '150px',
height: '100px'
},
overrideStyle: {
border: '5px solid orange',
backgroundColor: 'blue'
}
},
methods:{
handle: function() {
this.heightStyle = '100px';
this.objStyle.width = '100px';
}
}
});
</script>
```
-
分支循環(huán)結(jié)構(gòu)
- v-if:控制元素是否渲染到頁面
- v-else
- v-else-if
- v-show:控制元素是否顯示(已經(jīng)渲染到頁面)
<div id="app"> <div v-if='score>=90'>優(yōu)</div> <div v-else-if='score<90&&score>=80'>良</div> <div v-else-if='score<80&&score>=60'>可</div> <div v-else>差</div> <!-- v-show的原理: 控制元素樣式是否顯示 --> <div v-show='flag'>測試v-show</div> <button v-on:click='handle'>點擊</button> </div> <script> let vm = new Vue({ el:'#app', data:{ name:"myVue", score:99, flag: true }, methods:{ handle: function() { this.flag = !this.flag; } } }); </script>
-
循環(huán)結(jié)構(gòu)
- v-for遍歷數(shù)組
<li v-for='item in list'>{{item}}</li>
<li v-for='(item,index) in list'>{{item + '---' + index}}</li>
- key的作用:幫助Vue區(qū)分不同的元素,從而提高性能
<li :key='item.id' v-for='(item,index) in list'>{{item}} + '---' {{index}}</li>
- v-for遍歷對象
<li v-for='(value, key, index) in object'></li>
- v-if和v-for結(jié)合使用
<li v-if='value==12' v-for='(value, key, index) in object'></li>
- v-for遍歷數(shù)組
Vue常用特性
-
表單操作
- input 單行文本
- textarea 多行文本
- select 下拉多選
- radio 單選框
- checkbox 多選框
- 表單域修飾符:
- number:轉(zhuǎn)化為數(shù)值
<input v-model.number="age" type="number">
- trim:去掉開始和結(jié)尾的空格
- lazy:將input時間切換為change事件
-
自定義指令
為何需要自定義指令板甘? 內(nèi)置指令不滿足需求
-
自定義指令的語法規(guī)則(獲取元素焦點)
// 自定義指令 Vue.directive('focus' ,{ inserted: function (el) { // 獲取元素的焦點 el.focus(); } })
-
自定義指令的用法
<input type="text" v-focus>
鉤子函數(shù)
-
鉤子函數(shù)參數(shù):
-
el
:指令所綁定的元素 -
binding
:一個對象党瓮,包含以下屬性:-
name
:指令名,不包含v-
前綴 -
value
:指令綁定的值 - ...
-
-
vnode
:Vue生成的虛擬節(jié)點 -
oldVnode
:上一個虛擬節(jié)點盐类,僅在update
和componentUpdated
鉤子中可用
-
<input type="text" v-color='{color:"orange"}'> <script> // 帶參數(shù)的自定義指令 Vue.directive('color'. { inserted: function(el, binding) { el.style.backgroundColor = binding.value.color; } }) </script>
-
局部指令:如果想要注冊局部指令寞奸,組件中也接受一個
directive
的選項:directive: { focus: { // 指令的定義 inserted: function (el) { el.focus() } } }
-
計算屬性
為何需要計算屬性?表達式的計算邏輯可能會比較復雜在跳,使用計算屬性可以是模板內(nèi)容更加簡潔
-
計算屬性用法:
computed: { reversedMessage: function () { return this.msg.split('').reverse().join() } }
-
計算屬性和方法的區(qū)別:
- 計算屬性是基于它們的依賴進行緩存的
- 方法不存在緩存
-
偵聽器
偵聽器應用場景:數(shù)據(jù)變化時執(zhí)行異步或開銷比較大的操作
-
偵聽器的用法
watch: { firstName: function (val) { // val變化之后的值 this.fullName = val + this.lastName; }, lastName: function (val) { this.fullName = this.firstName + val; } }
-
過濾器
作用:格式化數(shù)據(jù)枪萄,比如將字符串格式化為首字母大寫,將日期格式轉(zhuǎn)化為指定的格式等
-
自定義過濾器
Vue.filter('過濾器名稱', function(value) { // 過濾器業(yè)務邏輯 })
-
過濾器的使用:
<div>{{msg | upper}}</div> <div>{{msg | upper | lower}}</div> <div v-bind:id="id | formatId"></div>
-
局部過濾器
filters: { capitalize: function() {} }
<div id="app"> <h1>{{name}}</h1> <input type="text" v-model="msg"> <div>{{msg | upper}}</div> <div>{{msg | upper | lower}}</div> <div :abc="msg | upper">測試數(shù)據(jù)</div> </div> <script> // Vue.filter('upper', function (val) { // return val.charAt(0).toUpperCase() + val.slice(1); // }); Vue.filter('lower', function (val) { return val.charAt(0).toLowerCase() + val.slice(1); }) let vm = new Vue({ el: '#app', data: { name: "myVue", msg: '' }, filters:{ upper: function(val) { return val.charAt(0).toUpperCase() + val.slice(1); } }, methods: { } }); </script>
-
帶參數(shù)的過濾器
<div>{{data | format('yyy-MMM-dd')}}</div> <script> Vue.filter('format', function(value, arg1) { // value就是過濾器傳遞過來的參數(shù) })
-
生命周期
- 掛載(初始化相關(guān)屬性)
-
beforeCreate
在實例初始化之后數(shù)據(jù)觀測和事件按配置之前被調(diào)用 -
created
在實例創(chuàng)建完成后被立即調(diào)用 -
beforeMount
在掛載開始之前被調(diào)用 -
mounted
el被新創(chuàng)建的vm.$el
替換猫妙,并掛載到實例上去之后調(diào)用該鉤子
-
- 更新(元素或組件的變更操作)
-
beforeUpdate
數(shù)據(jù)過呢更新時被調(diào)用瓷翻,發(fā)生在虛擬DOM打補丁之前 -
updated
由于數(shù)據(jù)更改導致的虛擬DOM重新渲染和打補丁,在這之后會調(diào)用該鉤子
-
- 銷毀(銷毀相關(guān)屬性)
-
beforeDestroy
實例銷毀之前調(diào)用 -
destroyed
實例銷毀后調(diào)用
-
- 掛載(初始化相關(guān)屬性)