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


Posted in Vue.js onApril 18, 2021

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

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

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

在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内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Vue.js 相关文章推荐
解决vue页面刷新,数据丢失的问题
Nov 24 Vue.js
vue-router定义元信息meta操作
Dec 07 Vue.js
Vue实现小购物车功能
Dec 21 Vue.js
Vue看了就会的8个小技巧
Jan 21 Vue.js
vue如何使用rem适配
Feb 06 Vue.js
vue+django实现下载文件的示例
Mar 24 Vue.js
vite+vue3.0+ts+element-plus快速搭建项目的实现
Jun 24 Vue.js
Vue项目打包、合并及压缩优化网页响应速度
Jul 07 Vue.js
Vue3如何理解ref toRef和toRefs的区别
Feb 18 Vue.js
Vue监视数据的原理详解
Feb 24 Vue.js
vue实现移动端div拖动效果
Mar 03 Vue.js
Vue中使用import进行路由懒加载的原理分析
Apr 01 Vue.js
Vue.js 带下拉选项的输入框(Textbox with Dropdown)组件
vue backtop组件的实现完整代码
vue中三级导航的菜单权限控制
Mar 31 #Vue.js
vue3中的组件间通信
vue前端工程的搭建
vue中data改变后让视图同步更新的方法
vue3如何优雅的实现移动端登录注册模块
You might like
第十五节--Zend引擎的发展
2006/11/16 PHP
PHP编程中八种常见的文件操作方式
2006/11/19 PHP
理解和运用PHP中的多态性[译]
2011/08/02 PHP
PHP使用NuSOAP调用Web服务的方法
2015/07/18 PHP
学习thinkphp5.0验证类使用方法
2017/11/16 PHP
PHP检查URL包含特定字符串实例方法
2019/02/11 PHP
jQuery 事件队列调整方法
2009/09/18 Javascript
理解Javascript_03_javascript全局观
2010/10/11 Javascript
AeroWindow 基于JQuery的弹出窗口插件
2011/06/27 Javascript
Jquery attr(&quot;checked&quot;) 返回checked或undefined 获取选中失效
2013/10/10 Javascript
jQuery动画特效实例教程
2014/08/29 Javascript
JavaScript实现同步于本地时间的动态时间显示方法
2015/02/02 Javascript
jQuery实现图片加载完成后改变图片大小的方法
2016/03/29 Javascript
javascript类型系统——undefined和null全面了解
2016/07/13 Javascript
微信小程序 聊天室简单实现
2017/04/19 Javascript
使用express+multer实现node中的图片上传功能
2018/02/02 Javascript
JS实现利用闭包判断Dom元素和滚动条的方向示例
2019/08/26 Javascript
小程序实现左滑删除的效果的实例代码
2020/10/19 Javascript
[06:45]DOTA2卡尔工作室 英雄介绍幻影长矛手篇
2013/07/12 DOTA
[20:21]《一刀刀一天》第十六期:TI国际邀请赛正式打响,总奖金超过550万
2014/05/23 DOTA
Django imgareaselect手动剪切头像实现方法
2015/05/26 Python
使用Python的urllib2模块处理url和图片的技巧两则
2016/02/18 Python
Pandas之drop_duplicates:去除重复项方法
2018/04/18 Python
Python字符串通过'+'和join函数拼接新字符串的性能测试比较
2019/03/05 Python
python logging.basicConfig不生效的原因及解决
2020/02/20 Python
python中如何打包用户自定义模块
2020/09/23 Python
德国奢侈品网上商城:Mytheresa
2016/08/24 全球购物
优秀家长自荐材料
2014/08/26 职场文书
法律专业大学生职业生涯规划书:向目标一步步迈进
2014/09/22 职场文书
毕业生实习期转正自我鉴定
2014/09/26 职场文书
学习退步检讨书
2014/09/28 职场文书
婚前协议书范本两则
2014/10/16 职场文书
升职自荐信怎么写
2015/03/05 职场文书
python 如何做一个识别率百分百的OCR
2021/05/29 Python
教你用Java在个人电脑上实现微信扫码支付
2021/06/13 Java/Android
Redis之RedisTemplate配置方式(序列和反序列化)
2022/03/13 Redis