最近將Vue進階文檔伺糠,vuex和vue-router都看了一遍伦泥,重新寫了些對初階知識點的認(rèn)識蹬耘,加了些vuex和vue-router的學(xué)習(xí)心得芝雪,文章沒有經(jīng)過排版,先分享综苔,介意的可先逃
框架出現(xiàn)的需求
Web應(yīng)用日趨復(fù)雜化以致前端開發(fā)難以單兵作戰(zhàn)惩系,此時需要一種統(tǒng)一的規(guī)范將所有人緊緊拴在一起,因此框架應(yīng)運而生
通過框架如筛,團隊成員在能在事先規(guī)定的接口各行其事堡牡,最后能較好將各個部分整合在一起
MVC框架的基本了解
MVC是框架的一種經(jīng)典范式,將整個Web文件劃分3層杨刨,每一層相對獨立并通過統(tǒng)一接口聯(lián)系在一起
Model:數(shù)據(jù)層晤柄,專門存放程序數(shù)據(jù)源,常用JSON格式數(shù)據(jù)
View:視圖層妖胀,由HTML+CSS構(gòu)成的界面
Controller:控制層芥颈,處理業(yè)務(wù)邏輯,是M和V的橋梁赚抡,通常負(fù)責(zé)處理數(shù)據(jù)與視圖的傳輸
Vue
數(shù)據(jù)綁定
- {{message}}:文本信息/單個JS表達(dá)式
- v-text='dataName':文本信息
- v-html='dataName':html
- v-bind:Attribute='dataName':元素屬性值
- v-model='dataName':數(shù)據(jù)雙向綁定
Class與Style綁定
code
處于人道主義爬坑,不建議在VM上綁定樣式,如有興趣請看綁定內(nèi)聯(lián)樣式
流程渲染語句
v-if和v-for專門用來渲染view
- v-if='dataName'怕品,為布爾值
- v-show='dataName'
- v-for='todo in todos'
v-if & v-show
二者區(qū)別相當(dāng)于妇垢,
經(jīng)常切換的用v-show
不常切換的用v-if,v-if還有v-else
v-for中的todos可以是數(shù)組也可以是對象
v-for
事件綁定
v-on:eventName='method'
demo
組件系統(tǒng)
組件本質(zhì)是具有預(yù)定義項的Vue實例
Vue的組件系統(tǒng)知識點包括:
組件注冊肉康,組件間的數(shù)據(jù)通信
code
構(gòu)建一個Vue應(yīng)用
- var app = new Vue(opts)
- opts的data屬性被Vue實例所代理闯估,可直接通過app.xxx訪問
- 部分opts的屬性和方法可通過app.$xxx訪問以便和data屬性區(qū)分
code
過濾器
過濾器只允許在mustache綁定和v-bind中使用,常用于文本轉(zhuǎn)換
計算屬性
處理數(shù)據(jù)的復(fù)雜邏輯
data:{
message:'hello world'
},
computed:{
splitStr:function{
return this.message.split(' ')
}
}
splitStr依賴于message吼和,并且有緩存
method可實現(xiàn)同樣效果涨薪,但不對結(jié)果進行緩存
code
計算屬性的getter和setter
computed:{
greet:{
get:function(){
return this.message
},
set:function(newVal){
this.message = newVal
}
}
}
觀察屬性
監(jiān)視數(shù)據(jù)變化
code
事件監(jiān)聽
組件
全局注冊
局部注冊
組件注冊時必須包含根節(jié)點
注冊
組件間的數(shù)據(jù)通信
props down events up
props down
events up
非父組件通信
動態(tài)組件
code
內(nèi)容分發(fā)——slot插槽
code
code2
異步組件
當(dāng)打包構(gòu)建應(yīng)用時,Javascript 包會變得非常大炫乓,影響頁面加載刚夺。如果我們能把不同路由對應(yīng)的組件分割成不同的代碼塊,然后當(dāng)路由被訪問的時候才加載對應(yīng)組件末捣,這樣就更加高效
Vue.component('async-webpack-example', function (resolve) {
// 這個特殊的 require 語法告訴 webpack
// 自動將編譯后的代碼分割成不同的塊侠姑,
// 這些塊將通過 Ajax 請求自動下載。
require(['./my-async-component'], resolve)
})
const Foo = resolve => {
// require.ensure 是 Webpack 的特殊語法箩做,用來設(shè)置 code-split point
// (代碼分塊)
require.ensure(['./Foo.vue'], () => {
resolve(require('./Foo.vue'))
})
}
const Foo = resolve => require(['./Foo.vue'], resolve)
組件的接口
Props:將外部環(huán)境數(shù)據(jù)傳給組件
Events:組件觸發(fā)事件傳遞給外部環(huán)境
Slots:允許外部環(huán)境將內(nèi)容插入組件中
組件的命名
注冊組件和字符串模板莽红,使用kebab-case ,camelCase 邦邦,或 TitleCase安吁;
HTML中必須使用kebab-case;
如果組件不含slot,可以在使用組件時直接<my-component/>
render函數(shù)
使用javascript方式去創(chuàng)建模板燃辖,更加貼近編譯器鬼店,實際上所有的模板實際都是編譯成render函數(shù)
render
自定義指令
有的情況下,你仍然需要對純 DOM 元素進行底層操作,這時候就會用到自定義指令
demo
Vue插件
var Vue = require('vue')
var VueRouter = require('vue-router')
// 不要忘了調(diào)用此方法
Vue.use(VueRouter)
####### Vuex
狀態(tài)管理模式。它采用集中式存儲管理應(yīng)用的所有組件的狀態(tài)
父子組件的作用域相隔離黔龟,數(shù)據(jù)通信通過props down & event up妇智,但是有以下問題:
多層嵌套組件傳參繁瑣
采用父子組件直接引用或者通過事件來變更和同步狀態(tài)的多份拷貝
因此,可把組件的共享狀態(tài)抽取出來氏身,以一個全局單例模式管理
這個全局對象具有以下2個特點:
Vuex 的狀態(tài)存儲是響應(yīng)式的巍棱,狀態(tài)變化,組件更新
不能直接改變 store 中的狀態(tài)观谦,只能通過提交方式顯式地提交(commit) mutations拉盾。這樣使得我們可以方便地跟蹤每一個狀態(tài)的變化,類似git的commit的追蹤
new Vue({
// state
data () {
return {
count: 0
}
},
// view
template: `
<div>{{ count }}</div>
`,
// actions
methods: {
increment () {
this.count++
}
}
})
通過提交 mutation 的方式豁状,而非直接改變 store.state.count捉偏,更明確地追蹤到狀態(tài)的變化
因此可以實現(xiàn)一些能記錄每次狀態(tài)改變,保存狀態(tài)快照的調(diào)試工具泻红。有了它夭禽,我們甚至可以實現(xiàn)如時間穿梭般的調(diào)試體驗。
code-1
code-2
為什么要使用computed獲取state的數(shù)據(jù)谊路?
因為狀態(tài)存儲是響應(yīng)式讹躯,即時常變化的,對于這類動態(tài)數(shù)據(jù)應(yīng)該使用computed而不是data
特點
Vuex使用單一狀態(tài)樹,一個對象就包含了全部的應(yīng)用層級狀態(tài)潮梯,即唯一數(shù)據(jù)源
之前的組件依賴于全局狀態(tài)單例骗灶,如果在模塊化構(gòu)建系統(tǒng)中,需要為每個組件都導(dǎo)入store秉馏,Vue通過store選項耙旦,將狀態(tài)從根組件『注入』到每一個子組件中
如果存在store中state的一些派生狀態(tài),即state中的計算屬性---getters
權(quán)衡全局狀態(tài)和局部狀態(tài)B芫俊C舛肌!
mutations
mutation 必須同步執(zhí)行帆竹,即
store.commit('increment')
//等待函數(shù)執(zhí)行
mutations:{
increment:state => state.count++
}
action實現(xiàn)異步調(diào)用mutation原理在于action可以異步調(diào)用绕娘,從而間接事件mutation的異步調(diào)用,本質(zhì)mutation還是“同步”
異步操作
模塊
state是單一狀態(tài)樹栽连,如果數(shù)據(jù)量過大則不利于維護和觀察险领,store的modules屬性允許將state劃分為多個模塊
每個模塊都有自己的state和rootState,但是類似getter升酣、mutation和action是公有方法
modules
表單處理
<input v-model="obj.message">
當(dāng)input修改Vuex store的值時舷暮,由于不是由store.mutation引起的,所以會報錯噩茄;
解決方案是監(jiān)聽input的input/change事件下面,然后以載荷的形式store.commit發(fā)送消息給mutation
code-1
使用雙向綁定的計算屬性
code-2
vue-router
開啟一個router,在客戶端
1.View層創(chuàng)建特定標(biāo)簽的鏈接
2.JS
定義路由模板绩聘,定義路由沥割,將路由配置VueRouter實例,將VueRouter實例配置Vue實例
code-1
如果存在多個用戶共用一個模板的情況凿菩,只需要變更用戶名机杜,則可以使用動態(tài)路由
code
由于組件在動態(tài)路由中是復(fù)用的,所以不會觸發(fā)created屬性衅谷,如果想要監(jiān)聽變化椒拗,只需要在watch屬性下,監(jiān)聽$route參數(shù)
code
嵌套路由
有這么個需求获黔,首先識別用戶從而渲染用戶初始界面Home蚀苛,根據(jù)點擊的鏈接識別不同板塊內(nèi)容而渲染about和profile
code
命名路由
直接寫路徑太煩,可以通過傳遞對象的方式去命名路由
code
命名視圖
有時需要在同一個路由同級展示多個視圖玷氏,可以考慮使用命名視圖
routes;{
path:'/',
components:{}//要變成components
}
history模式
不加mode:'history'堵未,將使用 URL 的 hash 來模擬一個完整的 URL,于是當(dāng) URL 改變時盏触,頁面不會重新加載渗蟹。
如果不想要很丑的 hash块饺,我們可以用路由的 history 模式,這種模式充分利用 history.pushState API 來完成 URL 跳轉(zhuǎn)而無須重新加載頁面雌芽。
const router = new VueRouter({
mode: 'history',
routes: [...]
})
導(dǎo)航鉤子
鉤子意味著捕獲授艰,導(dǎo)航鉤子就是捕獲導(dǎo)航變化
可以在全局、某個路由以及某個組件中定義
teardown
響應(yīng)式機制
如何追蹤數(shù)據(jù)變化
使用Object.defineProperty的getter和setter
每一個組件實例膘怕,都有一個watcher實例對象
watcher實例對象作用是將data屬性記錄為依賴
當(dāng)data屬性的setter調(diào)用時想诅,會通知watcher
watcher發(fā)出re-render召庞,觸發(fā)組件的render函數(shù)
將render到虛擬DOM Tree
重置data的getter
最后走生命周期