浅谈vue2的$refs在vue3组合式API中的替代方法

2022-07-23,,,,

如果你有过vue2的项目开发经验,那么对$refs就很熟悉了。由于vue3的断崖式的升级,在vue3中如何使用$refs呢?想必有遇到过类似的问题,我也有一样的疑惑。通过搜索引擎和github,基本掌握如何使用$refs。在vue3中使用组合式api的函数ref来代替静态或者动态html元素的应用。

最近业余在学习vue3项目《蜡笔(crayon)管理模板:vue3 + vuex4 + ant design2》开发,这两天迭代推进了一点,实现了chart图表组件,写文章的时候发现提交代码的commit有错别字。

在vue3中使用组合式api的setup()方法的时候,无法正常使用this.$refs,但可以使用新的函数ref()。

下面代码摘自:https://github.com/quintiontang/crayon/blob/feat-dashboard/src/qtui/components/chart.vue

<template>
    <canvas ref="refchart" :height="setheight"></canvas>
</template>
<script>
import { definecomponent, onmounted, ref, inject, watch } from "vue";
import chart from "chart.js";
import { deepcopy } from "@/helper/index";
export default definecomponent({
    name: "qtchart",
    props: {
        type: {
            type: string,
            required: true,
            default: "line",
        },
        data: {
            type: object,
            required: true,
            default: () => ({}),
        },
        options: {
            type: object,
            default: () => ({}),
        },
        height: {
            type: number,
            default: 0,
        },
        refkey: {
            type: string,
            default: null,
        },
    },
    setup(props) {
        const refchart = ref();
        // 初始化方法
        const init = () => {
            const canvaschart = refchart.value?.getcontext("2d");
            const charthelper = new chart(canvaschart, {
                type: props.type,
                data: deepcopy(props.data),
                options: props.options,
            });
            watch(props, () => {
                charthelper.data = deepcopy(props.data);
                charthelper.options = props.options;
                charthelper.update();
            });
            // 附加一个实例给refchart
            refchart.value.instance = charthelper;
        };
        // 设置高度
        const setheight = () => {
            return {
                height: props.height,
            };
        };
        // 绑定一个实例,使用inject注入
        const bindinstance = () => {
            if (props.refkey) {
                const bind = inject(`bind[${props.refkey}]`);
                if (bind) {
                    bind(refchart.value);
                }
            }
        };
        onmounted(() => {
            bindinstance();
            init();
        });
        return {
            refchart,
            setheight,
        };
    },
});
</script>

这段代码完整的实现了一个图表组件chart,其中自定义了属性props,通过把参数传递给setup方法来使用其属性值。html中定义一个ref="refchart"来作为图表的dom对象,在setup方法中通过方法ref方法来定义响应式可变对象,并在setup函数结尾作为返回值。

const refchart = ref();

需要注意的是,返回值的属性名必须和html中的ref值一致。

下面代码是可以正常执行的。

<template>
    <canvas ref="refchart" :height="setheight"></canvas>
</template>
<script>
import { definecomponent, onmounted, ref, inject, watch } from "vue";
import chart from "chart.js";
import { deepcopy } from "@/helper/index";
export default definecomponent({
    name: "qtchart",
    props: {
        // ... 
    },
    setup(props) {
        const refchartbox = ref();
        // ...
        return {
            refchart:refchartbox,
        };
    },
});
</script>

下面的情况,会出现程序错误,无法达到预期效果。应为html中定义的ref="refchart"和setup返回的refchartbox不一致。

<template>
    <canvas ref="refchart" :height="setheight"></canvas>
</template>
<script>
import { definecomponent, onmounted, ref, inject, watch } from "vue";
import chart from "chart.js";
import { deepcopy } from "@/helper/index";
export default definecomponent({
    name: "qtchart",
    props: {
        // ... 
    },
    setup(props) {
        const refchartbox = ref();
        // ...
        return {
            refchartbox,
        };
    },
});
</script>

结论

本文只是简单的介绍ref方法的使用,正好在项目中用到,后续将继续边学边推进项目并做好笔记。

到此这篇关于浅谈vue2的$refs在vue3组合式api中的替代方法的文章就介绍到这了,更多相关vue3组合式api内容请搜索以前的文章或继续浏览下面的相关文章希望大家以后多多支持!

《浅谈vue2的$refs在vue3组合式API中的替代方法.doc》

下载本文的Word格式文档,以方便收藏与打印。