vue學習筆記

starkbl發表於2021-09-09
  • 主要針對筆者在學習中遇到的一些疑問進行記錄

  • 以前一直以為概念是不太重要的東西,所以一直疲於記錄,但是最近發現這些原理的概念還是要在以後的學習和使用中不斷反覆琢磨才能更加靈活的使用,因此會在後期的學習中專門記錄。

Vue 生命週期

圖片描述

Vue2.0  生命週期官網圖

從圖中我們可以看到Vue執行的整個生命週期以及各個階段的動作。

  • beforeCreate

元件例項剛剛被建立,元件屬性計算之前,如data屬性等;

  • created

元件例項建立完成,屬性已繫結,完成了資料的觀測,但是DOM結構還沒有生成(尚未掛載),$el屬性還不存在,不可用;

  • beforeMount

模板編譯/掛載之前

  • mounted

模板編譯/掛載之後,el掛載到例項上後呼叫,業務邏輯一般會在這裡開始;

  • beforeUpdate

元件更新之前

  • updated

元件更新之後

  • activated

元件被啟用時呼叫:for keep-alive

  • deactivate

元件被移除時呼叫:for keep-alive

  • beforeDestory

元件銷燬前呼叫,主要解綁一些使用addEventListener監聽的事件;

  • destoryed

元件銷燬後呼叫

Vue插值

  • 資料的展示使用{{}},括號裡面可以包括data裡面的資料;

  • 如果有的時候想輸出HTML,而不是將資料解釋後的純文字,可以使用v-html ;

  <div id="app">
      <span v-html="link"></span>
  </div><script>
    var app = new Vue{{
        el:"#app",
        data:{
            link:'<a href="#">只是一個連結</a>'
        }
    }}</script>

link的內容會被渲染為一個a標籤,而不是純文字,為了防止XSS攻擊,可以將“<>”進行轉義;

  • 如果想顯示{{}}標籤,而不進行替換,使用v-pre即可跳過這個元素和他的子元素的編譯過程;

<span v-pre>{{hello,I'm 不會被編譯}}</span>
Vue過濾器

  • Vue支援在{{}}插入的值的尾部新增一個管道符'|'來對資料進行過濾,用來格式化文字,如字母全部大寫,貨幣千位或者逗號分隔符,可以自定義過濾的規則,透過給vue例項新增filters來設定;

<template>
    <span>{{date|formatDate}}</span>        </template><script>
    var app = new Vue{{        el:"#app",        data:{            link:'<a href="#">只是一個連結</a>',            date:new Date(),
        },        filters:{            //過濾的方法
            formatDate:function(value){                let date = new Date(value);                var year = date.getFullYear();                var month = date.getMonth()+1;                var day = date.getDate();                return year+"-"+month+"-"+day;
                
            }
        }
    }}</script>

過濾器也可以串聯,而且可以接收引數

<!--  串聯 -->1. {{message |filterA | filterB}}<!--  接收引數 -->2. {{message |filterA('arg1',arg2")}}
內建指令
  1. v-cloak

不需要表示式,它會在Vue例項結束編譯時從繫結的HTML元素上移除,經常和CSS的display:none配合使用;

  • v-cloak是一個解決初始化慢導致頁面閃動的方法;

  1. v-once

定義它的元素或元件只渲染一次,包括元素和元件的所有子節點;首次渲染後,不再隨資料的變化重新渲染,被視為靜態內容。

  1. v-if, v-else-if,v-else

v-else-if要緊跟v-if.v-else要緊跟v-else-if或者v-if

  1. v-show

v-show 的用法和v-if基本一致,不過v-show改變元素的display屬性,v-show表示的值是false時,元素會隱藏;

  • v-show不能再<template>上使用

v-show和v-if的比較:

  1. v-if才是真正的條件渲染,他會根據表示式適當的銷燬或重建元素及繫結元素的事件或子元件,只要當條件第一次為真時才開始編譯;

  2. v-show只是簡單的css屬性切換,無論條件真與否,都會被編譯。v-if更適合條件不經常改變的場景,因為切換開銷相對較大,而v-show適用於頻繁切換條件;

  1. v-for

  • 陣列列表迴圈

<template>                                                     
    <div>                                                      
        <ul v-for="item in books">   
                 <!--  如果需要索引可以使用如下方式 -->        
                  <!--  <ul v-for="(item,index)  in books">    -->                   
            <li>{{item.name}}</li>                             
        </ul>                                                  
    </div>                                                     </template>                                                    
                                                               <script>                                                       
                                                               
    export default{                                            
        data(){                                                
            return{                                            
                books:[                                         
                    {name:'<Vue實戰>'},                          
                    {name:'<Javascript實戰>'},                   
                    {name:'<CSS實戰>'},                   

                ]                                              
            }                                                  
        }                                                      
    }                                                          
      </script>
  • 物件遍歷

<template>                                                     
    <div>                                                      
          <span v-for="(val,key,index) in bookInfo">{{index}}-{{key}}- {{val}}</span>                                             
    </div>                                                     </template>                                                    
                                                               <script>                                                       
                                                               
    export default{                                            
        data(){                                                
            return{                                            
                bookInfo: {  
                       name:'<Vue實戰>',
                       edition:1.2.3,                       author:'wang yan'
                     },                          
                }                                                  
        }                                                      
    }                                                          
      </script>

陣列更新
  • 改變陣列的方法: push(),pop(),shift(),unshift(),splice(),sort(),reverse()

  • 不改變陣列的方法: filter(),concat(),slice()

這些陣列的用途可以參見MDN[https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/filter]

  • 透過索引直接設定項和修改陣列長度都不會觸發檢視更新,可以使用set方法

Vue.set(app.books,3,{ name:'Vue 設定資料'})

Prop
  • slot

    父元件模板的所有東西都會在父級作用域內編譯;子元件模板的所有東西都會在子級作用域內編譯

  • keep-alive

要求被切換到的元件都有自己的名字,不論是透過元件的name選項還是區域性/全域性註冊;

Prop

include:字串或者正規表示式,只有匹配的元件會被快取
exclude:字串或者正規表示式,任何匹配的元件都不會被快取

用法:

  • 包裹動態元件時,會快取不活動的元件例項,而不是銷燬它們。和 transition相似,keep-alive是一個抽象元件:它自身不會渲染一個 DOM 元素,也不會出現在父元件鏈中。

  • is特性:

Vuex
  • action 提交的是 mutation,而不是直接變更狀態。

  • action 可以包含任意非同步操作。

  • action 透過 store.dispatch 方法觸發。

Vue Router
  • this.$route.query 路由查詢字串

  • this.$route.hash  路由的hash值

  • this.$route.params 路由的的引數

  • router.push({ name: 'user', params: { userId }}) == router.push({ path: /user/${userId} })

  • 使用props將元件和路由解耦

    const User = {
        props: ['id'],
        template: '<div>User {{ id }}</div>'
    }    const router = new VueRouter({
        routes: [
            { 
                path: '/user/:id', 
                component: User, 
                props: true 
            },            // 對於包含命名檢視的路由,你必須分別為每個命名檢視新增 `props` 選項:
            {
                path: '/user/:id',
                components: { default: User, sidebar: Sidebar },
                props: { default: true, sidebar: false }
            }   
        ]
    })
  • History模式

正常情況下都需要後端配合著使用

  • node js 使用的是connect-history-api-fallback

導航守衛
  • router.beforeEach 註冊一個全域性前置守衛

router.beforeEach((to,from,next)=>{    //...   })

1.next:Function 一定要透過呼叫該方法來resolve這個鉤子。執行結果依賴next方法的呼叫引數;

2.next()進行管道中的下一個鉤子。如果全部鉤子執行完了,則導航的狀態就是confirmed;

3.next(false)中斷當前的導航。如果瀏覽器的URL改變了,那麼URL地址會重置到from路由對應的地址;

4.next('/') 或者 next({ path: '/' }): 跳轉到一個不同的地址。當前的導航被中斷,然後進行一個
新的導航。你可以向 next傳遞任意位置物件,且允許設定諸如 replace: true、name: 'home' 之類的
選項以及任何用在 router-link 的 to prop 或 router.push 中的選項。

5.next(error): 如果傳入 next 的引數是一個 Error 例項,則導航會被終止且該錯誤會被傳
遞給 router.onError() 註冊過的回撥。

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

  • router.beforeResolve 註冊一個全域性守衛,這和 router.beforeEach 類似,區別是在導航被確認之前,同時在所有元件內守衛和非同步路由元件被解析之後,解析守衛就被呼叫

  • 全域性後置鉤子:這些鉤子不會接受next函式也不會改變導航本身

  • 路由獨享的守衛 beforeEnter

  • 元件內的守衛:
    beforeRouteEnter(to,from,next)

在渲染該元件的對應路由被confirm前呼叫,不能訪問元件例項this,因為當守衛執行前,元件例項還沒被建立

  • beforeRouteUpdate (to,from,next)

在當前路由改變,但是該元件被複用時呼叫,可以訪問元件例項this,

eg: 舉例來說,對於一個帶有動態引數的路徑 /foo/:id,在 /foo/1 和 /foo/2 之間跳轉的時候,
由於會渲染同樣的 Foo 元件,因此元件例項會被複用。而這個鉤子就會在這個情況下被呼叫。

  • beforeRouteLeave(to,from,next)

導航離開該元件的對應路由時呼叫,可以訪問元件例項this

完整的導航解析流程
  1. 導航被觸發。

  1. 在失活的元件裡呼叫離開守衛。

  2. 呼叫全域性的 beforeEach 守衛。

  3. 在重用的元件裡呼叫 beforeRouteUpdate 守衛 (2.2+)。

  4. 在路由配置裡呼叫 beforeEnter。

  5. 解析非同步路由元件。

  6. 在被啟用的元件裡呼叫 beforeRouteEnter。

  7. 呼叫全域性的 beforeResolve 守衛 (2.5+)。

  8. 導航被確認。

  9. 呼叫全域性的 afterEach 鉤子。

  10. 觸發 DOM 更新。

  11. 用建立好的例項呼叫 beforeRouteEnter 守衛中傳給 next 的回撥函式。

路由元資訊
  • 常常被用來驗證登入許可權以及設定頁面的title

const router = new VueRouter({
  routes: [
    {
      path: '/foo',
      component: Foo,
      children: [
        {
          path: 'bar',
          component: Bar,          // a meta field
          meta: { 
            requiresAuth: true,
            title:'Bar page'
            
          }
        }
      ]
    }
  ]
})

一個路由匹配到的所有路由記錄會暴露在route物件的route.matched陣列

router.beforeEach((to, from, next) => {  if (to.matched.some(record => record.meta.requiresAuth)) {    // this route requires auth, check if logged in
    // if not, redirect to login page.
    if (!auth.loggedIn()) {
      next({        path: '/login',        query: { redirect: to.fullPath }
      })
    } else {
      next()
    }
  } else {
    next() // 確保一定要呼叫 next()
  }
})
資料獲取
  • 導航完成之後獲取

先完成導航,然後在接下來的元件生命週期鉤子中獲取資料。在資料獲取期間顯示“載入中”之類的指示。

  • 導航完成之前獲取

導航完成前,在路由進入的守衛中獲取資料,在資料獲取成功後執行導航。



作者:yanruoxin
連結:


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/3705/viewspace-2815588/,如需轉載,請註明出處,否則將追究法律責任。

相關文章