Electron+Vue3 MAC 版日历开发记录(29)——知识篇使用Template Refs

这是我参与更文挑战的第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
喜欢就支持一下吧
点赞0 分享