Vue使用的擴展


1、Bus(總線)實現非父子組件通信

Vue2.0提供了Vuex進行非父子組件之間的通信,但在簡單的場景下,可以使用一個空的Vue實例作為中央事件總線。

實現代碼示例:

<div id="app">
    <c1></c1>
    <c2></c2>
</div>
var Bus = new Vue();   //為了方便將Bus(空vue)定義在一個組件中,在實際的運用中一般會新建一Bus.js
Vue.component('c1',{   //這里以全局組件為例,同樣,單文件組件和局部組件也同樣適用
template:'<div>{{msg}}</div>',
  data: () => ({
    msg: 'Hello World!'
  }),
  created() {
    Bus.$on('setMsg', content => {     //監聽Vue示例 Bus 的某一個事件
      this.msg = content;
    });
  }
});
Vue.component('c2',{
  template: '<button @click="sendEvent">Say Hi</button>',
  methods: {
    sendEvent() {
      Bus.$emit('setMsg', 'Hi Vue!');  //觸發vue示例 bus 的某一個事件,並且將參數作為數據傳過去
    }
  }
});
var app= new Vue({
    el:'#app'
})

在實際運用中,一般將Bus抽離出來:

// Bus.js
import Vue from 'vue'
const Bus = new Vue()
export default Bus

組件調用時先引入

// 組件1
import Bus from './Bus'
export default {
  data() {
      return {
         .........
       }
    },
  methods: {
      ....
      Bus.$emit('log', 120)
  },
}
// 組件2
import Bus from './Bus'
export default {
    data() {
        return {
            .........
            }
      },
    mounted () {
       Bus.$on('log', content => { 
          console.log(content)
        });    
    }    
} 

但這種引入方式,經過webpack打包后可能會出現Bus局部作用域的情況,即引用的是兩個不同的Bus,導致不能正常通信

1.1、推薦使用Bus的方式

(1)直接將Bus注入到Vue根對象中

import Vue from 'vue'
const Bus = new Vue()
var app= new Vue({
    el:'#app',
   data:{
    Bus
    }  
})

在子組件中通過this.$root.Bus.$on()、this.$root.Bus.$emit()來調用

(2)在一個教程視頻中看過,也可以通過將Bus放在vue示例的原型對象中使用

Vue.prototype.bus = new Vue();

每個組件都是一個Vue示例,所以每個組件都會有bus屬性,在組件中可以通過 this.bus.$emit、this.bus.$on 來調用

Vue.component('c2',{
  template: '<button @click="sendEvent">Say Hi</button>',
  methods: {
    sendEvent() {
      this.bus.$emit('setMsg', 'Hi Vue!');  
    }
  }
});

 參考:https://www.cnblogs.com/fanlinqiang/p/7756566.html

 

2、異步組件(按需加載)

官方文檔:https://cn.vuejs.org/v2/guide/components-dynamic-async.html

在單頁應用中,如果沒有應用懶加載,運用webpack打包后的文件將會異常的大(此時通常只有一個JS文件),造成進入首頁時,需要加載的內容過大,延時過長,不利於用戶體驗,而運用懶加載則可以將頁面進行划分,需要的時候加載頁面,可以有效的分擔首頁所承擔的加載壓力,減少首頁加載用時。

其實 vue 中實現按需加載也非常簡單,只要將平常的導入組件的方式改一下就行,vue-router會自動幫我們實現按需加載需要的組件,而 webpack 會自動幫我們實現代碼拆分,由此實現了在需要的時候才加載需要的組件文件。

2.1、使用resolve => require([’./_account’], resolve)實現按需加載

創建一個項目,組件目錄:Helloworld 組件是首頁,在 HelloWord 中引入加載 item01 組件,在 item01 組件中引入加載 item02 組件。

     1、使用普通的引入方式:

//HelloWord.vue 中的代碼
<template>
  <div class="hello">
    <h3>this is HelloWorld</h3>
    <template v-if="showItem">
      <Item01></Item01>
    </template>
    <button @click="toggleItem">切換</button>
  </div>
</template>

import Item01 from './Item01.vue'
export default {
  name: 'HelloWorld',
  data () {
    return {
      showItem: false
    }
  },
  components: {
    Item01
  },
  methods: {
    toggleItem () {
      this.showItem = !this.showItem;
    }
  }
}

//Item01.vue 中的代碼
<template>
  <div>
    <h3>this is item01</h3>
    <Item02></Item02>
  </div>
</template>

import Item02 from './Item02.vue'

運行項目:

點擊切換按鈕,顯示 item01、item02 組件:

 

可以看到,加載的 JS 文件並沒有任何變化,即沒有新加載 JS 文件。可以看到 item01和 item02 組件都被打包到了 app.js 文件中,所有的組件 JS 代碼都被打包到了一個文件中,這會導致該文件過大,影響加載速度。

     

      2、使用按需加載的方式:

//HelloWord.vue 中的代碼
<template>
  <div class="hello">
    <h3>this is HelloWorld</h3>
    <template v-if="showItem">
      <Item01></Item01>
    </template>
    <button @click="toggleItem">切換</button>
  </div>
</template>

const Item01 = resolve => require(['./Item01'],resolve)   //按需加載 item01 組件
export default {
  name: 'HelloWorld',
  data () {
    return {
      showItem: false
    }
  },
  components: {
    Item01
  },
  methods: {
    toggleItem () {
      this.showItem = !this.showItem;
    }
  }
}

//Item01.vue 中的代碼
<template>
  <div>
    <h3>this is item01</h3>
    <Item02></Item02>
  </div>
</template>

const Item02 = resolve => require(['./Item02'],resolve)   //按需加載 item02 組件

運行項目:

 

點擊切換按鈕,顯示 item01、item02 組件:

可以看到,一開始沒有顯示 item01、item02 組件時,瀏覽器只加載了 app.js 文件。當點擊按鈕顯示 item01、item02 組件后,開始依次加載 item01、item02打包后的 JS 文件。

通過按需加載,webpack 會幫我們將需要按需加載的組件跟一開始需要加載的 JS 文件分離開,當需要加載的時候再加載。按需加載只是改變掉加載組件的方式而已,webpack 會自動幫我們實現按需加載。

利用此特性,我們便能做很多針對前端的優化。比如:將頁面核心功能(音、視頻播放、文章、商品等等)打包成一個核心模塊,通過框架優先加載。其他的一些周邊功能打包后,通過服務器異步加載,從而解決業務需求越來越多導致的系統難維護、訪問慢問題。

參考:https://segmentfault.com/a/1190000012138052

其它實現按需加載的引入方法可以參考:https://blog.csdn.net/scarlett_dream/article/details/83756392https://segmentfault.com/a/1190000011519350

 

3、Vue 動態插入組件

代碼示例:

<div id="app">
  <p>{{ message }}</p >
  <button @click="add('a-component', '我是A')">添加A組件</button>
  <button @click="add('b-component', '我是B')">添加B組件</button>
  <component :is="item.component" :text="item.text" v-for="item in items"></component>
</div>
js:

<script>
const aComponent = Vue.extend({
  props: ['text'],
  template: '<li>A Component: {{ text }}</li>'
})

const bComponent = Vue.extend({
  props: ['text'],
  template: '<li>B Component: {{ text }}</li>'
})

new Vue({
  el: '#app',
  data () {
    return {
      message: 'Hello Vue.js!',
      items: []
    }
  },
  methods: {
    add (name, text) {
       this.items.push({
         component: name,
         text: text
       })
    }
  },
  components: {
    aComponent,
    bComponent
  }
})
</script>

Vue.extend 是構造一個組件的語法器。你給它參數它給你一個組件,然后這個組件你可以作用到Vue.component 這個全局注冊方法里, 也可以在任意vue模板里使用<apple>組件

var apple = Vue.extend({
   ....
})
Vue.component('apple',apple) 

也可以作用到vue實例或者某個組件中的components屬性中並在內部使用apple組件

new Vue({ 
  components:{
     apple:apple
  }
})

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM