Vue2的Mixins

在Vue2里就有类似的Mixins。

Mixins能将多个相同的逻辑抽离出来,各个组件只要引入mixins,就能实现一次写代码,多组件受益的效果。

但Mixins存在其问题

  1. 会涉及到覆盖的问题,组件的data、methods、filters会覆盖mixin中的同名data、methods、filters

  2. 来自mixins的变量难以使用,隐式传入不利于阅读,使代码难以维护

hooks

使用hooks做一个根据图片生成base64的逻辑

hooks/index.ts:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
import { onMounted } from "vue"

type Options = {
el:string
}

export default function(options:Options):Promise<{baseUrl:string}> {
return new Promise((resolve)=> {
onMounted(()=> {
const img:HTMLImageElement = document.querySelector(options.el) as HTMLImageElement
// 等图片加载完成后再转换,不然会报错
img.onload = ()=> {
resolve({
baseUrl:base64(img)
})
}
})

const base64 = (el:HTMLImageElement)=> {
const canvas = document.createElement("canvas")
const ctx = canvas.getContext("2d")
canvas.width = el.width
canvas.height = el.height
// 根据图片画canvas
ctx?.drawImage(el,0,0,canvas.width,canvas.height)
// 获取图片的后缀名
const src = el.src
const suffix = src.substring(src.lastIndexOf(".")+1)
// 导出一个base64
return canvas.toDataURL(`image/${suffix}`)
}
})
}

App.vue:

1
2
3
4
5
6
7
8
9
10
<template>
<div>
<img id="img" width="300" height="300" src="./assets/images/Computer Love EP_109951166194032069.jpg" alt="">
</div>
</template>

<script setup lang="ts">
import useBase64 from "@/hooks/index"
useBase64({el: "#img"}).then(console.log)
</script>