vue2的$refs在vue3组合式API中的替代方法
如果你有过vue2的项目开发经验,那么对$refs
就很熟悉了。由于vue3的断崖式的升级,在vue3中如何使用$refs
呢?想必有遇到过类似的问题,我也有一样的疑惑。通过搜索引擎和github,基本掌握如何使用$refs
。在vue3中使用组合式API的函数ref
来代替静态或者动态html元素的应用。
最近业务在学习vue3项目《蜡笔(Crayon)管理模板:Vue3 + Vuex4 + Ant Design2》开发,这两天迭代推进了一点,实现了chart
图表组件,写文章的时候发现提交代码的commit
有错别字。
在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
方法的使用,正好在项目中用到,后续将继续边学边推进项目并做好笔记。