vue知識點整理(轉發)

rosenWang發表於2018-12-06

一.MVVM

MVVMModel-View-ViewModel 的縮寫。

  • Model代表資料模型,也可以在Model中定義資料修改和操作的業務邏輯。
  • View 代表UI 元件,它負責將資料模型轉化成UI 展現出來。
  • ViewModel 監聽模型資料的改變和控制檢視行為、處理使用者互動,簡單理解就是一個同步View 和 Model的物件,連線Model和View。

在MVVM架構下,View 和 Model 之間並沒有直接的聯絡,而是通過ViewModel進行互動,Model 和 ViewModel 之間的互動是雙向的, 因此View 資料的變化會同步到Model中,而Model 資料的變化也會立即反應到View 上。

ViewModel 通過雙向資料繫結把 View 層和 Model 層連線了起來,而View 和 Model 之間的同步工作完全是自動的,無需人為干涉,因此開發者只需關注業務邏輯,不需要手動操作DOM, 不需要關注資料狀態的同步問題,複雜的資料狀態維護完全由 MVVM 來統一管理。

vue知識點整理(轉發)

注意, MVVM模型中, Model和View是不會直接連線的,而ViewModel則會以雙向連線的形式連線Model和View。

二.Vue和React的區別

Vue的優點

  1. 輕量級的框架
  2. 雙向資料繫結
  3. 指令
  4. 外掛化

與React的對比

  • 兩者具有許多的相似之處

    • 使用 Virtual DOM
    • 提供了響應式 (Reactive) 和元件化 (Composable) 的檢視元件。
    • 將注意力集中保持在核心庫,而將其他功能如路由和全域性狀態管理交給相關的庫。
  • Vue與React的不同之處

    • 元件的重渲染 React中元件的重渲染需要通過shouldComponentUpdate來避免不必要的子元件的重渲染,而Vue中元件的依賴是在渲染過程中自動追蹤的,所以系統能精確知曉哪個元件確實需要被重渲染。
    • JSX vs Template 在 React 中,所有的元件的渲染功能都依靠 JSX。JSX 是使用 XML 語法編寫 JavaScript 的一種語法糖。Vue預設推薦使用Vue模板(更適用於表現類),但Vue也支援JSX。
    • 元件作用域的CSS 在React中,CSS 作用域是通過 CSS-in-JS 的方案實現的 (比如 styled-components、glamorous 和 emotion),而Vue則有更好的解決方案,如下:

      <style scoped>
        @media (min-width: 250px) {
          .list-container:hover {
            background: orange;
          }
        }
      </style>複製程式碼

      這個可選 scoped 屬性會自動新增一個唯一的屬性 (比如 data-v-21e5b78) 為元件內 CSS 指定作用域,編譯的時候 .list-container:hover 會被編譯成類似 .list-container[data-v-21e5b78]:hover,這樣就可以控制CSS只在這個元件內生效。

三.VUE知識點

1. Vue的生命週期

  1. beforeCreate
  2. created
  3. beforeMount
  4. mounted
  5. beforeUpdated
  6. updated
  7. beforeDestroy
  8. destroyed

大致過程就是

  • 資料初始化(1~2)
    完成資料觀測、屬性和方法的運算載入,event/wather時間回撥。
  • dom掛載階段(3~4)
    el被新建立的vm.$el替換並掛載到例項上去,之後呼叫鉤子函式。
  • 資料更新階段(5~6)
    資料更新,虛擬dom重渲染
  • 元件解除安裝階段(7~8)
    銷燬例項及子例項

2. Vue實現資料雙向繫結的原理

Vue實現這種資料雙向繫結的效果,需要三大模組:

  1. Observer:能夠對資料物件的所有屬性進行監聽,如有變動可拿到最新值並通知訂閱者。
  2. Compile:對每個元素節點的指令進行掃描和解析,根據指令模板替換資料,以及繫結相應的更新函式
  3. Watcher:作為連線Observer和Compile的橋樑,能夠訂閱並收到每個屬性變動的通知,執行指令繫結的相應回撥函式,從而更新檢視

Observer

Observer的核心是通過Obeject.defineProperty()來監聽資料的變動,這個函式內部可以定義settergetter,每當資料發生變化,就會觸發setter。這時候Observer就要通知訂閱者,訂閱者就是Watcher

Watcher

Watcher訂閱者作為ObserverCompile之間通訊的橋樑,主要做的事情是:

  1. 在自身例項化時往屬性訂閱器(dep)裡面新增自己
  2. 自身必須有一個update()方法
  3. 待屬性變動dep.notice()通知時,能呼叫自身的update()方法,並觸發Compile中繫結的回撥

Compile

Compile主要做的事情是解析模板指令,將模板中的變數替換成資料,然後初始化渲染頁面檢視,並將每個指令對應的節點繫結更新函式,新增監聽資料的訂閱者,一旦資料有變動,收到通知,更新檢視。

vue資料雙向繫結原理詳解在這裡剖析Vue原理&實現雙向繫結MVVM

3.vue-router

Vue Router 是vue官方推建的路由管理器。它和 Vue.js 的核心深度整合,讓構建單頁面應用變得易如反掌。包含的功能有:

  • 巢狀的路由/檢視表
  • 模組化的、基於元件的路由配置
  • 路由引數、查詢、萬用字元
  • 基於 Vue.js 過渡系統的檢視過渡效果
  • 細粒度的導航控制
  • 帶有自動啟用的 CSS class 的連結
  • HTML5 歷史模式或 hash 模式,在 IE9 中自動降級
  • 自定義的滾動條行為

(1)動態路由匹配

一個“路徑引數”使用冒號 : 標記。當匹配到一個路由時,引數值會被設定到 this.$route.params,可以在每個元件內使用。

const router = new VueRouter({
  routes: [
    // 動態路徑引數 以冒號開頭
    { path: '/user/:id', component: User }
  ]
})複製程式碼

使用$route.params$route.query獲取路由中的引數。

(2)巢狀路由

在專案的開發中常常在一個父路由下新增若干的字路由,也可以在子路由中新增後代路由,即路由的巢狀。

const router = new VueRouter({
  routes: [
    { path: '/user/:id', component: User,
      children: [
        {
          path: 'profile',
          component: UserProfile
        },
        {
          path: 'posts',
          component: UserPosts
        }
      ]
    }
  ]
})複製程式碼

要注意,以 / 開頭的巢狀路徑會被當作根路徑。 這讓你充分的使用巢狀元件而無須設定巢狀的路徑。

(3).程式設計式導航(跳轉)

vue知識點整理(轉發)

vue知識點整理(轉發)

router-link:   路由標籤實現前端路由的跳轉,本質上是$router.push(),通過tag渲染成目標標籤,to轉到目的路由。

<router-link tag='div' to='./user'></router-link>複製程式碼

router.push: 想要導航到不同的 URL,則使用 router.push 方法。這個方法會向 history 棧新增一個新的記錄,所以,當使用者點選瀏覽器後退按鈕時,則回到之前的 URL。

router.replace: router.push 很像,唯一的不同就是,它不會向 history 新增新記錄,而是跟它的方法名一樣 —— 替換掉當前的 history 記錄。

router.go(n): 這個方法的引數是一個整數,意思是在 history 記錄中向前或者後退多少步,類似 window.history.go(n)

(4)路由重定向和路由模式

重定向:通過redirect屬性,將目的路由指向對應路由

路由模式:hash路由和history路由(通過設定mode的值來改變路由模式)

vue-router 預設 hash 模式 —— 使用 URL 的 hash 來模擬一個完整的 URL,於是當 URL 改變時,頁面不會重新載入,但是會在URL後新增’#‘號,不是很美觀。

http://www.rosenwang.xyz:8080/#/home    ----hash
複製程式碼

history路由則顯得更加符合要求,但是需要後端的支援,如何直接使用,上線後訪問會出現404.

http://www.rosenwang.xyz:8080/home       -history複製程式碼

(5)導航守衛

全域性守衛:beforeEach,afterEach

路由獨享守衛:beforeEnter,afterEnter

元件內守衛:beforeRouterEnter,beforeRouterUpdate,beforeRouterLeave

每個守衛方法接收三個引數:

  • to: Route: 即將要進入的目標 路由物件

  • from: Route: 當前導航正要離開的路由

  • next: Function: 一定要呼叫該方法來 resolve 這個鉤子。執行效果依賴 next 方法的呼叫引數。

確保要呼叫 next 方法,否則鉤子就不會被 resolved。

(6)路由懶載入

const Foo = () => import(/* webpackChunkName: "group-foo" */ './Foo.vue')
const Bar = () => import(/* webpackChunkName: "group-foo" */ './Bar.vue')
const Baz = () => import(/* webpackChunkName: "group-foo" */ './Baz.vue')複製程式碼

4.父子元件

(1)父元件向子元件傳參

父元件通過標籤上定義傳值,子元件通過props方法接受資料

<parent>
<child :child-msg="msg"></child>  //這裡必須要用 - 代替駝峰
</parent>
  props: {
    childMsg: {
        type: Array,    //傳入的型別
        default: [] //預設值
    }
  }複製程式碼

(2)子元件向父元件傳遞資料

子元件通過$emit方法傳遞引數,父元件通過v-on(簡寫為@)來監聽DOM事件,並在觸發時接收資料執行js函式。

   //子元件   
   testClick() {
        this.$emit('test','123'); 
        //$emit(even,value)even 是一個函式,value 是傳給父元件的值 
    }

  //父元件
<div>
    <child @test="change" :msg="msg"></child>  //監聽子元件觸發的test事件,然後呼叫change方法
</div>
methods: {
    change(val) {
        this.msg = val;  // val: 123
    }
}複製程式碼

(3)非父子元件資料傳遞

通過vuex統一實現狀態管理,實現了非父子元件內的資料通訊

5. Vue響應資料變化的幾種做法

  1. methods: 每次獲取都會重新計算求值
  2. computed(計算屬性,有快取): 基於資料依賴進行快取,只有當資料變化時,才會重新求值。(計算屬性只有 getter,可以在需要的時候自己設定 setter)。computed 擅長處理的情景:一個資料受多個資料影響。
  3. watch: 當需要在資料變化時執行非同步操作或者消耗較大的操作時,比較有效。watch 擅長處理的情景:一個資料影響多個資料。
  4. v-model: 基於資料雙向繫結(對於 v-for 迴圈列表中的項,需要使用鍵值)

6. Vue的條件渲染

v-if 是真正的條件渲染,它會適當地銷燬和重建DOM達到讓元素顯示和隱藏的效果。

 v-show 通過修改元素的display的CSS屬性讓其顯示或者隱藏,元素始終會被渲染並保留在DOM中。

v-if vs v-show

一般來說,v-if 有更高的切換開銷,而 v-show 有更高的初始渲染開銷。因此,如果需要非常頻繁地切換,則使用 v-show較好;如果在執行時條件很少改變,則使用 v-if 較好。


相關文章