浅谈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使用Element实现增删改查+打包的步骤
Nov 25 Vue.js
实用的 vue tags 创建缓存导航的过程实现
Dec 03 Vue.js
用vue设计一个日历表
Dec 03 Vue.js
vue中如何自定义右键菜单详解
Dec 08 Vue.js
Vue.extend 登录注册模态框的实现
Dec 29 Vue.js
基于Vue2实现移动端图片上传、压缩、拖拽排序、拖拽删除功能
Jan 05 Vue.js
vue集成一个支持图片缩放拖拽的富文本编辑器
Jan 29 Vue.js
详解Vue的sync修饰符
May 15 Vue.js
vue-element-admin项目导入和导出的实现
May 21 Vue.js
vue+echarts实现多条折线图
Mar 21 Vue.js
vue-cli3.0修改打包后的文件名和文件地址,打包后本地运行报错解决
Apr 06 Vue.js
Vue OpenLayer测距功能的实现
Apr 20 Vue.js
Vue.js 带下拉选项的输入框(Textbox with Dropdown)组件
vue backtop组件的实现完整代码
vue中三级导航的菜单权限控制
Mar 31 #Vue.js
vue3中的组件间通信
vue前端工程的搭建
vue中data改变后让视图同步更新的方法
vue3如何优雅的实现移动端登录注册模块
You might like
删除无限分类并同时删除它下面的所有子分类的方法
2010/08/08 PHP
php的ddos攻击解决方法
2015/01/08 PHP
PHP实现GIF图片验证码
2015/11/04 PHP
PDO::rollBack讲解
2019/01/29 PHP
Laravel中如何轻松容易的输出完整的SQL语句
2020/07/26 PHP
js利用div背景,做一个竖线的效果。
2008/11/22 Javascript
jquery遍历筛选数组的几种方法和遍历解析json对象
2013/12/13 Javascript
使用pjax实现无刷新更改页面url
2015/02/05 Javascript
Javascript中使用parseInt函数需要注意的问题
2015/04/02 Javascript
JavaScript 模块化编程(笔记)
2015/04/08 Javascript
javascript中Date()函数在各浏览器中的显示效果
2015/06/18 Javascript
让你一句话理解闭包(简单易懂)
2016/06/03 Javascript
原生js获取元素样式的简单方法
2016/08/06 Javascript
AngularJS国际化详解及示例代码
2016/08/18 Javascript
Vue.js使用v-show和v-if的注意事项
2016/12/13 Javascript
angularjs实现简单的购物车功能
2017/09/21 Javascript
vue-router beforeEach跳转路由验证用户登录状态
2018/12/26 Javascript
Node.js对MongoDB进行增删改查操作的实例代码
2019/04/18 Javascript
原生JS实现天气预报
2020/06/16 Javascript
[51:53]DOTA2-DPC中国联赛 正赛 RNG vs Dragon BO3 第二场 1月24日
2021/03/11 DOTA
python进阶教程之函数对象(函数也是对象)
2014/08/30 Python
python实现获取序列中最小的几个元素
2014/09/25 Python
Python函数式编程
2017/07/20 Python
Python实现的双色球生成功能示例
2017/12/18 Python
Python3.5 Json与pickle实现数据序列化与反序列化操作示例
2019/04/29 Python
tensorflow 初始化未初始化的变量实例
2020/02/06 Python
Python Selenium截图功能实现代码
2020/04/26 Python
基于Python-Pycharm实现的猴子摘桃小游戏(源代码)
2021/02/20 Python
x-ua-compatible content=”IE=7, IE=9″意思理解
2013/07/22 HTML / CSS
全球地下的服装和态度:Slam Jam
2018/02/04 全球购物
战友聚会邀请函
2014/01/18 职场文书
个人廉政承诺书
2015/04/28 职场文书
观后感开头
2015/06/19 职场文书
餐厅服务员管理制度
2015/08/05 职场文书
聊聊Python中关于a=[[]]*3的反思
2021/06/02 Python
python模块与C和C++动态库相互调用实现过程示例
2021/11/02 Python