vue

一、 vue 有多少個(gè)生命周期,每個(gè)作用是什么?

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <title></title>
    <link rel="stylesheet" href="">
    <script src="https://cdn.bootcss.com/vue/2.2.1/vue.min.js"></script>
</head>
<body>
    
    <div id="app">
        <template>
            <div>
              <p>{{ total }}</p>
              <button-counter v-on:increment="incrementTotal"></button-counter>
              <button-counter v-on:increment="incrementTotal"></button-counter>
              <hr>
              <button onclick="vm.$destroy()">此按鈕用來銷毀實(shí)例</button>
            </div>
        </template>
    </div>

    <script>

        Vue.component('button-counter', {
            template: '<button @click="increment">我是按鈕{{ counter }}</button>',
            data: function() {
                return {
                    counter: 0
                }
            },
            methods: {
                increment(){
                    this.counter ++;
                    this.$emit('increment')
                }
            }
        })
        
        var vm = new Vue({
            el: "#app",
            data() {
                return {
                    total: 0
                }
            },
            methods: {
                incrementTotal(){
                    this.total ++;
                }
            },
            // 組件生命周期
            beforeCreate() {   // 在實(shí)例創(chuàng)建之后,在數(shù)據(jù)初始化之前被調(diào)用
                console.log('beforeCreated-1')
            },
            created() { // 在數(shù)據(jù)初始化之后被調(diào)用,如果你的頁面進(jìn)來的時(shí)候就調(diào)用接口,那么created是第一選擇
                console.log('created-2') 
            },
            beforeMount() { // 在數(shù)據(jù)渲染之前被調(diào)用
                console.log('beforeMount-3') 
            },
            mounted() { // 實(shí)例創(chuàng)建完成、數(shù)據(jù)初始化、渲染頁面數(shù)據(jù)后,才被調(diào)用
                console.log('mounted-4') 
            },
            beforeUpdate() { // 在數(shù)據(jù)改變時(shí)被調(diào)用
                console.log('beforeUpdate-5')
            },
            updated() { // 數(shù)據(jù)被更新之后
                console.log('updated-6')
            },

            //keep-alive生命周期有兩個(gè) (activated , deactivated)
            activated() { // keep-alive 組件激活時(shí)調(diào)用,也就是說在路由切換時(shí)被調(diào)用,注意要配合keep-alive使用才會(huì)被調(diào)用, <keep-alive>  
                // 可以看下別人寫的 https://www.cnblogs.com/sysuhanyf/p/7454530.html
                
            },
            deactivated(){// keep-alive 組件停用時(shí)調(diào)用,也可以理解成在路由切換的會(huì)自動(dòng)停用組件, 

                // 可以看下別人寫的 https://www.cnblogs.com/sysuhanyf/p/7454530.html
              
            },
            beforeDestroy() { // 實(shí)例銷毀前被調(diào)用
                console.log('beroreDestroy-9')
            },
            destroyed() { //實(shí)例銷毀后被調(diào)用
                console.log('destroyed-10')
            }
        })

    </script>

</body>
</html>

|

二、 vue路由有多少個(gè)鉤子,每個(gè)作用是什么?

1. beforeEach 全局路由鉤子,只要頁面路由改變就會(huì)執(zhí)行,鉤子有是三個(gè)參數(shù) to 、from 、next
export default {
    name: 'app',
    data() {
      return {
      }
    },
    mounted() {
      this.$router.beforeEach((to, from, next) => {
        console.log(to, from)
        next()
      })
    }
  }

to 要去哪個(gè)頁面 返回信息如下圖
from 是我從哪個(gè)頁面過來的,和to參數(shù)格式一樣,只不過path不同
next 是一個(gè)執(zhí)行的參數(shù) 必須要加上next(),不然路由不會(huì)跳轉(zhuǎn)

image.png
2. afterEach 全局路由鉤子 有兩個(gè)參數(shù) to 、from

這兩個(gè)參數(shù)和beforeEach相同,唯一的區(qū)別是afterEach鉤子是路由跳轉(zhuǎn)之后才被執(zhí)行

this.$router.afterEach((to, from) => {
      console.log(to, from)
})
3. beforeEnter 這個(gè)一般情況下用不到,在路由頁面配置 beforeEnter,在進(jìn)入這個(gè)路由后執(zhí)行
routes: [{
      path: '/Hello',
      name: 'Hello',
      component: Hello
    },
    {
      path: '/index',
      component: index,
      children: [
        { path: 'world', component: world ,
          beforeEnter: (to, from, next) => {
            // 執(zhí)行邏輯
            next()
          }
        },
        { path: 'world_childen', component: world_childen },
      ]
    }
  ]
4. beforeRouteEnter 組件私有鉤子

組件私有的鉤子,組件被調(diào)用事執(zhí)行,在beforeRouteEnter這個(gè)鉤子里面沒有this
因?yàn)樵谶@個(gè)鉤子執(zhí)行的時(shí)候組件的實(shí)例還沒有創(chuàng)建,所以打印this是undefined
在next里面使用vm.name可以代替 this。
to 返回的信息是當(dāng)前頁面路由信息
from 返回的是從哪里過來的,和beforeEach 有點(diǎn)差異

export default {
        data() {
          return {
             name: 'web_珂珂'
          }
        },
        beforeRouteEnter(to, from, next){   
          console.log(this) // undefined
          next(vm => {
            console.log(vm.name) // web_珂珂
          });
        }
}
5. beforeRouteUpdate 組件私有鉤子,只有在組件被多次調(diào)用并且路由有變的的時(shí)候才會(huì)執(zhí)行

比如: A頁面調(diào)用了當(dāng)前組件,B頁面也調(diào)用了當(dāng)前組件,但是他們的路由變化了,beforeRouteUpdate就會(huì)被執(zhí)行
beforeRouteUpdate this是指向?qū)嵗?br> html:

// 類似于這樣 兩個(gè)router-link都調(diào)用world組件,但是參數(shù)不同,就會(huì)被執(zhí)行
<router-link to="/index/world">導(dǎo)航二</router-link>
<router-link to="/index/world?name=web_keke">測(cè)試beforeRouteUpdate鉤子</router-link>
<script>
    export default {
        data() {
          return {
             name: 'web_珂珂'
          }
        },
        beforeRouteUpdate(to, from, next){
            console.log(this.name) // web_珂珂
            console.log(to,from)
            next()
        }
    }
</script>
6. beforeRouteLeave 從當(dāng)前組件的跳轉(zhuǎn)別的路由頁面執(zhí)行,就是離開的時(shí)候執(zhí)行
    export default {
        data() {
        },
        beforeRouteLeave (to, from, next) {
            console.log(to, from)
            next()
        }
    }

三、computed計(jì)算屬性與methods方法的區(qū)別?

computed 在數(shù)據(jù)沒有更新的情況下,computed緩存數(shù)據(jù),下次進(jìn)來還是讀取緩存的數(shù)據(jù)。
而methods方法會(huì)每次都會(huì)執(zhí)行,不會(huì)走緩存,舉個(gè)例子:

<template>
    <div>
        <!--  computed  -->
        我是computed 只要數(shù)據(jù)沒有更新,我會(huì)讀取緩存,不會(huì)重新計(jì)算
        <p>
            數(shù)量:{{ computedCount }}
        </p>
        <p>
            數(shù)量:{{ computedCount }}
        </p>
        <p>
            數(shù)量:{{ computedCount }}
        </p>
        <hr>
        
        <!--  方法  -->
        我是methods方法,每次都會(huì)重新調(diào)用methodsCount()函數(shù)
        <p>
            數(shù)量:{{ methodsCount() }}
        </p>
        <p>
            數(shù)量:{{ methodsCount() }}
        </p>
        

    </div>

</template>

<script>
export default {
    data() {
      return {
         count: 1
      }
    },
    // 計(jì)算
    computed: {
        computedCount(){
            return this.count + 100
        }
    },
    // 方法
    methods: {
        methodsCount(){
            return this.count + 100
        }
    }
}
</script>

image.png

四、自定義指令 directive

vue 有他們自己內(nèi)置的指令如v-model, 還可以自己定義一些指令(directive),自定義指令可以寫成局部的,也可以寫成全局的,下面有個(gè)回車搜索的案例(這個(gè)還是我之前的一個(gè)朋友教我的-_-"),用于多個(gè)頁面搜索框輸入直接回車就可以調(diào)用方法

鉤子函數(shù)鉤子函數(shù)參數(shù)

1. 全局指令

全局的寫法我在main.js里面寫的,在任何組件都可以用

Vue.directive('keyup-enter',{
    inserted(el, binding) {
        let $inputs = el.getElementsByTagName('input')
        Array.from($inputs).forEach( $item => {
            $item.addEventListener('keydown', event => {
                let e = event || window.event
                if (e.keyCode === 13) {
                  if (binding.value) {
                    setTimeout(() => {
                      binding.value()
                    }, 100)
                  }
                }
            })
        })
    }
})

然后在組件中調(diào)用keyup-enter指令,
把指令綁定到最外層的div上面 如,然后在輸入框輸入文本按回車

<template>
 <!-- 這里綁定指令 v-keyup-enter -->  
<div v-keyup-enter="getName"> 
        名稱:
        <input type="text" v-model="name">
        年齡:
        <input type="text" v-model="age">
    </div>
</template>

<script>

    export default {
      data() {
        return {
          name: '珂珂',
          age: '26'
        }
      },
      methods: {
        getName() {
            console.log(this.name) // 珂珂
            console.log(this.age) // 26
        }   
      }
    }

</script>
image.png

2. 局部指令

比如有個(gè)需求,要求頁面一進(jìn)來,就讓某一樣文本,添加一個(gè)顏色,并且讓這個(gè)文字翻轉(zhuǎn),或者只有第一次需要添加顏色,這中情況使用指令是最合適的
v-reverse 就是自定義的指令名稱

<template>
    <div>
        <p v-reverse>{{ message }}</p>
    </div>
</template>

<script>

    export default {
      data() {
        return {
          message: '"-_-我是菜鳥',
        }
      },
      directives: {
        reverse: {
            inserted(el) {
                el.innerHTML = el.innerHTML.split('').reverse().join(''); // 鳥菜是我-_-"
                el.style.color = 'red';
                console.log(el) // <p style="color: red;">鳥菜是我-_-"</p>
            }
          }
        }
    }
</script>

image.png

五、 keep-alive 緩存

詳解 keep-alive

keep-alive有兩個(gè)生命周期 activated和deactivated,activated是組件被緩存的時(shí)候執(zhí)行,deactivated是離開緩存組件的時(shí)候執(zhí)行。

keep-alive屬性 如: <keep-alive include="Hello"> 緩存Hello組件
include - 字符串或正則表達(dá)式。只有名稱匹配的組件會(huì)被緩存。
exclude - 字符串或正則表達(dá)式。任何名稱匹配的組件都不會(huì)被緩存。
max - 數(shù)字。最多可以緩存多少組件實(shí)例

在Hello中切換tab到內(nèi)容二選項(xiàng),然后在跳轉(zhuǎn)的world組件后,在切回到Hello組件中,你會(huì)發(fā)現(xiàn)還是剛才的內(nèi)容二的文本,他并沒有顯示初始化的內(nèi)容一的文本,這樣就實(shí)現(xiàn)了緩存,另外keep-alive屬性include 設(shè)置的名稱是你要緩存的組件中寫的那個(gè)name名稱,如果名字不統(tǒng)一,緩存則無效。
如果想緩存多個(gè)組件,可以以逗號(hào)分隔,如: <keep-alive include="Hello, world">

緩存方式一、

app.vue

<template>
  <div id="app">
    <div class="nav">
      <ul>
        <router-link 
          v-for="(item, index) in arr" 
          :key="index" 
          :to="item.routerPath">
            {{item.routerName}}
            <br><br><br>
        </router-link>
      </ul>
    </div>
    <div class="view-box">
       // 這里緩存組件Hello
      <keep-alive include="Hello">
        <router-view></router-view>
      </keep-alive>
    </div>
  </div>
</template>
<script>
  export default {
    name: 'app',
    data() {
      return {
       active: '/Hello',
       arr: [
          {
            routerName: '我是hello組件',
            routerPath: '/Hello'
          },
          {
            routerName: '我是world組件',
            routerPath: '/world'
          }
        ]
      }
    }
  }

</script>

Hello.vue

<template>
  <div class="hello">
        <ul>
        <li v-for="(item, index) in navArr" :key="index">
          <button 
            @click="tab(item.tab)" 
            :class="{ active : tabShow == item.tab }"
            >
            {{ item.name }}
          </button>
        </li>
      </ul>
      <div class="box">
        <div :is="tabShow"></div>
      </div>
  </div>
</template>

<script>

  let A = {
    template:`<h3>我是內(nèi)容一的信息11111</h3>`
  }
  let B = {
    template:`<h3>我是內(nèi)容二的信息22222222222</h3>`
  }

  export default {
    name:'Hello', // 這個(gè)name要和 keep-alive中include 設(shè)置的名字統(tǒng)一,否則無效
    data () {
      return {
        tabShow:'A',
        navArr: [
          {
            name: '內(nèi)容一',
            tab: 'A'
          },
          {
            name: '內(nèi)容二',
            tab: 'B'
          }
        ]
      }
    },
    components: {
        'A': A,
        'B': B
    },
    methods: {
        tab(currentShowTab){
            this.tabShow = currentShowTab;
        }
    },
    activated(){ // 組件被緩存的時(shí)候執(zhí)行
      console.log('組件被緩存的時(shí)候執(zhí)行')
    },
    deactivated(){ // 離開緩存組件的時(shí)候執(zhí)行
      console.log('離開緩存組件的時(shí)候執(zhí)行')
    }
  }

</script>

緩存方式二、

配合router路由去動(dòng)態(tài)緩存, 這種方式 keep-alive 就是根據(jù)路由配置里面來實(shí)現(xiàn)的
index.js (router下的index.js文件)

import Vue from 'vue'
import Router from 'vue-router'
import Hello from '../components/Hello'
import index from '../components/index'
import world from '../components/world'

Vue.use(Router)

export default new Router({
  routes: [{
      path: '/Hello',
      name: 'Hello',
      component: Hello,
      meta: {
        keepAlive: true //  設(shè)置為緩存
      }
    },
    {
      path: '/world',
      name: 'world',
      component: world,
      meta:{
         keepAlive: false  //設(shè)置為不緩存
      } 
    }
  ]
})

然后修改app.vue

<template>
  <div id="app">
    <div class="nav">
      <ul>
        <router-link v-for="(item, index) in arr" :key="index" :to="item.routerPath">
          {{item.routerName}}
          <br><br><br>
        </router-link>
      </ul>
    </div>
    <div class="view-box">
      // 修改為根據(jù)路由配置來實(shí)現(xiàn)緩存某些頁面
      <keep-alive>
        <router-view v-if="$route.meta.keepAlive"></router-view>
      </keep-alive>
      <router-view v-if="!$route.meta.keepAlive"></router-view>
    </div>
  </div>
</template>
image.png
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 1. Vue 實(shí)例 1.1 創(chuàng)建一個(gè)Vue實(shí)例 一個(gè) Vue 應(yīng)用由一個(gè)通過 new Vue 創(chuàng)建的根 Vue 實(shí)...
    王童孟閱讀 1,097評(píng)論 0 2
  • PS:轉(zhuǎn)載請(qǐng)注明出處作者: TigerChain地址: http://www.itdecent.cn/p/218...
    TigerChain閱讀 26,535評(píng)論 5 70
  • 前言 記錄平時(shí)學(xué)到的知識(shí),標(biāo)題寫的大氣一點(diǎn),也算是給自己一點(diǎn)鼓勵(lì),希望在技術(shù)這條路可以遠(yuǎn)走越遠(yuǎn),路越走越寬~ 文中...
    徐國軍_plus閱讀 1,758評(píng)論 3 28
  • Vue 實(shí)例 屬性和方法 每個(gè) Vue 實(shí)例都會(huì)代理其 data 對(duì)象里所有的屬性:var data = { a:...
    云之外閱讀 2,389評(píng)論 0 6
  • 主要還是自己看的,所有內(nèi)容來自官方文檔。 介紹 Vue.js 是什么 Vue (讀音 /vju?/,類似于 vie...
    Leonzai閱讀 3,556評(píng)論 0 25

友情鏈接更多精彩內(nèi)容