MVVM 是 Model-View-ViewModel 的縮寫。mvvm 是一種設計思想。Model 層表明數據模型,也能夠在 Model 中定義數據修改和操做的業務邏輯;View 表明 UI 組件,它負責將數據模型轉化成 UI 展示出來,ViewModel 是一個同步 View 和 Model 的對象。html
在 MVVM 架構下,View 和 Model 之間並無直接的聯繫,而是經過 ViewModel 進行交互,Model 和 ViewModel 之間的交互是雙向的, 所以 View 數據的變化會同步到 Model 中,而 Model 數據的變化也會當即反應到 View 上。前端
ViewModel 經過雙向數據綁定把 View 層和 Model 層鏈接了起來,而 View 和 Model 之間的同步工做徹底是自動的,無需人爲干涉,所以開發者只需關注業務邏輯,不須要手動操做 DOM, 不須要關注數據狀態的同步問題,複雜的數據狀態維護徹底由 MVVM 來統一管理。vue
MVC與MVVM都是前端web開發的框架模式webpack
MVC(Model View Controller 模型-視圖-控制器)是一種Web架構的模式。通訊是單向的:瀏覽器發送請求,Model和Contorller交互獲取數據,Contorller調用View,View渲染數據返回。ios
MVVM(Model-View-ViewModel),是一種基於前端開發的架構模式。核心是提供對View 和 Model 的雙向數據綁定,View和Model之間並無直接的聯繫,而是經過ViewModel(VM)進行交互,View的變更,自動反映在Model上,反之亦然,這樣就保證視圖和數據的一致性。web
答:vue在使用過程當中,分爲多個階段,具備建立、運行、銷燬。ajax
建立階段:beforeCreate: 建立以前,data和methods還沒有初始化。vue-router
created: data和methods已經建立,能夠被訪問,此處能夠發送ajax請求,並給data作數據初始化。(數據放在了實例身上,但尚未渲染DOM,el尚未)。vuex
beforeMount:: 容器內容仍是原始的vue指令內容,尚未被vue作數據渲染,沒被替換。npm
mounted: 頁面剛被vue渲染完畢,若是要操做DOM,此處是最好的選擇。
運行階段:beforeUpdate: vue虛擬數據是最新的,可是頁面仍是舊的,出現變化時執行,在變化以前觸發。
updated: 頁面和數據都是最新的,出現變化後執行。
銷燬階段:beforeDestroy: 將要銷燬,銷燬以前階段,實例還正常使用。
destroyed: 銷燬以後,實例不在工做了。
<blog-post :title="vue"></blog-post>
,注意傳遞的數據須要在子組件用props屬性接收。(父元素經過標籤進行屬性傳值,子元素經過props方法接收數據)this.$children
訪問或遞歸訪問其子孫組件。this.$parent
訪問或遞歸訪問其父級組件,直至根組件。ref
屬性爲子組件指定一個索引名稱,在父組件中經過 this.$ref[name]
訪問ref爲name的子組件。provide
函數返回提供的數據,子孫後代組件使用 inject
屬性接收上層組件provide的數據。.$emit('event', data)
觸發一個自定義事件,並傳遞數據;.
$on('event', data => { console.log(data) })
監聽自定義事件,並在回調函數中處理傳遞過來的數據。this.$store.state
訪問 state;commit mutation
或者 dispatch action
來更新store裏的數據v-if(判斷是否隱藏)、v-for(把數據遍歷出來)、v-bind(綁定屬性)、v-model(實現雙向綁定)
vue.js 是採用數據劫持結合發佈者-訂閱者模式的方式,經過 Object.defineProperty()來劫持各個屬性的 setter,getter,在數據變更時發佈消息給訂閱者,觸發相應的監聽回調。
具體步驟:
第一步:須要 observe 的數據對象進行遞歸遍歷,包括子屬性對象的屬性,都加上 setter 和 getter 這樣的話,給這個對象的某個值賦值,就會觸發 setter,那麼就能監聽到了數據變化
第二步:compile 解析模板指令,將模板中的變量替換成數據,而後初始化渲染頁面視圖,並將每一個指令對應的節點綁定更新函數,添加監聽數據的訂閱者,一旦數據有變更,收到通知,更新視圖
第三步:Watcher 訂閱者是 Observer 和 Compile 之間通訊的橋樑,主要作的事情是:
第四步:MVVM 做爲數據綁定的入口,整合 Observer、Compile 和 Watcher 三者,經過 Observer 來監聽本身的 model 數據變化,經過 Compile 來解析編譯模板指令,最終利用 Watcher 搭起 Observer 和 Compile 之間的通訊橋樑,達到數據變化 -> 視圖更新;視圖交互變化(input) -> 數據 model 變動的雙向綁定效果。
在實際項目中咱們會碰到多層嵌套的組件組合而成,可是咱們如何實現嵌套路由呢?所以咱們須要在 VueRouter 的參數中使用 children 配置,這樣就能夠很好的實現路由嵌套。
index.html,只有一個路由出口
<div id="app"> <!-- router-view 路由出口, 路由匹配到的組件將渲染在這裏 --> <router-view></router-view> </div>
main.js,路由的重定向,就會在頁面一加載的時候,就會將 home 組件顯示出來,由於重定向指向了 home 組件,redirect 的指向與 path 的必須一致。children 裏面是子路由,固然子路由裏面還能夠繼續嵌套子路由。
import Vue from 'vue' import VueRouter from 'vue-router' Vue.use(VueRouter) //引入兩個組件 import home from "./home.vue" import game from "./game.vue" //定義路由 const routes = [ { path: "/", redirect: "/home" },//重定向,指向了home組件 { path: "/home", component: home, children: [ { path: "/home/game", component: game } ] } ] //建立路由實例 const router = new VueRouter({routes}) new Vue({ el: '#app', data: { }, methods: { }, router })
home.vue,點擊顯示就會將子路由顯示在出來,子路由的出口必須在父路由裏面,不然子路由沒法顯示。
webpack 中提供了 require.ensure()來實現按需加載。之前引入路由是經過 import 這樣的方式引入,改成 const 定義的方式進行引入。
不進行頁面按需加載引入方式:
import home from '../../common/home.vue'
進行頁面按需加載的引入方式
const home = r => require.ensure( [], () => r (require('../../common/home.vue')))
vue 框架中狀態管理。在 main.js 引入 store,注入。新建了一個目錄 store,….. export 。場景有:單頁應用中,組件之間的狀態。音樂播放、登陸狀態、加入購物車
// 新建 store.js import vue from 'vue' import vuex form 'vuex' vue.use(vuex) export default new vuex.store({ //...code }) //main.js import store from './store' ...
有 5 種,分別是 state、getter、mutation、action、module
若是請求來的數據不是要被其餘組件公用,僅僅在請求的組件內使用,就不須要放入 vuex 的 state 裏
若是被其餘地方複用,請將請求放入 action 裏,方便複用,幷包裝成 promise 返回
vuex 僅僅是做爲 vue 的一個插件而存在,不像 Redux,MobX 等庫能夠應用於全部框架,vuex 只能使用在 vue 上,很大的程度是由於其高度依賴於 vue 的 computed 依賴檢測系統以及其插件系統,
vuex 總體思想誕生於 flux,可其的實現方式完徹底全的使用了 vue 自身的響應式設計,依賴監聽、依賴收集都屬於 vue 對對象 Property set get 方法的代理劫持。最後一句話結束 vuex 工做原理,vuex 中的 store 本質就是沒有 template 的隱藏着的 vue 組件;
Vue.use(Vuex) 方法執行的是 install 方法,它實現了 Vue 實例對象的 init 方法封裝和注入,使傳入的 store 對象被設置到 Vue 上下文環境的store中。所以在VueComponent任意地方都可以經過this.store 訪問到該 store。
在 store 構造方法中有 makeLocalContext 方法,全部 module 都會有一個 local context,根據配置時的 path 進行匹配。因此執行如 dispatch('submitOrder', payload)這類 action 時,默認的拿到都是 module 的 local state,若是要訪問最外層或者是其餘 module 的 state,只能從 rootState 按照 path 路徑逐步進行訪問。
store 初始化時,全部配置的 action 和 mutation 以及 getters 均被封裝過。在執行如 dispatch('submitOrder', payload)的時候,actions 中 type 爲 submitOrder 的全部處理方法都是被封裝後的,其第一個參數爲當前的 store 對象,因此可以獲取到 { dispatch, commit, state, rootState } 等數據。
Vuex 中修改 state 的惟一渠道就是執行 commit('xx', payload) 方法,其底層經過執行 this._withCommit(fn) 設置_committing 標誌變量爲 true,而後才能修改 state,修改完畢還須要還原_committing 變量。外部修改雖然可以直接修改 state,可是並無修改_committing 標誌位,因此只要 watch 一下 state,state change 時判斷是否_committing 值爲 true,便可判斷修改的合法性。
devtoolPlugin 中提供了此功能。由於 dev 模式下全部的 state change 都會被記錄下來,'時空穿梭' 功能其實就是將當前的 state 替換爲記錄中某個時刻的 state 狀態,利用 store.replaceState(targetState) 方法將執行 this._vm.state = state 實現。
axios 是請求後臺資源的模塊。 npm i axios -S
若是發送的是跨域請求,需在配置文件中 config/index.js 進行配置
三種