Vue2全家桶
阿新 • • 發佈:2022-04-12
1). 一位華裔前Google工程師(尤雨溪)開發的前端js庫
2). 作用: 動態構建使用者介面
3). 特點:
* 遵循MVVM模式
* 編碼簡潔, 體積小, 執行效率高, 移動/PC端開發
* 它本身只關注UI, 可以輕鬆引入vue外掛和其它第三庫開發專案
4). 與其它框架的關聯:
* 借鑑angular的模板和資料繫結技術
* 借鑑react的元件化和虛擬DOM技術
5). vue包含一系列的擴充套件外掛(庫):
* vue-cli: vue腳手架
* vue-resource(axios): ajax請求
* vue-router: 路由
* vuex: 狀態管理
* vue-lazyload: 圖片懶載入
* vue-scroller: 頁面滑動相關
* mint-ui: 基於vue的元件庫(移動端)
* element-ui: 基於vue的元件庫(PC端)
2. 基本使用
1). 引入vue.js
2). 建立Vue例項物件(vm), 指定選項(配置)物件
el : 指定dom標籤容器的選擇器
data : 指定初始化狀態資料的物件/函式(返回一個物件)
3). 在頁面模板中使用{{}}或vue指令
3. Vue物件的選項
1). el
指定dom標籤容器的選擇器
Vue就會管理對應的標籤及其子標籤
2). data
物件或函式型別
指定初始化狀態屬性資料的物件
vm也會自動擁有data中所有屬性
頁面中可以直接訪問使用
資料代理: 由vm物件來代理對data中所有屬性的操作(讀/寫)
3). methods
包含多個方法的物件
供頁面中的事件指令來繫結回撥
回撥函式預設有event引數, 但也可以指定自己的引數
所有的方法由vue物件來呼叫, 訪問data中的屬性直接使用this.xxx
4). computed
包含多個方法的物件
對狀態屬性進行計算返回一個新的資料, 供頁面獲取顯示
一般情況下是相當於是一個只讀的屬性
利用set/get方法來實現屬性資料的計算讀取, 同時監視屬性資料的變化
如何給物件定義get/set屬性
在建立物件時指定: get name () {return xxx} / set name (value) {}
物件建立之後指定: Object.defineProperty(obj, age, {get(){}, set(value){}})
5). watch
包含多個屬性監視的物件
分為一般監視和深度監視
xxx: function(value){}
xxx : {
deep : true,
handler : fun(value)
}
另一種新增監視方式: vm.$watch('xxx', function(value){})
4. 過渡動畫
利用vue去操控css的transition/animation動畫
模板: 使用<transition name='xxx'>包含帶動畫的標籤
css樣式
.fade-enter-active: 進入過程, 指定進入的transition
.fade-leave-active: 離開過程, 指定離開的transition
.xxx-enter, .xxx-leave-to: 指定隱藏的樣式
編碼例子
.xxx-enter-active, .xxx-leave-active {
transition: opacity .5s
}
.xxx-enter, .xxx-leave-to {
opacity: 0
}
<transition name="xxx">
<p v-if="show">hello</p>
</transition>
5. 生命週期
vm/元件物件
生命週期圖
主要的生命週期函式(鉤子)
created() / mounted(): 啟動非同步任務(啟動定時器,傳送ajax請求, 繫結監聽)
beforeDestroy(): 做一些收尾的工作
6. 自定義過濾器
1). 理解
對需要顯示的資料進行格式化後再顯示
2). 編碼
1). 定義過濾器
Vue.filter(filterName, function(value[,arg1,arg2,...]){
// 進行一定的資料處理
return newValue
})
2). 使用過濾器
<div>{{myData | filterName}}</div>
<div>{{myData | filterName(arg)}}</div>
7. vue內建指令
v-text/v-html: 指定標籤體
* v-text : 當作純文字
* v-html : 將value作為html標籤來解析
v-if v-else v-show: 顯示/隱藏元素
* v-if : 如果vlaue為true, 當前標籤會輸出在頁面中
* v-else : 與v-if一起使用, 如果value為false, 將當前標籤輸出到頁面中
* v-show: 就會在標籤中新增display樣式, 如果vlaue為true, display=block, 否則是none
v-for : 遍歷
* 遍歷陣列 : v-for="(person, index) in persons"
* 遍歷物件 : v-for="value in person" $key
v-on : 繫結事件監聽
* v-on:事件名, 可以縮寫為: @事件名
* 監視具體的按鍵: @keyup.keyCode @keyup.enter
* 停止事件的冒泡和阻止事件預設行為: @click.stop @click.prevent
* 隱含物件: $event
v-bind : 強制繫結解析表示式
* html標籤屬性是不支援表示式的, 就可以使用v-bind
* 可以縮寫為: :id='name'
* :class
* :class="a"
* :class="{classA : isA, classB : isB}"
* :class="[classA, classB]"
* :style
:style="{color : color}"
v-model
* 雙向資料繫結
* 自動收集使用者輸入資料
ref : 標識某個標籤
* ref='xxx'
* 讀取得到標籤物件: this.$refs.xxx
8. 自定義指令
1). 註冊全域性指令
Vue.directive('my-directive', function(el, binding){
el.innerHTML = binding.value.toUpperCase()
})
2). 註冊區域性指令
directives : {
'my-directive' : function(el, binding) {
el.innerHTML = binding.value.toUpperCase()
}
}
3). 使用指令
<div v-my-directive='xxx'>
----------------------假裝這裡有條分割線------------------
1.[].slice.call(lis): 將偽陣列轉換為真陣列
2.node.nodeType: 得到節點型別
3.Object.defineProperty(obj, propertyName, {}): 給物件新增/修改屬性(指定描述符)
configurable: true/false 是否可以重新define
enumerable: true/false 是否可以列舉(for..in / keys())
value: 指定初始值
writable: true/false value是否可以修改存取(訪問)描述符
get: 函式, 用來得到當前屬性值
set: 函式, 用來監視當前屬性值的變化
4.Object.keys(obj): 得到物件自身可列舉的屬性名的陣列
5.DocumentFragment: 文件碎片(高效批量更新多個節點)
6.obj.hasOwnProperty(prop): 判斷prop是否是obj自身的屬性
2. 資料代理(MVVM.js)
1.通過一個物件代理對另一個物件中屬性的操作(讀/寫)
2.通過vm物件來代理data物件中所有屬性的操作
3.好處: 更方便的操作data中的資料
4.基本實現流程
1). 通過Object.defineProperty()給vm新增與data物件的屬性對應的屬性描述符
2). 所有新增的屬性都包含getter/setter
3). 在getter/setter內部去操作data中對應的屬性資料
3. 模板解析(compile.js)
1.模板解析的關鍵物件: compile物件
2.模板解析的基本流程:
1). 將el的所有子節點取出, 新增到一個新建的文件fragment物件中
2). 對fragment中的所有層次子節點遞迴進行編譯解析處理
* 對錶達式文字節點進行解析
* 對元素節點的指令屬性進行解析
* 事件指令解析
* 一般指令解析
3). 將解析後的fragment新增到el中顯示
3.解析表示式文字節點: textNode.textContent = value
1). 根據正則物件得到匹配出的表示式字串: 子匹配/RegExp.$1
2). 從data中取出表示式對應的屬性值
3). 將屬性值設定為文字節點的textContent
4.事件指令解析: elementNode.addEventListener(事件名, 回撥函式.bind(vm))
v-on:click="test"
1). 從指令名中取出事件名
2). 根據指令的值(表示式)從methods中得到對應的事件處理函式物件
3). 給當前元素節點繫結指定事件名和回撥函式的dom事件監聽
4). 指令解析完後, 移除此指令屬性
5.一般指令解析: elementNode.xxx = value
1). 得到指令名和指令值(表示式)
2). 從data中根據表示式得到對應的值
3). 根據指令名確定需要操作元素節點的什麼屬性
* v-text---textContent屬性
* v-html---innerHTML屬性
* v-class--className屬性
4). 將得到的表示式的值設定到對應的屬性上
5). 移除元素的指令屬性
4. 資料劫持-->資料繫結
1.資料繫結(model==>View):
1). 一旦更新了data中的某個屬性資料, 所有介面上直接使用或間接使用了此屬性的節點都會更新(更新)
2.資料劫持
1). 資料劫持是vue中用來實現資料繫結的一種技術
2). 基本思想: 通過defineProperty()來監視data中所有屬性(任意層次)資料的變化, 一旦變化就去更新介面
3.四個重要物件
1). Observer
* 用來對data所有屬性資料進行劫持的建構函式
* 給data中所有屬性重新定義屬性描述(get/set)
* 為data中的每個屬性建立對應的dep物件
2). Dep(Depend)
* data中的每個屬性(所有層次)都對應一個dep物件
* 建立的時機:
* 在初始化define data中各個屬性時建立對應的dep物件
* 在data中的某個屬性值被設定為新的物件時
* 物件的結構
{
id, // 每個dep都有一個唯一的id
subs //包含n個對應watcher的陣列(subscribes的簡寫)
}
* subs屬性說明
* 當一個watcher被建立時, 內部會將當前watcher物件新增到對應的dep物件的subs中
* 當此data屬性的值發生改變時, 所有subs中的watcher都會收到更新的通知, 從而最終更新對應的介面
3). Compile
* 用來解析模板頁面的物件的建構函式(一個例項)
* 利用compile物件解析模板頁面
* 每解析一個表示式(非事件指令)都會建立一個對應的watcher物件, 並建立watcher與dep的關係
* complie與watcher關係: 一對多的關係
4). Watcher
* 模板中每個非事件指令或表示式都對應一個watcher物件
* 監視當前表示式資料的變化
* 建立的時機: 在初始化編譯模板時
* 物件的組成
{
vm, //vm物件
exp, //對應指令的表示式
cb, //當表示式所對應的資料發生改變的回撥函式
value, //表示式當前的值
depIds //表示式中各級屬性所對應的dep物件的集合物件
//屬性名為dep的id, 屬性值為dep
}
5). 總結: dep與watcher的關係: 多對多
* 一個data中的屬性對應對應一個dep, 一個dep中可能包含多個watcher(模板中有幾個表示式使用到了屬性)
* 模板中一個非事件表示式對應一個watcher, 一個watcher中可能包含多個dep(表示式中包含了幾個data屬性)
* 資料繫結使用到2個核心技術
* defineProperty()
* 訊息訂閱與釋出
4.雙向資料繫結
1). 雙向資料繫結是建立在單向資料繫結(model==>View)的基礎之上的
2). 雙向資料繫結的實現流程:
* 在解析v-model指令時, 給當前元素新增input監聽
* 當input的value發生改變時, 將最新的值賦值給當前表示式所對應的data屬性
----------------------假裝這裡有條分割線------------------
用來建立vue專案的工具包
建立專案:
npm install -g vue-cli
vue init webpack VueDemo
vue create 專案名稱
開發環境執行:
cd VueDemo
npm install
npm run serve
生產環境打包釋出
npm run build
npm install -g serve
serve dist
http://localhost:5000
2. eslint
用來做專案編碼規範檢查的工具
基本原理: 定義了很多規則, 檢查專案的程式碼一旦發現違背了某個規則就輸出相應的提示資訊
有相應的配置, 可定製檢查
3. 元件化程式設計
vue檔案包含3個部分
<template>
<div></div>
</template>
<script>
export default {
props: []/{}
data(){},
computed: {}
methods: {},
watch: {}
filters: {}
directives: {
color:{
bind(el,binding){}
update(el,binding){}
}
或
color(el,binding){}
}
components: {}
}
</script>
<style>
</style>
元件化編碼的基本流程
1). 拆分介面, 抽取元件
2). 編寫靜態元件
3). 編寫動態元件
初始化資料, 動態顯示初始化介面
實現與使用者互動功能
元件通訊的5種方式
props
vue的自定義事件
pubsub第三方庫
slot
vuex(後面單獨講)
props:
父子元件間通訊的基本方式
屬性值的2大型別:
一般: 父元件-->子元件
函式: 子元件-->父元件
隔層元件間傳遞: 必須逐層傳遞(麻煩)
兄弟元件間: 必須藉助父元件(麻煩)
vue自定義事件
子元件與父元件的通訊方式
用來取代function props
不適合隔層元件和兄弟元件間的通訊
pubsub第三方庫(訊息訂閱與釋出)
適合於任何關係的元件間通訊
slot
通訊是帶資料的標籤
注意: 標籤是在父元件中解析
vuex
多元件共享狀態(資料的管理)
元件間的關係也沒有限制
功能比pubsub強大, 更適用於vue專案
4. ajax
相關庫:
vue-resource: vue外掛, 多用於vue1.x
axios: 第三方庫, 多用於vue2.x
vue-resource使用
// 引入模組
import VueResource from 'vue-resource'
// 使用外掛
Vue.use(VueResource)
// 通過vue/元件物件傳送ajax請求
this.$http.get('/someUrl').then((response) => {
// success callback
console.log(response.data) //返回結果資料
}, (response) => {
// error callback
console.log(response.statusText) //錯誤資訊
})
axios使用
// 引入模組
import axios from 'axios'
// 傳送ajax請求
axios.get(url)
.then(response => {
console.log(response.data) // 得到返回結果資料
})
.catch(error => {
console.log(error.message)
})
5. vue-router
vue用來實現SPA的外掛
使用vue-router
1. 建立路由器: router/index.js
new VueRouter({
routes: [
{ // 一般路由
path: '/about',
component: about
},
{ // 自動跳轉路由
path: '/',
redirect: '/about'
}
]
})
2. 註冊路由器: main.js
import router from './router'
new Vue({
router
})
3. 使用路由元件標籤:
<router-link to="/xxx">Go to XXX</router-link>
<router-view></router-view>
編寫路由的3步
1. 定義路由元件
2. 對映路由
3. 編寫路由2個標籤
巢狀路由
children: [
{
path: '/home/news',
component: news
},
{
path: 'message',
component: message
}
]
向路由元件傳遞資料
params: <router-link to="/home/news/abc/123">
props: <router-view msg='abc'>
快取路由元件
<keep-alive>
<router-view></router-view>
</keep-alive>
路由的程式設計式導航
this.$router.push(path): 相當於點選路由連結(可以返回到當前路由介面)
this.$router.replace(path): 用新路由替換當前路由(不可以返回到當前路由介面)
this.$router.back(): 請求(返回)上一個記錄路由
----------------------假裝這裡有條分割線------------------
github站點: https://github.com/vuejs/vuex
線上文件: https://vuex.vuejs.org/zh-cn/
簡單來說: 對應用中元件的狀態進行集中式的管理(讀/寫)
2. 狀態自管理應用
state: 驅動應用的資料來源
view: 以宣告方式將state對映到檢視
actions: 響應在view上的使用者輸入導致的狀態變化(包含n個更新狀態的方法)
3. 多元件共享狀態的問題
多個檢視依賴於同一狀態
來自不同檢視的行為需要變更同一狀態
以前的解決辦法
* 將資料以及操作資料的行為都定義在父元件
* 將資料以及操作資料的行為傳遞給需要的各個子元件(有可能需要多級傳遞)
vuex就是用來解決這個問題的
4. vuex的核心概念
1). state(資料)
vuex管理的狀態物件
它應該是唯一的
const state = {
xxx: initValue
}
2). mutations(操作資料的方法,影響原資料。必須為同步)
包含多個直接更新state的方法(回撥函式)的物件
誰來觸發: action中的commit('mutation名稱')
只能包含同步的程式碼, 不能寫非同步程式碼
const mutations = {
yyy (state, data) {
// 更新state的某個屬性
}
}
3). actions($store.dispatch
觸發mutations方法 可以為非同步)
包含多個事件回撥函式的物件
通過執行: commit()來觸發mutation的呼叫, 間接更新state
誰來觸發: 元件中: $store.dispatch('action名稱') // 'zzz'
可以包含非同步程式碼(定時器, ajax)
const actions = {
zzz ({commit, state}, data1) {
commit('yyy', data2)
}
}
4). getters(相當於store中的計算屬性,對state中的資料操作後快取,不會影響原資料)
包含多個計算屬性(get)的物件
誰來讀取: 元件中: $store.getters.xxx
const getters = {
mmm (state) {
return ...
}
}
5). modules(store分割的模組)
包含多個module
一個module是一個store的配置物件
與一個元件(包含有共享資料)對應
6). 向外暴露store物件
export default new Vuex.Store({
state,
mutations,
actions,
getters
})
7). 元件中:
import {mapGetters, mapActions} from 'vuex'
export default {
computed: mapGetters(['mmm'])
methods: mapActions(['zzz'])
}
{{mmm}} @click="zzz(data)"
8). 對映store
import store from './store'
new Vue({
store
})
9). store物件
1.所有用vuex管理的元件中都多了一個屬性$store, 它就是一個store物件
2.屬性:
state: 註冊的state物件
getters: 註冊的getters物件
3.方法:
dispatch(actionName, data): 分發action
5. 將vuex引到專案中
1). 下載: npm install vuex --save
2). 使用vuex
1.store.js
import Vuex from 'vuex'
export default new Vuex.Store({
state,
mutations,
actions,
getters,
modules
})
2.main.js
import store from './store.js'
new Vue({
store
})