vue進階 -- 技巧總結

1、合理利用watch的immediate屬性

例如在組件建立時須要獲取一次數據列表,而後監聽數據的變化,根據數據改變從新獲取列表。一般這麼寫:html

created(){
    this.fetchPostList()
},
    watch: {
        changeValue(){
            this.fetchPostList()
        }
    }

可是上面的這種寫法咱們能夠精簡寫成以下:vue

watch: {
    changeValue:{
        handler: 'fetchPostList',
            immediate: true
    }
}
聲明 immediate:true, 表示建立的時候當即執行一次。

2、利用require.context()進行組件引入和註冊

通常狀況下,組件寫法以下:webpack

import BaseButton from './baseButton'
import BaseIcon from './baseIcon'
import BaseInput from './baseInput'

export default {
    components: {
        BaseButton,
        BaseIcon,
        BaseInput
    }
}
<BaseInput v-model="searchText" @keydown.enter="search" />
<BaseButton @click="search"> <BaseIcon name="search"/></BaseButton>

通常步驟有三步:web

  1. 引入
  2. 註冊組件
  3. 正式使用

這是最多見和通用的寫法。可是若是組件過多,則要引入屢次,註冊屢次。vue-router

咱們能夠藉助一下webpack,使用 require.context() 方法來建立本身的(模塊)上下文,從而實現自動動態require組件。vuex

思路是:在src文件夾下面main.js中,藉助webpack動態地將須要的基礎組件通通打包進來。異步

代碼以下:函數

一些方法解釋: upperFirstcamelCaserequire.context()
import Vue from 'vue'
import upperFirst from 'lodash/upperFirst'
import camelCase from 'lodash/camelCase'

// Require in a base component context
const requireComponent = require.context(
    ‘./components', false, /base-[\w-]+\.vue$/
)

requireComponent.keys().forEach(fileName => {
    // Get component config
    const componentConfig = requireComponent(fileName)

    // Get PascalCase name of component
    const componentName = upperFirst(
        camelCase(fileName.replace(/^\.\//, '').replace(/\.\w+$/, ''))
    )

    // Register component globally
    Vue.component(componentName, componentConfig.default || componentConfig)
})

這樣咱們引入組件只須要第三步就能夠了:post

<BaseInput v-model="searchText" @keydown.enter="search" />
<BaseButton @click="search">
    <BaseIcon name="search" /></BaseButton>

3、精簡vuex的modules引入

對於vuex,咱們輸出store寫法以下:fetch

import auth from './modules/auth'
import posts from './modules/posts'
import comments from './modules/comments'
...

export default new Vuex.Store({
    modules: {
        auth,
        posts,
        comments,
        ...
    }
})

要引入不少modules,而後再註冊到Vuex.Store中。。

精簡的作法也是運用 require.context()讀取文件,代碼以下:

import camelCase from 'lodash/camelCase'
const requireModule = require.context('.', false, /\.js$/)
const modules = {}
requireModule.keys().forEach(fileName => {
    // Don't register this file as a Vuex module
    if (fileName === './index.js') return

    const moduleName = camelCase(
        fileName.replace(/(\.\/|\.js)/g, '')
    )
    modules[moduleName] = {
        namespaced: true,
        ...requireModule(fileName),
    }
})
export default modules

這樣咱們只需以下代碼就能夠了:

import modules from './modules'
export default new Vuex.Store({
    modules
})

4、組件的異步加載(按需加載組件)

在平時的demo中,可能不會碰見這個需求。當頁面不少,組件不少的時候,SPA頁面在首次加載的時候,就會變的很慢。這是由於vue首次加載的時候把可能一開始看不見的組件也一次加載了,這個時候就須要對頁面進行優化,就須要異步組件了。

在路由index.js裏(路徑: src/router/index.js ),經過require方式或者import()方式動態加載組件。像下面這樣:

{
    path: '/home',
    name: 'home',
    component:require('@views/home').default
}

或者

{
    path: '/home',
    name: 'home',
    component:() => import('@views/home')
}

5、經過router :key進行組件刷新

首先默認使用的是Vue-router來實現路由的控制。

假設如今在寫一個網站,需求是從 /post/a 跳轉到 /post/b 。而後咱們就會發現,頁面跳轉後數據居然沒更新?!緣由是vue-router 「智能地」 發現這是同一個組件,而後它就決定要複用這個組件,因此在created函數裏寫的方法所有沒有執行。

一般的解決方案是監聽$route的變化來初始化數據,以下:

data() {
    return {
        loading: false,
        error: null,
        post: null
    }
}, 
watch: {
   '$route': {
       handler: 'resetData',
       immediate: true
    }
},
methods: {
    resetData() {
       this.loading = false
       this.error = null
       this.post = null
       this.getPost(this.$route.params.id)
     },
    getPost(id){}
}

問題是解決了,可是這樣的處理方式不夠優雅。咱們但願代碼這樣寫:

data() {
    return {
        loading: false,
        error: null,
        post: null
    }
},
created () {
    this.getPost(this.$route.params.id)
},
methods () {
    getPost(postId) {
        ...
    }
}

如何達到這樣的效果:給router-view添加一個惟一的key,這樣只要url變化了,就必定會從新建立這個組件。就避免了vue-rouer由於複用組件致使created函數中的方法不執行的問題。

<router-view :key="$route.fullpath"></router-view>
注: 這個通常應用在子路由裏面,這樣才能夠避免大量重繪,假設App.vue根目錄添加這個屬性,那麼每次點擊改變地址都會重繪!
相關文章
相關標籤/搜索