在Vue2中使用composition

P1 为什么需要在vue2中使用composition

vue3出来了,composition相比于mixin好太多了,路径清晰,文件指引明确,mixin后对TS支持非常棒,但是很多vue2组件很多vue2项目拖着怎么办?别急!@vue/composition-api他带着composition来了!

P2 什么是@vue/composition-api

点击官网可以看到这样一个说明:

image.png

人家已经说的很清楚了嗷,就是用于提供composition的vue2插件!很棒!

P3 对标vue3 api的程度

image.png

大家从上图可以看到,他支持的vue3 api可太多拉,像最常用的ref/computed/Ref/ComputedRef/watch/watchEffect/defineComponent/onBeforeMount/onBeforeUnmount/reactive啊都有,基本上和vue3相差无几了。除了因为底层2和3不一样,某些功能需要做兼容,大部分功能是可以无缝迁移的噢

image.png

P4 有哪些限制

image.png

P5 实战使用

声明一个导出表格的composition

import { dateFormatter } from "@kushim/kushim-util/common/date";
import { DownloadHTMLTableElement } from "@kushim/kushim-util/table";

function $(str: string) {
    const objE = document.createElement("div");
    objE.innerHTML = str;
    return objE.childNodes;
}

interface Th {
    style: string
    text: string
}

type Tr = (string | number)[]


export function useExportExcel() {

    function exportAsExcel({ ths, trs }: { ths: Th[], trs: Tr[] }, tableName: string, sheetName = "sheet1") {
        const tables = <HTMLTableElement[]><unknown>$(
            `<table>
                <thead>
                    ${ths.map(_ => `<th style='${_.style}'>${_.text}</th>`).join("")}
                </thead>
                <tbody>
                    ${trs.map((_, i) =>
                `<tr style="border:1px solid #aaaaaa;background-color:${i % 2 === 0 ? "#eeeeee" : "#ffffff"}">
                    ${_.map(_ =>
                    `<td raw style='text-align:center;line-height:40px;white-space:pre;'>
                     ${_}
                    </td>`
                ).join("")}
                    </tr>`
            ).join("")}
                </tbody>
            </table>`);

        DownloadHTMLTableElement(
            tables[0],
            `${tableName}[${dateFormatter(new Date(), "yyyy-MM-dd HH-mm-ss")}]`,
            sheetName
        );
    }

    return {
        exportAsExcel
    }
}
复制代码

狠狠地使用它

<template>
    <div @click='exportAsExcel'>点我</div>
</template>
复制代码
<script lang='ts'>
import {  defineComponent, ref, computed, onBeforeMount, watch, reactive} from "@vue/composition-api";

export default defineComponent({
    setup(props,ctx) {
        const list = ref([1,2,3,4,5,6,7,8,9,10])
        
        const doubleList = computed(()=> list.value.map(_=>_*2))

        const { exportAsExcel } = useExportExcel();

        function exportExcel() {
            exportAsExcel(
                {
                    ths: [ { text: "序号" }, { text: "值" },],
                    trs: doubleList.value.map((_, i) =>[ i + 1, _, ])
                },
                "导出的double表格"
            );
        }

        onBeforeMount(()=>{
            exportExcel()
        })

        watch(()=>list.value,(nv)=>{
            if(nv.length===0) return
            exportExcel()
        })

        setTimeout(()=>{
            list.value.push(99,98,97,96)
        },3000)

        return {
            list,
            doubleList,
            exportExcel
        }
    }
})
</script>
复制代码

P6 使用建议

  1. 建议搭配typescript使用噢
  2. vue2部分ctx属性于vue3不同,使用时建议使用这种属性时,单独抽离成函数,收窄调用入口,以便后续升级vue3

如ctx.root 还有ctx.refs

image.png

image.png

P7 贴图证明

1. 一些通用compositions

image.png

2. 项目vue和@vue/composition-api版本

image.png

Guess you like

Origin juejin.im/post/7031436439741169678