浅谈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的tree组件
Dec 03 Vue.js
通过vue.extend实现消息提示弹框的方法记录
Jan 07 Vue.js
vue 页面跳转的实现方式
Jan 12 Vue.js
vue 组件基础知识总结
Jan 26 Vue.js
Vue实现圆环进度条的示例
Feb 06 Vue.js
vue+flask实现视频合成功能(拖拽上传)
Mar 04 Vue.js
vue3如何优雅的实现移动端登录注册模块
Mar 29 Vue.js
Vue+TypeScript中处理computed方式
Apr 02 Vue.js
vue 数字翻牌器动态加载数据
Apr 20 Vue.js
vue3 自定义图片放大器效果的示例代码
Jul 23 Vue.js
el-table-column 内容不自动换行的解决方法
Aug 14 Vue.js
Vue.js 带下拉选项的输入框(Textbox with Dropdown)组件
vue backtop组件的实现完整代码
vue中三级导航的菜单权限控制
Mar 31 #Vue.js
vue3中的组件间通信
vue前端工程的搭建
vue中data改变后让视图同步更新的方法
vue3如何优雅的实现移动端登录注册模块
You might like
php输出echo、print、print_r、printf、sprintf、var_dump的区别比较
2013/06/21 PHP
Zend Framework动作助手Url用法详解
2016/03/05 PHP
关于IE、Firefox、Opera页面呈现异同 写脚本很痛苦
2009/08/28 Javascript
HTML颜色选择器实现代码
2010/11/23 Javascript
extjs中form与grid交互数据(record)的方法
2013/08/29 Javascript
JavaScript学习笔记之检测客户端类型是(引擎、浏览器、平台、操作系统、移动设备)
2015/12/03 Javascript
如何解决easyui自定义标签 datagrid edit combobox 手动输入保存不上
2015/12/26 Javascript
JavaScript中setTimeout和setInterval函数的传参及调用
2016/03/11 Javascript
JavaScript对Json的增删改属性详解
2016/06/02 Javascript
javascript闭包概念简单解析(推荐)
2016/06/03 Javascript
jquery获取select,option所有的value和text的实例
2017/03/06 Javascript
基于vue实现swipe分页组件实例
2017/05/25 Javascript
对于Javascript 执行上下文的全面了解
2017/09/05 Javascript
微信小程序之滑动页面隐藏和显示组件功能的实现代码
2020/06/19 Javascript
用Python制作在地图上模拟瘟疫扩散的Gif图
2015/03/31 Python
python重试装饰器的简单实现方法
2019/01/31 Python
pybind11在Windows下的使用教程
2019/07/04 Python
python使用 cx_Oracle 模块进行查询操作示例
2019/11/28 Python
css3图片边框border-image的用法
2017/06/30 HTML / CSS
HTML5本地存储和本地数据库实例详解
2017/09/05 HTML / CSS
微信端html5页面调用分享接口示例
2018/03/14 HTML / CSS
HTML5实现自带进度条和滑块滑杆效果
2018/04/17 HTML / CSS
美津浓美国官网:Mizuno美国
2018/08/07 全球购物
介绍一下Linux文件的记录形式
2013/09/29 面试题
大学生个人自荐信
2014/02/24 职场文书
《九寨沟》教学反思
2014/04/08 职场文书
幼儿园小班评语
2014/04/18 职场文书
慈善晚会策划方案
2014/05/14 职场文书
主题团日活动总结
2014/06/25 职场文书
竞选大学学委演讲稿
2014/09/13 职场文书
2014年体育工作总结
2014/11/24 职场文书
社区党员干部承诺书
2015/05/04 职场文书
2015小学新教师个人工作总结
2015/10/14 职场文书
学生会2016感恩节活动小结
2016/04/01 职场文书
Win11怎样将锁屏账户头像图片改成动画视频
2021/11/21 数码科技
高并发下Redis如何保持数据一致性(避免读后写)
2022/03/18 Redis