Vue的一些開發(fā)技巧

1.require.context()

1.場景:如頁面需要導入多個組件,原始寫法:

import titleCom from '@/components/home/titleCom'
import bannerCom from '@/components/home/bannerCom'
import cellCom from '@/components/home/cellCom'
components:{titleCom,bannerCom,cellCom}

2.這樣就寫了大量重復的代碼,利用 require.context 可以寫成

const path = require('path')
const files = require.context('@/components/home', false, /\.vue$/)
const modules = {}
files.keys().forEach(key => {
  const name = path.basename(key, '.vue')
  modules[name] = files(key).default || files(key)
})
components:modules

3.API 方法

實際上是 webpack 的方法,vue 工程一般基于 webpack,所以可以使用
require.context(directory,useSubdirectories,regExp)
接收三個參數(shù):
directory:說明需要檢索的目錄
useSubdirectories:是否檢索子目錄
regExp: 匹配文件的正則表達式,一般是文件名

4.render 函數(shù)

1.場景:有些代碼在 template 里面寫會重復很多,所以這個時候 render 函數(shù)就有作用啦

// 初級
<template>
  <div>
    <div v-if="level === 1"> <slot></slot> </div>
    <p v-else-if="level === 2"> <slot></slot> </p>
    <h1 v-else-if="level === 3"> <slot></slot> </h1>
    <h2 v-else-if="level === 4"> <slot></slot> </h2>
    <strong v-else-if="level === 5"> <slot></slot> </stong>
    <textarea v-else-if="level === 6"> <slot></slot> </textarea>
  </div>
</template>
// 優(yōu)化版,利用 render 函數(shù)減小了代碼重復率
<template>
  <div>
    <child :level="level">Hello world!</child>
  </div>
</template>
<script type='text/javascript'>
  import Vue from 'vue'
  Vue.component('child', {
    render(h) {
      const tag = ['div', 'p', 'strong', 'h1', 'h2', 'textarea'][this.level-1]
      return h(tag, this.$slots.default)
    },
    props: {
      level: {  type: Number,  required: true  } 
    }
  })   
  export default {
    name: 'hehe',
    data() { return { level: 3 } }
  }
</script>

2.render 和 template 的對比
前者適合復雜邏輯,后者適合邏輯簡單;
后者屬于聲明是渲染炭序,前者屬于自定Render函數(shù);
前者的性能較高,后者性能較低端壳。

5.異步組件

場景:項目過大就會導致加載緩慢,所以異步組件實現(xiàn)按需加載就是必須要做的事啦
1.異步注冊組件

// 工廠函數(shù)執(zhí)行 resolve 回調
Vue.component('async-webpack-example', function (resolve) {
  // 這個特殊的 `require` 語法將會告訴 webpack
  // 自動將你的構建代碼切割成多個包, 這些包
  // 會通過 Ajax 請求加載
  require(['./my-async-component'], resolve)
})

// 工廠函數(shù)返回 Promise
Vue.component(
  'async-webpack-example',
  // 這個 `import` 函數(shù)會返回一個 `Promise` 對象洲鸠。
  () => import('./my-async-component')
)

// 工廠函數(shù)返回一個配置化組件對象
const AsyncComponent = () => ({
  // 需要加載的組件 (應該是一個 `Promise` 對象)
  component: import('./MyComponent.vue'),
  // 異步組件加載時使用的組件
  loading: LoadingComponent,
  // 加載失敗時使用的組件
  error: ErrorComponent,
  // 展示加載時組件的延時時間达皿。默認值是 200 (毫秒)
  delay: 200,
  // 如果提供了超時時間且組件加載也超時了,
  // 則使用加載失敗時使用的組件。默認值是:`Infinity`
  timeout: 3000
})

異步組件的渲染本質上其實就是執(zhí)行2次或者2次以上的渲染, 先把當前組件渲染為注釋節(jié)點, 當組件加載成功后, 通過 forceRender 執(zhí)行重新渲染田篇√娣希或者是渲染為注釋節(jié)點, 然后再渲染為loading節(jié)點, 在渲染為請求完成的組件

2.路由的按需加載

webpack< 2.4 時
{
  path:'/',
  name:'home',
  components:resolve=>require(['@/components/home'],resolve)
}

webpack> 2.4 時
{
  path:'/',
  name:'home',
  components:()=>import('@/components/home')
}

import()方法由es6提出,import()方法是動態(tài)加載泊柬,返回一個Promise對象舶担,then方法的參數(shù)是加載到的模塊。類似于Node.js的require方法彬呻,主要import()方法是異步加載的衣陶。

6.動態(tài)組件

場景:做一個 tab 切換時就會涉及到組件動態(tài)加載

<component v-bind:is="currentTabComponent"></component>

但是這樣每次組件都會重新加載,會消耗大量性能,所以<keep-alive> 就起到了作用

<keep-alive>
  <component v-bind:is="currentTabComponent"></component>
</keep-alive>

這樣切換效果沒有動畫效果,這個也不用著急,可以利用內置的<transition>

<transition>
<keep-alive>
  <component v-bind:is="currentTabComponent"></component>
</keep-alive>
</transition>

9.components和 Vue.component

// components:局部注冊組件
export default{
  components:{home}
}

// Vue.component:全局注冊組件
Vue.component('home',home)

11.mixins

場景:有些組件有些重復的 js 邏輯,如校驗手機驗證碼,解析時間等,mixins 就可以實現(xiàn)這種混入

const mixin={
    created(){
      this.dealTime()
    },
    methods:{
      dealTime(){
        console.log('這是mixin的dealTime里面的方法');
      }
  }
}

export default{
  mixins:[mixin]
}

16.Vue.directive

場景:官方給我們提供了很多指令,但是我們如果想將文字變成指定的顏色定義成指令使用,這個時候就需要用到Vue.directive

// 全局定義
Vue.directive("change-color",function(el,binding,vnode){
  el.style["color"]= binding.value;
})

// 使用
<template>
<div v-change-color=“color”>{{message}}</div>
</template>
<script>
  export default{
    data(){
      return{
        color:'green'
      }
    }
  }
</script>

22.Vue.config.performance

場景:監(jiān)聽性能

Vue.config.performance = true

只適用于開發(fā)模式和支持 performance.mark API 的瀏覽器上

27.v-once

場景:有些 template 中的靜態(tài) dom 沒有改變,這時就只需要渲染一次,可以降低性能開銷

<span v-once> 這時只需要加載一次的標簽</span>

30.5 Vue.$router

this.$router.push():跳轉到不同的url,但這個方法回向history棧添加一個記錄闸氮,點擊后退會返回到上一個頁面
this.$router.replace():不會有記錄
this.$router.go(n):n可為正數(shù)可為負數(shù)剪况。正數(shù)返回上一個頁面,類似 window.history.go(n)

33.2 transformToRequire

場景:以前在寫 Vue 的時候經常會寫到這樣的代碼:把圖片提前 require 傳給一個變量再傳給組件

// page 代碼
<template>
  <div>
    <avatar :img-src="imgSrc"></avatar>
  </div>
</template>
<script>
  export default {
    created () {
      this.imgSrc = require('./assets/default-avatar.png')
    }
  }
</script>

現(xiàn)在:通過配置 transformToRequire 后,就可以直接配置蒲跨,這樣vue-loader會把對應的屬性自動 require 之后傳給組件

// vue-cli 2.x在vue-loader.conf.js 默認配置是
transformToRequire: {
    video: ['src', 'poster'],
    source: 'src',
    img: 'src',
    image: 'xlink:href'
}

// 配置文件,如果是vue-cli2.x 在vue-loader.conf.js里面修改
  avatar: ['default-src']

// vue-cli 3.x 在vue.config.js
// vue-cli 3.x 將transformToRequire屬性換為了transformAssetUrls
module.exports = {
  pages,
  chainWebpack: config => {
    config
      .module
        .rule('vue')
        .use('vue-loader')
        .loader('vue-loader')
        .tap(options => {
          options.transformAssetUrls = {
            avatar: 'img-src',
          }
        return options;
      });
  }
}

// page 代碼可以簡化為
<template>
  <div>
    <avatar img-src="./assets/default-avatar.png"></avatar>
  </div>
</template>

34.為路徑設置別名

1.場景:在開發(fā)過程中译断,我們經常需要引入各種文件,如圖片或悲、CSS孙咪、JS等,為了避免寫很長的相對路徑(../)巡语,我們可以為不同的目錄配置一個別名

2.vue-cli 2.x 配置

// 在 webpack.base.config.js中的 resolve 配置項翎蹈,在其 alias 中增加別名
resolve: {
    extensions: ['.js', '.vue', '.json'],
    alias: {
      'vue$': 'vue/dist/vue.esm.js',
      '@': resolve('src'),
    }
  },

3.vue-cli 3.x 配置

// 在根目錄下創(chuàng)建vue.config.js
var path = require('path')
function resolve (dir) {
  console.log(__dirname)
  return path.join(__dirname, dir)
}
module.exports = {
  chainWebpack: config => {
    config.resolve.alias
      .set(key, value) // key,value自行定義,比如.set('@@', resolve('src/components'))
  }
}

35.img 加載失敗

場景:有些時候后臺返回圖片地址不一定能打開,所以這個時候應該加一張默認圖片

// page 代碼
<img :src="imgUrl" @error="handleError" alt="">
<script>
export default{
  data(){
    return{
      imgUrl:''
    }
  },
  methods:{
    handleError(e){
      e.target.src=reqiure('圖片路徑') //當然如果項目配置了transformToRequire,參考上面 27.2
    }
  }
}
</script>

原文鏈接:# Vue 開發(fā)必須知道的 36 個技巧【近1W字】

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末男公,一起剝皮案震驚了整個濱河市荤堪,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌枢赔,老刑警劉巖澄阳,帶你破解...
    沈念sama閱讀 217,657評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異踏拜,居然都是意外死亡碎赢,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,889評論 3 394
  • 文/潘曉璐 我一進店門速梗,熙熙樓的掌柜王于貴愁眉苦臉地迎上來肮塞,“玉大人,你說我怎么就攤上這事镀琉÷袜停” “怎么了?”我有些...
    開封第一講書人閱讀 164,057評論 0 354
  • 文/不壞的土叔 我叫張陵屋摔,是天一觀的道長烁设。 經常有香客問我,道長,這世上最難降的妖魔是什么装黑? 我笑而不...
    開封第一講書人閱讀 58,509評論 1 293
  • 正文 為了忘掉前任副瀑,我火速辦了婚禮,結果婚禮上恋谭,老公的妹妹穿的比我還像新娘糠睡。我一直安慰自己,他們只是感情好疚颊,可當我...
    茶點故事閱讀 67,562評論 6 392
  • 文/花漫 我一把揭開白布狈孔。 她就那樣靜靜地躺著,像睡著了一般材义。 火紅的嫁衣襯著肌膚如雪均抽。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,443評論 1 302
  • 那天其掂,我揣著相機與錄音油挥,去河邊找鬼。 笑死款熬,一個胖子當著我的面吹牛深寥,可吹牛的內容都是我干的。 我是一名探鬼主播贤牛,決...
    沈念sama閱讀 40,251評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼惋鹅,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了盔夜?” 一聲冷哼從身側響起负饲,我...
    開封第一講書人閱讀 39,129評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎喂链,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體妥泉,經...
    沈念sama閱讀 45,561評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡椭微,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,779評論 3 335
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了盲链。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蝇率。...
    茶點故事閱讀 39,902評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖刽沾,靈堂內的尸體忽然破棺而出本慕,到底是詐尸還是另有隱情,我是刑警寧澤侧漓,帶...
    沈念sama閱讀 35,621評論 5 345
  • 正文 年R本政府宣布锅尘,位于F島的核電站,受9級特大地震影響布蔗,放射性物質發(fā)生泄漏藤违。R本人自食惡果不足惜浪腐,卻給世界環(huán)境...
    茶點故事閱讀 41,220評論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望顿乒。 院中可真熱鬧议街,春花似錦、人聲如沸璧榄。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,838評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽骨杂。三九已至涂身,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間腊脱,已是汗流浹背访得。 一陣腳步聲響...
    開封第一講書人閱讀 32,971評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留陕凹,地道東北人悍抑。 一個月前我還...
    沈念sama閱讀 48,025評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像杜耙,于是被迫代替她去往敵國和親搜骡。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,843評論 2 354

推薦閱讀更多精彩內容

  • 基于Vue的一些資料 內容 UI組件 開發(fā)框架 實用庫 服務端 輔助工具 應用實例 Demo示例 element★...
    嘗了又嘗閱讀 1,151評論 0 1
  • 響應式布局的理解 響應式開發(fā)目的是一套代碼可以在多種終端運行,適應不同屏幕的大小,其原理是運用媒體查詢,在不同屏幕...
    懶貓_6500閱讀 787評論 0 0
  • 要招一個會vue的開發(fā)者: 作為面試官的你佑女,你還會每次都只是問這些老土的問題嗎记靡?你對MVVM的理解是什么?你知道什...
    浪子神劍閱讀 23,072評論 0 260
  • 6.10起团驱,早上的困意如何破摸吠?
    池淺笑安然閱讀 44評論 0 0
  • 我不是一個好學生,更不是一個聰明的人嚎花。 沒有超高的情商寸痢,也沒有一個很好的智商。 有的只是踏實和努力的精神紊选。 從小到...
    Fiona星閱讀 603評論 0 0