浅谈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+iview实现文件上传
Nov 17 Vue.js
Vue router安装及使用方法解析
Dec 02 Vue.js
Vue如何实现验证码输入交互
Dec 07 Vue.js
vue祖孙组件之间的数据传递案例
Dec 07 Vue.js
vue 基于abstract 路由模式 实现页面内嵌的示例代码
Dec 14 Vue.js
vue动态设置路由权限的主要思路
Jan 13 Vue.js
vue使用lodop打印控件实现浏览器兼容打印的方法
Feb 07 Vue.js
vue实现拖拽进度条
Mar 01 Vue.js
vue3.0封装轮播图组件的步骤
Mar 04 Vue.js
Vue项目中如何封装axios(统一管理http请求)
May 02 Vue.js
详解Vue slot插槽
Nov 20 Vue.js
vue实现在data里引入相对路径
Jun 05 Vue.js
Vue.js 带下拉选项的输入框(Textbox with Dropdown)组件
vue backtop组件的实现完整代码
vue中三级导航的菜单权限控制
Mar 31 #Vue.js
vue3中的组件间通信
vue前端工程的搭建
vue中data改变后让视图同步更新的方法
vue3如何优雅的实现移动端登录注册模块
You might like
PHP6 先修班 JSON实例代码
2008/08/23 PHP
从PHP的源码中深入了解stdClass类
2014/04/18 PHP
PHP命名空间(namespace)的动态访问及使用技巧
2014/08/18 PHP
PHP入门教程之面向对象基本概念实例分析
2016/09/11 PHP
php实现自定义中奖项数和概率的抽奖函数示例
2017/05/26 PHP
PHP读取CSV大文件导入数据库的实例
2017/07/24 PHP
用PHP的反射实现委托模式的讲解
2019/03/22 PHP
PHP语言对接抖音快手小红书视频/图片去水印API接口源码
2020/08/11 PHP
javascript编程起步(第四课)
2007/02/27 Javascript
javascript各浏览器中option元素的表现差异
2011/04/07 Javascript
xmlhttp缓存清除的2种解决方法
2013/12/13 Javascript
js 去掉空格实例 Trim() LTrim() RTrim()
2014/01/07 Javascript
让JavaScript的Alert弹出框失效的方法禁止弹出警告框
2014/09/03 Javascript
jQuery插件实现大图全屏图片相册
2015/03/14 Javascript
通过伪协议解决父页面与iframe页面通信的问题
2015/04/05 Javascript
深入浅析JavaScript系列(13):This? Yes,this!
2016/01/05 Javascript
js获取元素下的第一级子元素的方法(推荐)
2017/03/05 Javascript
微信小程序实现给循环列表添加点击样式实例
2017/04/26 Javascript
深入理解Node中的buffer模块
2017/06/03 Javascript
layui-laydate时间日历控件使用方法详解
2018/11/15 Javascript
Angular使用Restful的增删改
2018/12/28 Javascript
微信小程序授权登录解决方案的代码实例(含未通过授权解决方案)
2019/05/10 Javascript
详解ECMAScript2019/ES10新属性
2019/12/06 Javascript
Python接收Gmail新邮件并发送到gtalk的方法
2015/03/10 Python
Python的爬虫包Beautiful Soup中用正则表达式来搜索
2016/01/20 Python
python先序遍历二叉树问题
2017/11/10 Python
python url 参数修改方法
2018/12/26 Python
Python后台开发Django的教程详解(启动)
2019/04/08 Python
Python实现操纵控制windows注册表的方法分析
2019/05/24 Python
python将三维数组展开成二维数组的实现
2019/11/30 Python
python实现高斯投影正反算方式
2020/01/17 Python
Jupyter打开图形界面并画出正弦函数图像实例
2020/04/24 Python
浅谈keras使用预训练模型vgg16分类,损失和准确度不变
2020/07/02 Python
Big Green Smile德国网上商店:提供各种天然产品
2018/05/23 全球购物
美国宠物护理专家:Revival Animal Health
2020/01/05 全球购物
InterProcessMutex实现zookeeper分布式锁原理
2022/03/21 Java/Android