vue2和vue3中的逻辑复用是怎么实现的?

248 阅读2分钟

vue2的方案 - - -> mixins(混入)

一.mixins的作用就是将相同的逻辑和功能抽离出来,放到专门的mixins文件中,需要时直接引入mixins来复用同样的代码逻辑。
创建一个mixins/index.js,我们试试定义一段逻辑,在两个不同的组件中使用

// mixins/index.js
// mixin里的东西就是组件里导出的对象,对象里怎么写,mixins就怎么写,vue会自动合并
// 定义一段用于复用的逻辑
export default {
  data () {
    return {
      userName: '张三'
    }
  },
  methods: {
    setUserName (newUserName) {
      this.userName = newUserName
    }
  }
}


// page1
<template>
  <div>
    {{userName}}
    <button @click="setUserName('李四')">changeName</button>
  </div>
</template>

<script>
import mixin1 from '@/mixins/index'
export default {
  mixins: [mixin1],
  data () {
    return {
    }
  },
  methods: {
  }
}
</script>

可以看到,我完全没定义page1中的data和methods,但实际运行后,页面能显示插值表达式里的userName,点击按钮也能正常改为'李四'

image.png

image.png

除了普通的data 和 methods,钩子函数 / computed / watch 也同样可以在mixins中定义

二.mixins如果出现命名冲突,vue会有一套默认的解决方案

  1. 如果你在组件里的methods / watch / computed定义了a方法,在mixins也定义了a方法,那么组件里的会覆盖mixins里的方法
  2. 如果你在组件和mixins都使用了生命周期钩子函数,那么两者都会运行,且mixins中的优先于组件中的执行

三.mixins也存在一些问题,这甚至导致在vue3中,已经不推荐使用mixins

可以看到上面的代码,在组件中,我直接调用了方法和数据,如果只看组件,是不是有些莫名其妙?

<template>
  <div>
    {{userName}}
    <button @click="setUserName('李四')">changeName</button>
  </div>
</template>

<script>
import mixin1 from '@/mixins/index'
export default {
  mixins: [mixin1],
  data () {
    return {
    }
  },
  methods: {
  }
}
</script>

mixins里的代码是无法直接在页面中看到的,在实际复杂的开发中,如果出现bug需要维护,那么我们只能看到调用了方法,却不知道这方法具体的逻辑,必须再打开mixins文件查看,这导致代码的可读性变得很差

vue3的方案 - - -> 组合式API

我们都说vue3的组合式PAPI好,但好在哪里好像也不太清楚,实际上,vue3的组合式API完全扬弃了以往的mixins,实现了更好的逻辑复用,让我们看下例子

// composable/index.js

import { ref } from "vue"

export const getSay = () => {
    const message = ref('')
    
    const say = (type) => {
        switch (type) {
          case 'humen' :
            message.value = '你好'
            console.log(message.value)
            break
          case 'cat' :
            message.value = '喵~'
            console.log(message.value)
            break
    }
    }
    // 注意要把定义的东西return出去
    return { message, say}
}

如果我们要复用这段逻辑,只需要导入并调用这个方法,他就会将message和say方法return出来,直接调用即可

import { getSay } from '@/composable/index.js'

const { message, say } = getSay()
say('humen')