vue-混入( mixin 更方便的組件功能復用方法)的使用

前言

  vue 中組件完成了樣式和功能的綜合復用,通過自定義指令完成了一部分功能的復用,本文總結一下混入在vue項目開發中提供的非常便利的功能復用。

正文

  1、混入的分類

  (1)全局混入

  <div id="app">
    <h1>我是app組件</h1>
  </div>
  <script>
    // 全局混入
    Vue.mixin({
      created: function () {
        console.log("全局混入");
      }
    })
    new Vue({
      el: "#app",
      data() {
        return {
        }
      },
      methods: {
      }
    })
  </script>

  上面的程式碼中,vue.mixin方法中傳入一個混入的對象,該對象為 created 鉤子函數,在app組件載入過程中調用了該鉤子函數,結果如下:

 

  (2)局部混入

  <div id="app">
    <mix-item></mix-item>
    <mix-item2></mix-item2>
  </div>
  <script>
    // 局部混入
    var myMixin = {
      created: function () {
        this.hello()
      },
      methods: {
        hello: function () {
          console.log('hello from mixin!')
        }
      }
    }
    Vue.component("mix-item", {
      mixins: [myMixin],
      template: `<div>我是mix-item</div>`
    })
    Vue.component("mix-item2", {
      mixins: [myMixin],
      template: `<div>我是mix-item2</div>`
    })
    new Vue({
      mixins: [myMixin],
      el: "#app",
      data() {
        return {
        }
      },
      methods: {
      }
    })
  </script>

  上面的程式碼中通過字面量的形式創建了一個對象變數 myMixin ,在兩個子組件和 Vue(#app) 父組件中分別混入了這個對象,因此三個地方會調用該混入對象,首先app父組件調用,然後才是子組件調用,結果如下:

 

  2、鉤子函數的合併

 <div id="app">
    <mix-item></mix-item>
    <mix-item2></mix-item2>
  </div>
  <script>
    // 局部混入
    var myMixin = {
      created: function () {
        console.log("我是混入的方法");
      },
    }
    Vue.component("mix-item", {
      mixins: [myMixin],
      created() {
        console.log("我是mix-item 的created方法");
      },
      template: `<div>我是mix-item</div>`
    })
    Vue.component("mix-item2", {
      mixins: [myMixin],
      created() {
        console.log("我是mix-item2 的created方法");
      },
      template: `<div>我是mix-item2</div>`
    })
    new Vue({
      mixins: [myMixin],
      el: "#app",
      data() {
        return {
        }
      },
      created() {
        console.log("我是app組件的created方法");
      },
      methods: {
      }
    })
  </script>

  上面的程式碼中定義了一個myMixin的變數,在子組件和app父組件中都混入了該變數,同時每個組件內部也使用了該對象對應的鉤子函數,同名的鉤子函數出現時出現的結果如下:

  注意:當組件和混入對象含有同名選項時,同名的鉤子函數將合併為一個數組,因此都將被調用,但是混入對象的鉤子函數將在自身組件鉤子函數之前調用。

  3、data對象的合併

  <div id="app">
    <mix-item></mix-item>
    <mix-item2></mix-item2>
  </div>
  <script>
    // 局部混入
    var myMixin = {
      data() {
        return {
          msg: "helloMixin",
        }
      },
    }
    Vue.component("mix-item", {
      data() {
        return {
          msg: "helloMixin",
          foo: "mix-item"
        }
      },
      created() {
        console.log("mix-item", this.$data);
      },
      mixins: [myMixin],
      template: `<div>我是mix-item</div>`
    })
    Vue.component("mix-item2", {
      data() {
        return {
          msg: "helloMixin",
          foo: "mix-item2"
        }
      },
      created() {
        console.log("mix-item2", this.$data);
      },
      mixins: [myMixin],
      template: `<div>我是mix-item2</div>`
    })
    new Vue({
      mixins: [myMixin],
      data: {
          msg: "helloMixinApp",
          foo: "fooo"
      },
      created() {
        console.log("#app", this.msg);
        console.log("#app", this.foo);
      },
      el: "#app",
      methods: {
      }
    })
  </script>

  上面的程式碼中通過字面量的形式創建一個混入對象 myMinxin ,在父組件( #app )和兩個子組件中分別混入了該對象,其中組件內部 data 對象和混入對象存在同名屬性,結果如下:

   注意:當混入對象為data數據對象時,數據對象會在組件內部進行遞歸合併,當混入對象和組件data同名衝突的時候,組件中的 data 會覆蓋混入對象的 data 屬性。

  4、methods 對象的合併

  <div id="app">
    <mix-item></mix-item>
    <mix-item2></mix-item2>
  </div>
  <script>
    // 局部混入
    var myMixin = {
      methods: {
        sayHello() {
          console.log("hello myMixin");
        }
      }
    }
    Vue.component("mix-item", {
      created() {
        this.sayHello()
      },
      mixins: [myMixin],
      template: `<div>我是mix-item</div>`
    })
    Vue.component("mix-item2", {
      created() {
        this.sayHello()
      },
      mixins: [myMixin],
      template: `<div>我是mix-item2</div>`
    })
    new Vue({
      mixins: [myMixin],
      created() {
        this.sayHello()
      },
      el: "#app",
      methods: {
        sayHello() {
          console.log("hello app");
        }
      }
    })
  </script>

  上面的程式碼中,定義了一個含methods屬性的混入對象,在父組件(app)和兩個子組件中分別混入該對象,其中組件內部存在和混入對象同名的方法時候結果如下:

  注意:當混入對象屬性為methods、cpmponents、directive 時,這些屬性會在組件內部進行遞歸合併,當混入對象和組件內部屬性同名衝突的時候,組件中的屬性會覆蓋混入對象的屬性。

寫在最後

  vue中的混入提供了一種非常靈活的方式來分發組件中可復用的功能,很大程度上提高了程式碼的復用性,混入有點類似與繼承,當子組件對象繼承了父組件對象,一般情況下遵循就近原則,但是混入又不完全等同於繼承,vue混入存在對不同配置的混入策略。

  以上就是本文的全部內容,希望給讀者帶來些許的幫助和進步,方便的話點個關注,小白的成長踩坑之路會持續更新一些工作中常見的問題和技術點。最後,大家國慶節快樂!!!

 

 

Tags: