最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Vue項(xiàng)目中常用的實(shí)用技巧匯總

 更新時(shí)間:2021年07月07日 11:30:51   作者:菜啊Hughes  
如果說是JQuery是手工作坊,那么Vue.js就像是一座工廠,雖然Vue.js做的任何事情JQuery都可以做,但無論是代碼量還是流程規(guī)范性都是前者較優(yōu),這篇文章主要給大家匯總介紹了關(guān)于Vue項(xiàng)目中常用的實(shí)用技巧,需要的朋友可以參考下

前言

在 Vue 項(xiàng)目開發(fā)中,很容易產(chǎn)生一些問題,比如代碼重復(fù)、繁雜等,其實(shí) Vue 項(xiàng)目開發(fā)中有很多技巧可以使用,本文將列出一些簡單且很好用的幾個(gè)技巧,幫助我們寫出漂亮的代碼。用到的技術(shù)棧是 Vue2.0 + TypeScript +  vue-property-decorator + ElementUI。將用到以下幾個(gè)技巧:

  • 使用 $attrs 和 $listeners 進(jìn)行多層級(jí)的數(shù)據(jù)和事件傳遞
  • 實(shí)現(xiàn)數(shù)據(jù)的雙向綁定,方便維護(hù)數(shù)據(jù)
  • 使用 Mixins
  • 使用動(dòng)態(tài)組件去懶加載組件
  • 在組件作用域內(nèi)的 CSS 中使用 ::v-deep  修改組件樣式
  • 使用裝飾器優(yōu)化代碼
  • 利用 require.context 去獲取項(xiàng)目目錄信息

1. 使用 $attrs 和 $listeners 進(jìn)行多層級(jí)的數(shù)據(jù)和事件傳遞

先聊聊如何傳遞 Prop,可以分為靜態(tài)和動(dòng)態(tài)的 Prop:

<!-- 靜態(tài)的prop -->
<blog-post title="My journey with Vue"></blog-post>
<!-- 動(dòng)態(tài)的prop -->
<blog-post v-bind:title="post.title"></blog-post>
<!-- 動(dòng)態(tài)的prop傳遞可以簡寫成 -->
<blog-post :title="post.title"></blog-post>
<!-- 需要傳遞多個(gè)prop的時(shí)候,可以一起寫在v-bind上 -->
<blog-post v-bind="{ editable, title: post.title}"></blog-post>

了解了 Props 的傳遞方式,在看看官方文檔是怎么定義 $attrs 的,  在尤大大的文檔中這樣介紹了 $attrs:

$attrs:  包含了父作用域中不作為 prop 被識(shí)別 (且獲取) 的 attribute 綁定 class 和 style 除外)。當(dāng)一個(gè)組件沒有聲明任何 prop 時(shí),這里會(huì)包含所有父作用域的綁定 (class 和 style 除外),并且可以通過 v-bind="$attrs" 傳入內(nèi)部組件

$attrs  包含了傳入到父作用域中沒有在 props 聲明的其他 props,因此我們可以用 $attrs 去代替那些父組件中不需要的而子組件需要的 props, 通過 v-bind="$attrs" 統(tǒng)一傳遞給后代。這樣就避免了一個(gè)個(gè)聲明然后再一個(gè)個(gè)傳遞。

<blog-post v-bind="$attrs"></blog-post>

上面這一行代碼就通過 v-bind="$attrs" 的方式將本作用域中不作為 prop 的其他屬性傳遞給了 blog-post 組件。

父組件通過 $attrs 傳遞給后代組件后,后代組件如果想通過觸發(fā)事件來更新父組件狀態(tài)該如何處理?如果一級(jí)一級(jí)地往上 emit 事件,會(huì)不會(huì)弄得代碼太繁瑣復(fù)雜了?在 Vue 中可以通過 $listeners 解決這個(gè)問題,先看看官方文檔關(guān)于  $listeners 的說明:

包含了父作用域中的 (不含 .native 修飾器的) v-on 事件監(jiān)聽器。它可以通過 v-on="$listeners" 傳入內(nèi)部組件——在創(chuàng)建更高層次的組件時(shí)非常有用。

文檔中說了 $listeners 包含了父作用域中的事件監(jiān)聽器。意思就是 $listeners 表示了父組件中的事件監(jiān)聽器集合,只要是觸發(fā)父組件的事件,而不是自己的,就可以用一個(gè) v-on="$listeners"表示。

<!-- 父組件(第一層組件) -->
<componentA @on-change="handleChange" v-bind="{ editable, title: post.title}" />

<!-- 中間層的組件 -->
<Child v-bind="$attrs" v-on="$listeners"/>

<!-- 數(shù)據(jù)傳遞的目標(biāo)組件,事件觸發(fā)的組件 -->
<div @click="handleClick">{{ title }} </div>
<script>
  export default {
    props: {
      title: String
    }
    handleClick() {
      this.$emit('on-change', 'New Title');
    }
  }
</script>

上面的代碼示例中,中間層的組件內(nèi)通過 v-bind="$attrs" 將其余的 Prop 傳遞給了 Child 組件,再通過 v-on="$listeners" 綁定父作用域中的事件監(jiān)聽器,一旦 emit 就會(huì)傳給了父組件。

2. 實(shí)現(xiàn)數(shù)據(jù)的雙向綁定,方便維護(hù)數(shù)據(jù)

有很多這樣的場景,父組件需要傳遞數(shù)據(jù)給子組件,且在子組件觸發(fā)數(shù)據(jù)更新的時(shí)候,馬上反饋給父組件,父組件數(shù)據(jù)更新,單向數(shù)據(jù)流向子組件,最后子組件更新。通常情況用 props + $emit 的方式去更新狀態(tài),但是這種處理方式有點(diǎn)笨拙,且不易維護(hù),所以可以通過實(shí)現(xiàn)數(shù)據(jù)的“雙向綁定”來提高代碼的可維護(hù)性。可以通過這以下方式去實(shí)現(xiàn):

使用 .sync 實(shí)現(xiàn) Prop 的“雙向綁定”

在 v-bind prop的時(shí)候添加  .sync 修飾符,賦新值的時(shí)候用  this.$emit('update:propName', newValue)

<!-- .sync是 v-on:update這種模式的一種縮寫 -->
<Child v-on:update:title="title" />
<!-- 相當(dāng)于 -->
<Child :title.sync="title" />

如果要更新上述代碼中的 title 值,只需要   this.$emit('update:title', '新標(biāo)題'),完成數(shù)據(jù)更新。

使用 model 選項(xiàng)

model 是2.2.0+ 新增的選項(xiàng),一個(gè)組件上的 v-model 默認(rèn)會(huì)利用名為 value  的 Prop  和名為 input 的事件, 而 model 選項(xiàng)可以規(guī)定 Prop 名稱和事件名稱來實(shí)現(xiàn) v-model,好處是在實(shí)現(xiàn) v-model 的同時(shí)也避免了 Prop 和事件名的沖突。

<!-- 父組件 -->
<Model v-model="checked"/>

<!-- Model組件 -->
<div @click="handleClick">
  <p>自定義組件的 v-model</p>
  checked {{checked}}
</div>
<script lang="ts">
export default {
  model: {
    prop: 'checked',
    event: 'change'
  },
  props: {
    checked: Boolean
  },
  methods: {
    handleClick() {
      this.$emit('change', !this.checked);
    }
  }

在上述代碼中,只需要在 model 選項(xiàng)中添加 prop 和 event,就可以實(shí)現(xiàn)了 v-model。而在 Vue + TS 項(xiàng)目中 vue-property-decorator 中提供了 Model 的裝飾器,需要這么寫:

@Model('change', { type: Boolean }) readonly checked!: boolean
handleClick() {
  this.$emit('change', !this.checked);
}

只需要通過 .sync 和 model 就可以實(shí)現(xiàn)數(shù)據(jù)的“雙向綁定”,這樣書寫代碼可以一定程度上減少我們的代碼,而且另代碼變得更優(yōu)雅且可維護(hù)。

3. 使用 Mixins

Mixins 可以用于兩種場景:

  1. 利用它去抽取成組件內(nèi)的公共代碼加強(qiáng)代碼復(fù)用,不要在全局內(nèi)套來套去,最好在組件內(nèi)或者頁面中使用。
  2. 利用它去分離功能點(diǎn),有時(shí)候會(huì)遇到一種情況,就是業(yè)務(wù)功能很多導(dǎo)致寫起來的 Vue 文件行數(shù)很多,導(dǎo)致代碼很難以維護(hù),功能點(diǎn)代碼不好追蹤??梢酝ㄟ^抽取功能代碼的方式,讓這個(gè)龐大的 Vue 文件更好維護(hù)。

首先寫一個(gè)公共的 mixin 文件, 把高復(fù)用的狀態(tài)和函數(shù)寫進(jìn)去。

export default class CommonMixins extends Vue{
    public paginations = {
        pageSize: 20,
        total: 0,
        currentPage: 1,
    }
    handleChangePageSize (pageSize: number, cb: Function) {
        this.paginations.pageSize = pageSize;
        cb();
    }
    handleChangePageNum (currentPage: number, cb: Function) {
        this.paginations.currentPage = currentPage;
        cb();
    }
}

vue-property-decorator 提供了 Mixins 的裝飾器,在業(yè)務(wù)頁面中引入 Mixin 只需要往里 Mixins 傳入 , 可以傳多個(gè),表示混入多個(gè) Mixin。

<script lang="ts">
import { Component, Mixins } from 'vue-property-decorator';
import CommonMixins from "./common-mixin";
import PermissionMixins from "./permission-mixin";
@Component({})
export default class Parent extends Mixins(CommonMixins, PermissionMixins) {
}
</script>

如果只需要一個(gè)的話,也可以直接繼承

<script lang="ts">
import { Component, Mixins } from 'vue-property-decorator';
import CommonMixins from "./common-mixin";
@Component({})
export default class Parent extends CommonMixins {
}
</script>

在遇到功能點(diǎn)多,代碼量大的頁面時(shí),我們可以利用 Mixin 抽離一些功能點(diǎn),通過文件去管理這些功能,這樣會(huì)比較方便去管理代碼。

4. 使用動(dòng)態(tài)組件去懶加載組件

組件在加載都是同步的,但當(dāng)頁面內(nèi)容很多,有些組件并不需要一開始就加載出來的比如彈窗類的組件,這些就可以用動(dòng)態(tài)組件,當(dāng)用戶執(zhí)行了某些操作后再加載出來,這樣可以提高主模塊加載的性能, 在 Vue 中可以使用 component 動(dòng)態(tài)組件, 依 is 的值,來決定哪個(gè)組件被渲染。

<template>
  <div>
    主頁面 <br/>
    <button @click="handleClick1">點(diǎn)擊記載組件1</button><br/>
    <button @click="handleClick2">點(diǎn)擊記載組件2</button><br/>
    <component :is="child1"></component>
    <component :is="child2"></component>
  </div>
</template>
<script lang="ts">
import { Component, Vue } from 'vue-property-decorator';
@Component({})
export default class AsyncComponent extends Vue {
  public child1:Component = null;
  public child2:Component = null;
  handleClick1() {
    this.child1 = require('./child1').default;
  }
  handleClick2() {
    this.child2 = require('./child2').default;
  }
}
</script>

示例代碼中,只有當(dāng)點(diǎn)擊的時(shí)候才會(huì)去加載組件。component 還可以配合 v-show 去控制顯示和隱藏,這樣這個(gè)component 只會(huì) mounted 一次,優(yōu)化性能。

5. 在組件作用域內(nèi)的 CSS 中使用 ::v-deep  修改組件樣式

有很多場景想更改 UI 組件樣式,然后怕影響別人的使用,加上 scoped 后又不能生效,可以使用  ::v-deep 深度作用選擇器去修改組件作用域內(nèi)的 CSS 的樣式。在 CSS 中我們可以使用 >>> 操作符,但在預(yù)處理器中的寫法就要用 /deep/ 或 ::v-deep。

<style scoped>
>>> .ivu-tabs-tabpane {
        background: #f1f1f1;
    }
</style>
<style lang="scss" scoped>
/deep/ .ivu-tabs-tabpane {
        background: #f1f1f1;
    }
</style>
<style lang="scss" scoped>
::v-deep .ivu-tabs-tabpane {
        background: #f1f1f1;
    }
</style>

::v-deep 和 /deep/ 作用是一樣的,但不推薦使用 /deep/, 在 Vue3.0 中將不支持 /deep/ 這種寫法。

6. 使用裝飾器優(yōu)化代碼

裝飾器增加了代碼的可讀性,清晰地表達(dá)了意圖,而且提供一種方便的手段,增加或修改類的功能,比如給類其中的方法提供防抖的功能。

import debounce from 'lodash.debounce';
export function Debounce(delay: number, config: object = {}) {
  return (target: any, prop: string) => {
    return {
      value: debounce(target[prop], delay, config),
    };
  };
}

這樣的好處是使用起來非常方便,另外增加了代碼的可讀性。

@Debounce(300)
onIdChange(val: string) {
  this.$emit('idchange', val);
}

7. 利用 require.context 去獲取項(xiàng)目目錄信息

關(guān)于 require.context,webpack 文檔是這么描述的:

可以給這個(gè)函數(shù)傳入三個(gè)參數(shù):一個(gè)要搜索的目錄,一個(gè)標(biāo)記表示是否還搜索其子目錄, 以及一個(gè)匹配文件的正則表達(dá)式。
webpack 會(huì)在構(gòu)建中解析代碼中的 require.context() 。如果想引入一個(gè)文件夾下面的所有文件,或者引入能匹配一個(gè)正則表達(dá)式的所有文件,這個(gè)功能就會(huì)很有幫助

根據(jù)這個(gè)提示,我們可以引用到一個(gè)文件夾下面的所有文件,由此可以利用獲取的文件信息去做一些操作,比如在注冊(cè)組件的時(shí)候,原本我們注冊(cè)組件的時(shí)候需要一個(gè)個(gè)引入并且一個(gè)個(gè)注冊(cè),而且后面想加新的,又要再寫上,現(xiàn)在可以通過 require.context 去優(yōu)化這一段代碼。

// import WmsTable from './wms-table/table/index';
import Table from './table/index.vue';
import CustomHooks from './custom-hooks/custom-hooks-actions/index';
import SFilter from './s-filter/filter-form';
import WButton from './button/index';
import CreateForm from './createForm/create-form/CreateForm.vue';
import Action from './table/action-table-column.vue';
import DetailItem from './detail-item.vue';


Vue.component('w-filter', SFilter);
Vue.component('w-button', WButton);
Vue.component('custom-hooks', CustomHooks);
Vue.component('create-form', CreateForm);
Vue.component('w-table', Table);
Vue.component('w-table-action', Action);
Vue.component('zonetime-date-picker', ZonetimeDatePicker);
Vue.component('detail', DetailItem);

注冊(cè)全局組件的時(shí)候,不需要一個(gè)一個(gè) import,和一個(gè)個(gè)去注冊(cè),使用 require.context 可以自動(dòng)導(dǎo)入模塊,這樣的好處在于,當(dāng)我們新建一個(gè)組件,不用自己再去手寫注冊(cè),而在一開始就幫我們自動(dòng)完成。

const contexts = require.context('./', true, /\.(vue|ts)$/);
export default {
  install (vm) {
    contexts.keys().forEach(component => {
      const componentEntity = contexts(component).default;
      if (componentEntity.name) {
        vm.component(componentEntity.name, componentEntity);
      }
    });
  }
};

總結(jié)

本文介紹了在 Vue 實(shí)戰(zhàn)中經(jīng)常用到的一些技巧,這些技巧的目的都是為了提升開發(fā)效率,比如簡單地實(shí)現(xiàn)雙向數(shù)據(jù)綁定和數(shù)據(jù)跨級(jí)傳遞等,另外也可以提高代碼的可維護(hù)性、可讀性,比如很實(shí)用的裝飾器和利用 Mixin 拆分代碼和管理功能點(diǎn)。

到此這篇關(guān)于Vue項(xiàng)目中常用的實(shí)用技巧匯總的文章就介紹到這了,更多相關(guān)Vue項(xiàng)目常用技巧內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

引用

相關(guān)文章

  • Vue實(shí)現(xiàn)萬年日歷的示例詳解

    Vue實(shí)現(xiàn)萬年日歷的示例詳解

    又是一個(gè)老生常談的功能,接下來會(huì)從零實(shí)現(xiàn)一個(gè)萬年日歷,從布局到邏輯,再到隨處可見的打卡功能。文中的示例代碼簡潔易懂,需要的可以參考一下
    2023-01-01
  • vue中destroyed方法及使用示例講解

    vue中destroyed方法及使用示例講解

    這篇文章主要為大家介紹了vue中destroyed方法及使用示例講解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-06-06
  • Vue+SpringBoot實(shí)現(xiàn)支付寶沙箱支付的示例代碼

    Vue+SpringBoot實(shí)現(xiàn)支付寶沙箱支付的示例代碼

    本文主要介紹了Vue+SpringBoot實(shí)現(xiàn)支付寶沙箱支付的示例代碼,文中通過示例代碼介紹的非常詳細(xì),需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-06-06
  • vue.js中父組件調(diào)用子組件的內(nèi)部方法示例

    vue.js中父組件調(diào)用子組件的內(nèi)部方法示例

    這篇文章主要給大家介紹了關(guān)于vue.js中父組件調(diào)用子組件內(nèi)部方法的相關(guān)資料,文中給出來了詳細(xì)的示例代碼供大家參考學(xué)習(xí),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。
    2017-10-10
  • Vue+ElementUI實(shí)現(xiàn)從后臺(tái)動(dòng)態(tài)填充下拉框的示例代碼

    Vue+ElementUI實(shí)現(xiàn)從后臺(tái)動(dòng)態(tài)填充下拉框的示例代碼

    本文主要介紹了Vue+ElementUI實(shí)現(xiàn)從后臺(tái)動(dòng)態(tài)填充下拉框的示例代碼,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-02-02
  • vue開發(fā)調(diào)試神器vue-devtools使用詳解

    vue開發(fā)調(diào)試神器vue-devtools使用詳解

    這篇文章主要為大家詳細(xì)介紹了vue開發(fā)調(diào)試神器vue-devtools的使用方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-07-07
  • VUE?mixin?使用示例詳解

    VUE?mixin?使用示例詳解

    混入mixin提供了一種非常靈活的方式,來分發(fā)Vue組件中的可復(fù)用功能,一個(gè)混入對(duì)象可以包含任意組件選項(xiàng),接下來通過本文給大家介紹VUE?mixin?使用,需要的朋友可以參考下
    2022-08-08
  • 如何以拖拽方式生成Vue用戶界面

    如何以拖拽方式生成Vue用戶界面

    這篇文章主要給大家介紹了關(guān)于如何以拖拽方式生成Vue用戶界面的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-04-04
  • Vue.js最佳實(shí)踐(五招助你成為vuejs大師)

    Vue.js最佳實(shí)踐(五招助你成為vuejs大師)

    這篇文章主要介紹了Vue.js最佳實(shí)踐,本文主要面向?qū)ο笫怯幸欢╲ue.js 編輯經(jīng)驗(yàn)的開發(fā)者,需要的朋友可以參考下
    2018-05-05
  • vue elementUI實(shí)現(xiàn)拖拽流程圖效果

    vue elementUI實(shí)現(xiàn)拖拽流程圖效果

    這篇文章主要為大家詳細(xì)介紹了如何通過vue elementUI實(shí)現(xiàn)拖拽流程圖效果,不引入插件,純手寫實(shí)現(xiàn),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2025-01-01

最新評(píng)論

隆德县| 芜湖市| 沂水县| 宁乡县| 伊春市| 满洲里市| 保靖县| 黎川县| 汤阴县| 弥勒县| 措勤县| 关岭| 大石桥市| 谢通门县| 怀安县| 肃宁县| 含山县| 潼南县| 通江县| 尼勒克县| 盐边县| 阿合奇县| 印江| 黔江区| 清水河县| 青铜峡市| 珠海市| 陵川县| 九龙城区| 芮城县| 修文县| 佳木斯市| 故城县| 十堰市| 多伦县| 云和县| 龙井市| 青田县| 荔浦县| 罗源县| 阆中市|