浅谈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实现两个区域滚动条同步滚动
Dec 13 Vue.js
vue3弹出层V3Popup实例详解
Jan 04 Vue.js
详解Vue2的diff算法
Jan 06 Vue.js
vue element和nuxt的使用技巧分享
Jan 14 Vue.js
Vue如何实现变量表达式选择器
Feb 18 Vue.js
vue实现倒计时功能
Mar 24 Vue.js
详细聊聊vue中组件的props属性
Nov 02 Vue.js
Vue.js中v-for指令的用法介绍
Mar 13 Vue.js
vue自定义右键菜单之全局实现
Apr 09 Vue.js
vue打包时去掉所有的console.log
Apr 10 Vue.js
vue本地构建热更新卡顿的问题“75 advanced module optimization”完美解决方案
Aug 05 Vue.js
vue el-table实现递归嵌套的示例代码
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 REMOTE_ADDR之获取访客IP的代码
2008/04/22 PHP
PHP MySQL应用中使用XOR运算加密算法分享
2011/08/28 PHP
简单实现限定phpmyadmin访问ip的方法
2013/03/05 PHP
兼容PHP和Java的des加密解密代码分享
2014/06/26 PHP
基于thinkPHP实现的微信自定义分享功能示例
2016/09/23 PHP
php实现微信发红包功能
2018/07/13 PHP
Yii框架日志操作图文与实例详解
2019/09/09 PHP
javascript克隆对象深度介绍
2012/11/20 Javascript
关闭页面时window.location事件未执行的原因分析及解决方案
2014/09/01 Javascript
JavaScript和CSS交互的方法汇总
2014/12/02 Javascript
JS阻止事件冒泡行为和闭包的方法
2016/06/16 Javascript
关于Jquery中的bind(),on()绑定事件方式总结
2016/10/26 Javascript
jQuery异步提交表单实例
2017/05/30 jQuery
详解React服务端渲染从入门到精通
2019/03/28 Javascript
python使用rsa加密算法模块模拟新浪微博登录
2014/01/22 Python
使用Python编写简单的画图板程序的示例教程
2015/12/08 Python
Python中如何优雅的合并两个字典(dict)方法示例
2017/08/09 Python
python opencv之分水岭算法示例
2018/02/24 Python
解决vscode python print 输出窗口中文乱码的问题
2018/12/03 Python
VSCode Python开发环境配置的详细步骤
2019/02/22 Python
python实现银联支付和支付宝支付接入
2019/05/07 Python
关于pytorch中网络loss传播和参数更新的理解
2019/08/20 Python
全网最详细的PyCharm+Anaconda的安装过程图解
2021/01/25 Python
移动端HTML5 input常见问题(小结)
2020/09/28 HTML / CSS
英国高档时尚男装购物网站:MR PORTER
2016/08/09 全球购物
如何减少垃圾回收让内存更加有效使用
2013/10/18 面试题
生物技术毕业生自荐信
2013/10/23 职场文书
《口技》教学反思
2014/02/21 职场文书
前处理组长岗位职责
2014/03/01 职场文书
秋天的怀念教学反思
2014/04/28 职场文书
国际语言毕业生求职信
2014/07/08 职场文书
工人先锋号事迹材料
2014/12/24 职场文书
后进生评语大全
2015/01/04 职场文书
《牧场之国》教学反思
2016/02/22 职场文书
诉讼和解协议书
2016/03/23 职场文书
导游词之西安大清真寺
2019/12/17 职场文书