VUE框架:基礎知識及核心原理

VUE框架第一部分:基礎知識及核心原理

VUE基礎概念

cn.vuejs.orgjavascript

Vue (讀音 /vjuː/,相似於 view) 是一套用於構建用戶界面的漸進式框架
特色:易用、靈活、高效
全家桶:vue + components(vue element / iview...) + vue-router + vuex + vue-cli
css

類庫 vs 插件 vs 組件 vs 框架

  • 類庫:jquery、zepto、underscore...
  • 插件:dialog、banner、drag、tab、iscroll...
  • 組件:bootstrap、swiper...
  • 框架:backbone、angular、vue、react、uni-app、react native、flutter...

聲明式和命令式

  • 命令式編程:命令「機器」如何去作事情(how),這樣無論你想要的是什麼(what),它都會按照你的命令實現,例如for循環
  • 聲明式編程:告訴「機器」你想要的是什麼(what),讓機器想出如何去作(how),例如數組內置方法forEach等

4.png

MVC  & MVVM

  • 傳統操做DOM模式
  • MVC:model view controller
  • MVVM:model view viewModel

2.jpg
3.jpg

<div id="app">
	{{msg}}
</div>
<!-- IMPORT JS -->
<script src="node_modules/vue/dist/vue.min.js"></script>
<script>
    new Vue({
    	el: '#app',
    	data: {
    		msg: 'hello world'
    	}
	});
	setTimeout(() => {
    	vm.msg = '你好世界';
    }, 1000);
</script>
複製代碼
<div id="app">
    人民幣:¥<input type="text" v-model='price'>元
	<br>
    美圓:${{price/8}}
</div>
<!-- IMPORT JS -->
<script src="node_modules/vue/dist/vue.min.js"></script>
<script>
    let vm = new Vue({
        el: '#app',
        data: {
            price: 0
        }
    });
</script>
複製代碼

VUE的基礎語法

new Vue(options)

  • 返回值vm(viewModel)
  • el:不能掛載到html或者body上  =>querySelector
  • data
    • 數據值對於對象來講要先聲明,不然新增屬性無效(能夠基於vm.$set處理)
    • vm.arr[0]=xxx 改變數組中的某一項視圖不會渲染,須要基於內置的方法,例如:push...
    • 對象或者數組能夠總體替換值實現數據變視圖也變
  • ...

mustache([ˈmʌstæʃ]) 小鬍子語法

  • value
  • JS表達式

經常使用的指令(directive)

  • v-model
  • v-html / v-text:取消小鬍子語法刷新中的閃爍問題
  • v-bind(縮寫 :)
  • v-once
  • v-if 和 v-show
  • v-for
    • for in循環 & for of循環
      • 遍歷數據類型的範圍
      • 原型上方法遍歷(或者數組新增的xxx:xxx屬性遍歷)
      • ......
    • Symbol.iteratoer:Array、Set、Map、String、Arguments、NodeList...
  • v-on 事件綁定
    • v-on:xxx
    • methods :和data相似,都會把方法掛載到vm實例上(this都是當前實例)
    • @xxx
    • @xxx="func"  &  @xxx="func($event,...)"

directive自定義指令

  • Vue.directive([指令名,省略v-], function(el,bindings,vnode){}
    • el當前元素
    • bindings包含不少信息
      • name:指令名,不包括 v- 前綴
      • value:指令的綁定值
      • oldValue:指令綁定的前一個值,僅在 update 和 componentUpdated 鉤子中可用
      • expression:字符串形式的指令表達式
      • arg:傳給指令的參數,可選。例如 v-my-directive:foo 中,參數爲 "foo"
      • modifiers:包含修飾符的對象。例如:my-directive.foo.bar 中,修飾符對象 { foo: true, bar: true }
    • vnode虛擬DOM
      • ctx = vnode.context  獲取當前元素所在的上下文
      • ctx[bindings.expression]=xxx 獲取上下文中的表達式變量,而且把指定的值賦值給它
  • 鉤子函數
    • bind:當用戶綁定指令時生效(只調一次)
    • update:所在組件的 VNode 更新時調用,可是可能發生在其子 VNode 更新以前(一個函數的方式就是把bind和update合在一塊兒的寫法)
    • componentUpdated:指令所在組件的 VNode 及其子 VNode 所有更新後調用
    • unbind:只調用一次,指令與元素解綁時調用
    • inserted:被綁定元素插入父節點時調用 (僅保證父節點存在,但不必定已被插入文檔中)
  • 小練習:建立一個自定義指令控制文本框的校驗

事件修飾符

  • 常規:.stop / .prevent / .once ...
  • 按鍵:.enter 或者 .13 / .up / .down / .left / .right ...
  • 組合修飾符
  • ...

表單元素的處理

  • 普通文本框 或者 文本域
  • 單選框
  • 複選框
  • 下拉框
  • 小案例:全選和非全選

計算屬性、過濾器、監聽器

  • methods 普通方法
  • filters 過濾器
    • 只能應用到鬍子語法和v-bind中
    • 小練習:輸入內容的單詞首字母大寫
  • computed
    • getter & setter
    • 相對於普通方法來說,計算屬性是基於它們的響應式依賴進行緩存的
    • 依賴data中的數據變量
    • 小練習:輸入內容的單詞首字母大寫
    • 小練習:全選和非全選
  • watch
    • 當須要在數據變化時執行異步或開銷較大的操做時應用監聽器
    • 小練習:全選和非全選
    • 小練習:數據異步綁定的處理
data(){
&emsp;&emsp;return {
&emsp;&emsp;&emsp;&emsp;checked:false, //是否全選
&emsp;&emsp;&emsp;&emsp;checkModel:[]
&emsp;&emsp;}
},
watch:{
&emsp;&emsp;checkModel(){
&emsp;&emsp;&emsp;&emsp;if(this.checkModel.length==this.list.length){
&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;this.checked=true;
&emsp;&emsp;&emsp;&emsp;}else{
&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;this.checked=false;
&emsp;&emsp;&emsp;&emsp;}
&emsp;&emsp;}
}
...
複製代碼

class和style綁定

  • class的處理(對象語法、數組語法)
  • 內聯樣式的處理
  • ...

生命週期函數(鉤子函數)

  • beforeCreate
  • created
  • beforeMount
  • mounted
  • beforeUpdate
  • updated
  • beforeDestory
  • destory
  • ...

經常使用的屬性方法

  • $set : 設置響應式數據
  • $el : 掛載的元素
  • $destroy : 銷燬vue的實例;同時調用beforeDestroy destroyed
  • $mount  : 掛載真實DOM的方法
  • $data  : 響應式的對象
  • $options: 是Vue的構造函數的參數
  • $refs : 能夠用來獲取指定的元素對象 (非受控組件)
  • $on : 訂閱
  • $emit : 發佈
  • $watch:監控
  • ...

案例:選項卡

案例:購物車計算器

案例:商城類別篩選


雙向數據綁定的實現原理

  • Object.defineProperty
  • 實現的底層原理
//observer:觀察者
function observer(obj) {
	if (obj && typeof obj === 'object') {
		for (let key in obj) {
			if (!obj.hasOwnProperty(key)) break;
			defineReactive(obj, key, obj[key]);
		}
	}
}

function defineReactive(obj, key, value) {
	observer(value);
	Object.defineProperty(obj, key, {
		get() {
			return value;
		},
		set(newValue) {
			observer(newValue);
			if (value === newValue) return;
			value = newValue;
		}
	});
}

function $set(data, key, value) {
	defineReactive(data, key, value);
}
複製代碼

5.jpg

Vue 主要經過如下 4 個步驟來實現數據雙向綁定的:

  • 實現一個監聽器 Observer:對數據對象進行遍歷,包括子屬性對象的屬性,利用 Object.defineProperty() 對屬性都加上 setter 和 getter。這樣的話,給這個對象的某個值賦值,就會觸發 setter,那麼就能監聽到了數據變化。
  • 實現一個解析器 Compile:解析 Vue 模板指令,將模板中的變量都替換成數據,而後初始化渲染頁面視圖,並將每一個指令對應的節點綁定更新函數,添加監聽數據的訂閱者,一旦數據有變更,收到通知,調用更新函數進行數據更新。
  • 實現一個訂閱者 Watcher:Watcher 訂閱者是 Observer 和 Compile 之間通訊的橋樑 ,主要的任務是訂閱 Observer 中的屬性值變化的消息,當收到屬性值變化的消息時,觸發解析器 Compile 中對應的更新函數。
  • 實現一個訂閱器 Dep:訂閱器採用 發佈-訂閱 設計模式,用來收集訂閱者 Watcher,對監聽器 Observer 和 訂閱者 Watcher 進行統一管理。

VUE中的組件(component)

組件的特色是:html

  • 每一個組件就是一個自定義標籤
  • 可複用
  • 方便維護
  • 方便拆分
  • 每一個組件做用域隔離(互不干擾)
  • 有完整的生命週期
  • 有本身的響應式數據和各類方法(事件)
  • ...

1.全局組件 & 組件的基本語法

在任何組件中能夠直接使用(不須要引入,直接在組件模板中調用便可) Vue.component(componentName,options)vue

  • 組件名字中的一點規範
    • kebab-case:只能調用
    • PasalCase:既可相似前種方式調用,也能夠方式調用
  • 調用組件的細節規範
    • 採用雙閉合方式
    • 單閉合方式不符合w3c規範(只能識別一個)
  • template
    • 每一個組件只能有一個根元素
    • 模板字符串方式
    • template標記方式
    • slot插槽處理
      • 基礎操做
      • 多插槽的指定
  • data必須是一個函數,保證不一樣組件之間的數據互不干擾(返回的對象中初始化數據)
  • ...
<my-component>
	<template v-slot:xxx 或者 #xxx>
		永懷善意
	</template>
</my-component>

{
	templete:`<div>
		<slot name='xxx'></slot>
	</div>`
}
複製代碼

2.局部組件

  • 建立組件:let componenName={...}
  • 基於components屬性聲明組件:想用哪一個組件須要先聲明
  • 使用組件

3.組件信息通信之父傳子:props屬性傳遞

  • 父組件調用到的時候
<my-component aa='hhh' :bb='xxx'></my-component> 複製代碼
  • 子組件中基於props聲明須要接收的屬性值
Vue.component('my-component',{
	props:['aa','bb'],
	...
})
複製代碼
  • props中聲明的屬性和data同樣,是響應式數據,掛載到vm實例上,可控制視圖渲染
  • props中的一些細節問題
    • 命名大小寫:傳遞的是kebab-case格式,props中獲取的是camelCase駝峯命名
    • 指定屬性的類型:props:{xxx:String,...}
    • 指定屬性的默認值:props:{xxx:{type:String,default:'xxx',required:true}}
      • type若是是一個數組,意爲指定的多類型皆能夠
      • default能夠是一個函數,函數返回值是默認值
      • validator自定義驗證規則函數:必須符合函數中指定的規則,返回true/false
    • 傳遞的屬性值默認都是字符串格式,若是想要讓傳遞的值是數字、布爾、數組、對象等格式,咱們須要使用v-bind處理
    • 樣式和class自動合併問題

4.vue的單向數據流

全部的 prop 都使得其父子 prop 之間造成了一個單向下行綁定:父級 prop 的更新會向下流動到子組件中,可是反過來則不行。java

Vue 的父組件和子組件生命週期鉤子函數執行順序能夠歸類爲如下 4 部分:node

  • 加載渲染過程:父 beforeCreate -> 父 created -> 父 beforeMount -> 子 beforeCreate -> 子 created -> 子 beforeMount -> 子 mounted -> 父 mounted
  • 子組件更新過程:父 beforeUpdate -> 子 beforeUpdate -> 子 updated -> 父 updated
  • 父組件更新過程:父 beforeUpdate -> 父 updated
  • 銷燬過程:父 beforeDestroy -> 子 beforeDestroy -> 子 destroyed -> 父 destroyed

每次父級組件發生更新時,子組件中全部的 prop 都將會刷新爲最新的值。這意味着你不該該在一個子組件內部改變 prop。若是你這樣作了,Vue 會在瀏覽器的控制檯中發出警告。子組件想修改時,只能經過 $emit 派發一個自定義事件,父組件接收到後,由父組件修改。有兩種常見的試圖改變一個 prop 的情形 :react

  • 這個 prop 用來傳遞一個初始值;這個子組件接下來但願將其做爲一個本地的 prop 數據來使用。 在這種狀況下,最好定義一個本地的 data 屬性並將這個 prop 用做其初始值
  • 這個 prop 以一種原始的值傳入且須要進行轉換。 在這種狀況下,最好使用這個 prop 的值來定義一個計算屬性

5.組件信息通信之子改父:this.$emit

  • 訂閱自定義事件:調用組件的時候基於屬性傳遞一個方法 (父)
<my-component @func='xxx'></my-component> new Vue({ methods:{ xxx(value){ //=>value是this.$emit時候傳遞的第二個參數值 } } }); 複製代碼
  • 通知自定義事件執行 (子)
{
	methods:{
		xxx(){
			this.$emit('func',10);
		}
	}
}
複製代碼
  • 也能夠基於此方法實現兄弟組件(父子組件、隔代組件)之間的信息通訊
let eventBus=new Vue; //=>建立事件總線

//A組件
eventBus.$on('xxxA',this.func);

//B組件
eventBus.$emit('xxxA');
複製代碼

6.基於ref實現父子組件信息通訊

  • ref 若是在普通的 DOM 元素上使用,引用指向的就是 DOM 元素;若是用在子組件上,引用就指向組件實例,基於此能夠快速獲取和操做子組件中的數據
  • parent和children是獲取組件和子組件的實例,只不過$children是一個數組集合,須要咱們記住組件順序才能夠

7.基於provide和inject實現祖先與後代的通訊

  • 祖先組件基於provide註冊須要供後代組件使用的數據
{
	provide:{ //=>對象或者返回對象的函數均可以(屬性值若是是data中的數據,則必須使用函數的方法進行處理)
		name:'hhh',
		year:10
	},
	...
}
複製代碼
  • 後代組件基於inject聲明須要使用的數據並調取使用
{
	inject:['name'],
	methods:{
		func(){
			let name=this.name;
		}
	}
}
複製代碼

VUE中的TRANSITION動畫

1. 什麼狀況下會用動畫

  • 條件渲染 v-if
  • 條件展現 v-show
  • 動態組件 例如:vue-router控制組件渲染
  • ...

2. 如何實現動畫

  • 修改元素的樣式:style & class
  • 使用JS實現動畫(前兩週在某些場景下都須要本身直接去操做DOM或者更加的麻煩)
  • 使用vue內置的transition & transition-group

3. transition的基礎使用

  • v-enter:定義進入過渡的開始狀態,在元素被插入以前生效,在元素被插入以後的下一幀移除
  • v-enter-active:定義進入過渡生效時的狀態,在整個進入過渡的階段中應用,在元素被插入以前生效,在過渡/動畫完成以後移除
  • v-enter-to: 定義進入過渡的結束狀態,元素被插入以後下一幀生效 ,在過渡/動畫完成以後移除
  • v-leave: 定義離開過渡的開始狀態,在離開過渡被觸發時馬上生效,下一幀被移除
  • v-leave-active:定義離開過渡生效時的狀態,在整個離開過渡的階段中應用,在離開過渡被觸發時馬上生效,在過渡/動畫完成以後移除
  • v-leave-to:  定義離開過渡的結束狀態,在離開過渡被觸發以後下一幀生效,在過渡/動畫完成以後移除
  • 基於 transiton 標記中的 name 屬性來進行動畫樣式區分
    • .demo-enter 等
  • 自定義過渡類名(例如:結合animate.css使用)
    • <transitionjquery

      enter-active-class="animated xxx"  leave-active-class="animated xxx"vue-router

4.JAVASCRIPT中的動畫鉤子函數

  • Velocity.js函數
<transition
  @before-enter="beforeEnter"
  @enter="enter"
  @after-enter="afterEnter"
  @before-leave="beforeLeave"
  ...
>
</transition>

methods:{
	 beforeEnter: function (el,done) {
   	 
   },
   ...
}
複製代碼

5. transition-group 處理多組元素動畫

  • 若是在transition-group中使用v-for,須要設置:key惟一值
  • 小練習:關鍵詞模糊匹配搜索

綜合實戰案例

1. 輪播圖的實現

2. TASK OA任務管理系統(俗稱TODO)

相關文章
相關標籤/搜索