这是我参与更文挑战的第29天,活动详情查看: 更文挑战
其实在重构过程,也是自我学习和了解 Vue 3 的一些深入知识的过程。比如:
在我们的 Location 坐标通过 computed
后:
provide() {
return {
flocation: computed(() => this.store.state.location),
};
},
复制代码
我们在子组件中拿到这个数据:
const flocation: ComputedRef<FLocation> | undefined = inject('flocation');
console.log(flocation);
const longitude = flocation?.value.longitude;
const latitude = flocation?.value.latitude;
复制代码
得到的数据类型是:ComputedRefImpl
类型,这时候可以通过定义类型:ComputedRef<FLocation> | undefined
来匹配,之前我们都出一刀切直接用 any
。现在看起来严谨多了。
Template Refs
说回今天的核心:使用 Template Refs 来做重构,先看看这个案例:
// FullcalendarSub.vue
events(): void {
const calendarArray = this.$refs['fullcalendar'] as any;
const calendarApi = calendarArray.getApi();
calendarApi.addEventSource(this.events);
},
},
methods: {
updateColors() {
this.calendarOptions.eventColor = this.themeVars.primaryColor;
},
updateView() {
const calendarArray = this.$refs['fullcalendar'] as any;
console.log(calendarArray);
const calendarApi = calendarArray.getApi();
const viewContent = this.dayCellNewContent();
calendarApi.changeView('dayGridMonth', viewContent['dayGridMonth']);
// 这种成本可能更高
// this.calendarApi.render();
},
复制代码
在多处都使用到了 const calendarArray = this.$refs['fullcalendar'] as any;
,而这里也是使用了 $refs
,自从 Vue 3 开始不建议使用 this 了,而提供了本文开始说的 Template Refs
。
自定义 fullcalendar 变量
<full-calendar
ref="fullcalendar"
:options="calendarOptions"
>
<template #eventContent="arg">
<i>{{ arg.event.title }}</i>
</template>
</full-calendar>
复制代码
在 setup
自定义一个和 ref 一样的变量名:
setup() {
const weather = inject('weather');
const store = useStore();
const themeVars = ref(useThemeVars());
const fullcalendar = ref(null);
onMounted(() => {
// the DOM element will be assigned to the ref after initial render
console.log(fullcalendar.value);// <div>This is a root element</div>
});
return {
weather,
darkTheme,
store,
themeVars,
fullcalendar,
};
},
复制代码
我们看看 mounted 后是不是可以拿到数据了:
获取 FullCalendar API
现在就可以重构上述的代码,用一个统一变量拿到我们的 FullCalendar API。
let fullcalendarApi = ref<InstanceType<typeof CalendarApi>>();
onMounted(() => {
fullcalendarApi = Object.getOwnPropertyDescriptor(fullcalendar.value, 'getApi')?.value();
});
复制代码
注:这里我是有 Proxy 直接获取函数,老报错。有知道方法的伙伴告诉我,我太缺乏 vue3 Proxy 相关知识了.
所以,我采用了 Object.getOwnPropertyDescriptor
,拿到我们所需要的 CalendarApi 了。
重构
对于之前的方法里,我直接可调用:
events(): void {
if (this.fullcalendarApi == null) {
this.fullcalendarApi = Object.getOwnPropertyDescriptor(this.fullcalendar, 'getApi')?.value();
}
this.fullcalendarApi.addEventSource(this.events as EventSourceInput);
},
updateView() {
if (this.fullcalendarApi == null) {
this.fullcalendarApi = Object.getOwnPropertyDescriptor(this.fullcalendar, 'getApi')?.value();
}
const viewContent = this.dayCellNewContent();
this.fullcalendarApi.changeView('dayGridMonth', viewContent['dayGridMonth'] as DateRangeInput | DateInput);
},
复制代码
注:这里 this.fullcalendarApi 这个只我老拿到的是
null
,有知道原因的伙伴麻烦告知~
小结
今天零零碎碎修改了一些 warning,降了 20 两个,有待于进一步优化。
未完待续!
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END