我们再来用一个例子

常见场景

有两个非常相似的组件,他们的基本功能是一样的,但他们之间又存在着足够的差异性,此时的你就像是来到了一个分岔路口:我是把它拆分成两个不同的组件呢?还是保留为一个组件,然后通过props传值来创造差异性从而进行区分呢?

两种解决方案都不够完美:如果拆分成两个组件,你就不得不冒着一旦功能变动就要在两个文件中更新代码的风险,这违背了 DRY 原则。反之,太多的props传值会很快变得混乱不堪,从而迫使维护者(即便这个人是你)在使用组件的时候必须理解一大段的上下文,拖慢写码速度。
使用Mixin。Vue 中的Mixin对编写函数式风格的代码很有用,因为函数式编程就是通过减少移动的部分让代码更好理解(引自 Michael Feathers )。Mixin允许你封装一块在应用的其他组件中都可以使用的函数。如果使用姿势得当,他们不会改变函数作用域外部的任何东西,因此哪怕执行多次,只要是同样的输入你总是能得到一样的值,真的很强大!

比如前面

我们现在App.Vue 中的配置

  1. <template>
  2. <div>
  3. <School />
  4. <Student/>
  5. </div>
  6. </template>
  7. <script>
  8. //引School组件
  9. import School from "@/components/School";
  10. import Student from "./components/Student"
  11. export default {
  12. name: 'App',
  13. components : {School,Student},
  14. }
  15. </script>
  16. <style>
  17. </style>

School.Vue

<template>
  <div class="demo">
    <h2> 学校名称 {{ name }}</h2>
    <h2 @click="ShowMethod"> 学校地址 {{ address }}</h2>
  </div>
</template>

<script>
export default {
  name: "School",
  data(){
    return {
      name: '苑庄小学',
      address: '金辉大厦',
    }
  },
  methods:{
    ShowMethod(){
      alert(this.name)
    }
  }
}
</script>

<style scoped>
  .demo {
    background: orange;
  }
</style>

Student.Vue

<template>
  <div class="demo">
    <h2> 学生姓名 {{ name }}</h2>
    <h2  @click="ShowMethod" > 学生年龄 {{ age }}</h2>
  </div>
</template>

<script>
export default {
  name: "Student",
  data(){
    return {
      name: '代亮',
      age: '18',
    }
  },
  methods:{
    ShowMethod(){
      alert(this.name)
    }
  }
}
</script>

<style scoped>
.demo {
  background: blue;
}
</style>

以上我们method是一样的。。有没有一种把这个东西抽离出来的方式呢?

我们新建一个mixin.js

export const  mixin = {
    methods:{
        ShowName(){
            alert(this.name)
        }
    }
}

然后我们在School和Student组件中删除method,增加mixins参数
还有需要import mixin 这个js

<template>
  <div class="demo">
    <h2> 学校名称 {{ name }}</h2>
    <h2 @click="ShowName"> 学校地址 {{ address }}</h2>
  </div>
</template>

<script>

//引入mixin
import {mixin} from "@/mixin";

export default {
  name: "School",
  data(){
    return {
      name: '苑庄小学',
      address: '金辉大厦',
    }
  },
  mixins:[mixin]
}
</script>

<style scoped>
  .demo {
    background: orange;
  }
</style>