最近將Vue進階文檔,vuex和vue-router都看了一遍,重新寫了些對初階知識點的認識,加了些vuex和vue-router的學習心得,文章沒有經過排版,先分享,介意的可先逃
框架出現的需求
Web應用日趨復雜化以致前端開發難以單兵作戰,此時需要一種統一的規范將所有人緊緊拴在一起,因此框架應運而生
通過框架,團隊成員在能在事先規定的接口各行其事,最后能較好將各個部分整合在一起
MVC框架的基本了解
MVC是框架的一種經典范式,將整個Web文件劃分3層,每一層相對獨立并通過統一接口聯系在一起
Model:數據層,專門存放程序數據源,常用JSON格式數據
View:視圖層,由HTML+CSS構成的界面
Controller:控制層,處理業務邏輯,是M和V的橋梁,通常負責處理數據與視圖的傳輸
Vue
數據綁定
- {{message}}:文本信息/單個JS表達式
- v-text='dataName':文本信息
- v-html='dataName':html
- v-bind:Attribute='dataName':元素屬性值
- v-model='dataName':數據雙向綁定
Class與Style綁定
code
處于人道主義,不建議在VM上綁定樣式,如有興趣請看綁定內聯樣式
流程渲染語句
v-if和v-for專門用來渲染view
- v-if='dataName',為布爾值
- v-show='dataName'
- v-for='todo in todos'
v-if & v-show
二者區別相當于,
經常切換的用v-show
不常切換的用v-if,v-if還有v-else
v-for中的todos可以是數組也可以是對象
v-for
事件綁定
v-on:eventName='method'
demo
組件系統
組件本質是具有預定義項的Vue實例
Vue的組件系統知識點包括:
組件注冊,組件間的數據通信
code
構建一個Vue應用
- var app = new Vue(opts)
- opts的data屬性被Vue實例所代理,可直接通過app.xxx訪問
- 部分opts的屬性和方法可通過app.$xxx訪問以便和data屬性區分
code
過濾器
過濾器只允許在mustache綁定和v-bind中使用,常用于文本轉換
計算屬性
處理數據的復雜邏輯
data:{
message:'hello world'
},
computed:{
splitStr:function{
return this.message.split(' ')
}
}
splitStr依賴于message,并且有緩存
method可實現同樣效果,但不對結果進行緩存
code
計算屬性的getter和setter
computed:{
greet:{
get:function(){
return this.message
},
set:function(newVal){
this.message = newVal
}
}
}
觀察屬性
監視數據變化
code
事件監聽
組件
全局注冊
局部注冊
組件注冊時必須包含根節點
注冊
組件間的數據通信
props down events up
props down
events up
非父組件通信
動態組件
code
內容分發——slot插槽
code
code2
異步組件
當打包構建應用時,Javascript 包會變得非常大,影響頁面加載。如果我們能把不同路由對應的組件分割成不同的代碼塊,然后當路由被訪問的時候才加載對應組件,這樣就更加高效
Vue.component('async-webpack-example', function (resolve) {
// 這個特殊的 require 語法告訴 webpack
// 自動將編譯后的代碼分割成不同的塊,
// 這些塊將通過 Ajax 請求自動下載。
require(['./my-async-component'], resolve)
})
const Foo = resolve => {
// require.ensure 是 Webpack 的特殊語法,用來設置 code-split point
// (代碼分塊)
require.ensure(['./Foo.vue'], () => {
resolve(require('./Foo.vue'))
})
}
const Foo = resolve => require(['./Foo.vue'], resolve)
組件的接口
Props:將外部環境數據傳給組件
Events:組件觸發事件傳遞給外部環境
Slots:允許外部環境將內容插入組件中
組件的命名
注冊組件和字符串模板,使用kebab-case ,camelCase ,或 TitleCase;
HTML中必須使用kebab-case;
如果組件不含slot,可以在使用組件時直接<my-component/>
render函數
使用javascript方式去創建模板,更加貼近編譯器,實際上所有的模板實際都是編譯成render函數
render
自定義指令
有的情況下,你仍然需要對純 DOM 元素進行底層操作,這時候就會用到自定義指令
demo
Vue插件
var Vue = require('vue')
var VueRouter = require('vue-router')
// 不要忘了調用此方法
Vue.use(VueRouter)
####### Vuex
狀態管理模式。它采用集中式存儲管理應用的所有組件的狀態
父子組件的作用域相隔離,數據通信通過props down & event up,但是有以下問題:
多層嵌套組件傳參繁瑣
采用父子組件直接引用或者通過事件來變更和同步狀態的多份拷貝
因此,可把組件的共享狀態抽取出來,以一個全局單例模式管理
這個全局對象具有以下2個特點:
Vuex 的狀態存儲是響應式的,狀態變化,組件更新
不能直接改變 store 中的狀態,只能通過提交方式顯式地提交(commit) mutations。這樣使得我們可以方便地跟蹤每一個狀態的變化,類似git的commit的追蹤
new Vue({
// state
data () {
return {
count: 0
}
},
// view
template: `
<div>{{ count }}</div>
`,
// actions
methods: {
increment () {
this.count++
}
}
})
通過提交 mutation 的方式,而非直接改變 store.state.count,更明確地追蹤到狀態的變化
因此可以實現一些能記錄每次狀態改變,保存狀態快照的調試工具。有了它,我們甚至可以實現如時間穿梭般的調試體驗。
code-1
code-2
為什么要使用computed獲取state的數據?
因為狀態存儲是響應式,即時常變化的,對于這類動態數據應該使用computed而不是data
特點
Vuex使用單一狀態樹,一個對象就包含了全部的應用層級狀態,即唯一數據源
之前的組件依賴于全局狀態單例,如果在模塊化構建系統中,需要為每個組件都導入store,Vue通過store選項,將狀態從根組件『注入』到每一個子組件中
如果存在store中state的一些派生狀態,即state中的計算屬性---getters
權衡全局狀態和局部狀態!!!
mutations
mutation 必須同步執行,即
store.commit('increment')
//等待函數執行
mutations:{
increment:state => state.count++
}
action實現異步調用mutation原理在于action可以異步調用,從而間接事件mutation的異步調用,本質mutation還是“同步”
異步操作
模塊
state是單一狀態樹,如果數據量過大則不利于維護和觀察,store的modules屬性允許將state劃分為多個模塊
每個模塊都有自己的state和rootState,但是類似getter、mutation和action是公有方法
modules
表單處理
<input v-model="obj.message">
當input修改Vuex store的值時,由于不是由store.mutation引起的,所以會報錯;
解決方案是監聽input的input/change事件,然后以載荷的形式store.commit發送消息給mutation
code-1
使用雙向綁定的計算屬性
code-2
vue-router
開啟一個router,在客戶端
1.View層創建特定標簽的鏈接
2.JS
定義路由模板,定義路由,將路由配置VueRouter實例,將VueRouter實例配置Vue實例
code-1
如果存在多個用戶共用一個模板的情況,只需要變更用戶名,則可以使用動態路由
code
由于組件在動態路由中是復用的,所以不會觸發created屬性,如果想要監聽變化,只需要在watch屬性下,監聽$route參數
code
嵌套路由
有這么個需求,首先識別用戶從而渲染用戶初始界面Home,根據點擊的鏈接識別不同板塊內容而渲染about和profile
code
命名路由
直接寫路徑太煩,可以通過傳遞對象的方式去命名路由
code
命名視圖
有時需要在同一個路由同級展示多個視圖,可以考慮使用命名視圖
routes;{
path:'/',
components:{}//要變成components
}
history模式
不加mode:'history',將使用 URL 的 hash 來模擬一個完整的 URL,于是當 URL 改變時,頁面不會重新加載。
如果不想要很丑的 hash,我們可以用路由的 history 模式,這種模式充分利用 history.pushState API 來完成 URL 跳轉而無須重新加載頁面。
const router = new VueRouter({
mode: 'history',
routes: [...]
})
導航鉤子
鉤子意味著捕獲,導航鉤子就是捕獲導航變化
可以在全局、某個路由以及某個組件中定義
teardown
響應式機制
如何追蹤數據變化
使用Object.defineProperty的getter和setter
每一個組件實例,都有一個watcher實例對象
watcher實例對象作用是將data屬性記錄為依賴
當data屬性的setter調用時,會通知watcher
watcher發出re-render,觸發組件的render函數
將render到虛擬DOM Tree
重置data的getter
最后走生命周期