【青训营】- 跟着月影学 JavaScript学习笔记(三) 如何写好一个组件

206 阅读2分钟

这是我参与8月更文挑战的第7天,活动详情查看:8月更文挑战

承接上文

3.3 vue3写法

在vue3中, 变化最大的莫过于组合式Api, 使用它的原因请各位详细阅读官方文档

有了上篇文章中vue2写法的基础, 我们利用setup方法对其进行重构, 这个组件就命名为CarouselTwo.vue

第一步, 先加入空的setup函数:

export default defineComponent({
  name: 'CarouselTwo',
  props: {
    images: {
      type: Array as PropType<string[]>,
      required: true
    },
    cycle: {
      type: Number,
      default: () => {
        return 3000;
      }
    }
  },
  setup(props) {}
})

它的第一个参数为props, 这样便可以利用参数数据来进行书写

第二步, 创建响应式变量与普通变量:

export default defineComponent({
  setup(props) {
    const selectedIndex = ref(0);
    let timer: number | undefined = undefined;
  }
})

如何区分响应式变量和普通变量呢, 笔者浅显的看待是: 修改内容会影响页面渲染的, 即响应式变量

我们的轮播图代码较为简单, 只需要一个响应式变量selectedIndex

第三步, 书写组件方法:

很好理解, 我们只需要把methods里的内容在setup中进行声明实现:

export default defineComponent({
  setup(props) {
    const selectedIndex = ref(0);
    let timer: number | undefined = undefined;
    const getSelectedItemIndex = (): number => {
      return selectedIndex.value;
    };
    const getSelectedItem = (): string => {
      return props.images[selectedIndex.value];
    };
    const slideTo = (index: number): void => {
      selectedIndex.value = index;
    };
    const slidePrevious = (): void => {
      slideTo((props.images.length + selectedIndex.value - 1) % props.images.length);
    };
    const slideNext = (): void => {
      slideTo((selectedIndex.value + 1) % props.images.length);
    };
    const stop = (): void => {
      clearInterval(timer);
    };
    const start = (): void => {
      stop();
      timer = setInterval(() => slideNext(), props.cycle);
    };
  }
})

第四步, 增加mounted:

import { defineComponent, onMounted } from 'vue';

export default defineComponent({
  setup(props) {
    // 业务代码...
    onMounted(() => {
      start();
    });
  }
})

vue提供了onMounted, 用于在setup中创建类似于vue2中的mounted

最后一步, 返回需要的内容:

export default defineComponent({
  setup(props) {
    // 业务代码...
    return {
      selectedIndex,
      timer,
      getSelectedItem,
      getSelectedItemIndex,
      slideTo,
      slidePrevious,
      slideNext,
      stop,
      start
    }
  }
})

在setup函数最后, 返回的内容会直接挂载在组件实例上

适应vue2思路的理解, 就是将selectedIndex/timerdata, getSelectedItem等方法给methods

在vue2中其实也能做到这种效果, 笔者在公司项目中曾尝试过, 如想了解的小伙伴可以私聊, 就不展开说啦

至此为止, vue3的组件写法已全部完成, 除了将业务逻辑代码汇聚在一个setup函数外, 貌似并没有什么差别?

那么试想如下场景:

完成轮播图组件后, 公司需要制定一个客制化轮播页面, 除了刚才完成的基本业务逻辑外, 还需要其它附加内容

一个还好, 我们可以再把刚才类似的方法重写一遍

如果有两个/三个/无数个类似的轮播需求呢?每次仅仅是改动html代码或者很少的业务逻辑, 那必然会出现大片的相似代码

笔者的解决方案是, 将轮播这个行为抽象出来

下篇文章继续讲述vue3写法升级