Electron+Vue3 MAC 版日历开发记录(28)——使用 Eslint 优化代码

1,715 阅读3分钟

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

今天还是继续昨天未完成的一个「专注页面」的重构:

专注页面重构

同样的,使用 NConfigProvider 包裹我们的子组件,让他们具备 theme 切换的功能:

  <n-config-provider
    :theme="themeValue"
  >
    <FanlyCountdownClock
      @finish="hideFocus"
    />
  </n-config-provider>

显示效果如下,但我们发现底下多出来一部分空白的。

因为我们之前是使用 document 的数据,容易受到页面切换缓存的影响,所以改为 window 自带的属性,获取全屏的高度:900 (本机器):

效果回来了:

eslint 的使用

本项目主要使用了 eslint 用于代码规范检测:

"lint": "eslint . --ext js,ts,vue",

每次都会有 error 的提示,这提示不会让我们把代码提交到 github 中,但避免不了会出现很多 warning的提示:

/Users/yemeishu/Documents/code/codes/fanlymenu/packages/services/LunarService.ts
  42:3  warning  Missing return type on function  @typescript-eslint/explicit-module-boundary-types

/Users/yemeishu/Documents/code/codes/fanlymenu/packages/services/TrayService.ts
   6:17  warning  Unexpected any. Specify a different type           @typescript-eslint/no-explicit-any
  32:11  warning  Argument 'fn' should be typed with a non-any type  @typescript-eslint/explicit-module-boundary-types
  32:15  warning  Unexpected any. Specify a different type           @typescript-eslint/no-explicit-any

/Users/yemeishu/Documents/code/codes/fanlymenu/packages/services/WeatherService.ts
  6:3   warning  Missing return type on function                          @typescript-eslint/explicit-module-boundary-types
  6:21  warning  Argument 'location' should be typed with a non-any type  @typescript-eslint/explicit-module-boundary-types
  6:31  warning  Unexpected any. Specify a different type                 @typescript-eslint/no-explicit-any53 problems (0 errors, 53 warnings)

我们发现有 53 个这样的 warning 提示,这虽然不是什么大问题,但要是我们按照「规范」来做修改,代码的可读性会提高不少,举一个例子:

/Users/yemeishu/Documents/code/codes/fanlymenu/packages/services/LunarService.ts
  42:3  warning  Missing return type on function  @typescript-eslint/explicit-module-boundary-types

如果我用 any 作为返回类型:

这个虽然是万能灵药,大家还是会提示 warning

最好的办法是写一个 interface 自定义类型:

export declare interface LunarServiceResult {
  nongliString: string,
  ganzhi: string[],
  yangliString: string,
  yi: string[],
  ji: string[],
}

然后,让返回的类型为 LunarServiceResult

这时候我们看看 yarn lint 提示少了这个 warning 了。

类似这样的问题,我们都可以这么处理。

接着看另一个问题:

/Users/yemeishu/Documents/code/codes/fanlymenu/packages/renderer/src/components/DateViewSub.vue
  101:5  warning  Prop 'weather' requires default value to be set  vue/require-default-prop

这类问题在于,我们组件的属性需要默认值。

解决此类问题,主要有两种方法:

  1. 顺着类型 Object 所需要的返回逻辑补充完整;
  2. 改 Object 为我们自定义的构造类型。

我们拿第一种举例(第二种方法,类似上面的案例做法)。

// 带有默认值的对象
propE: {
  type: Object,
  // 对象或数组默认值必须从一个工厂函数获取
  default() {
    return { message: 'hello' }
  }
},

按照这个,只需要带入一个默认返回工厂函数即可:

  props: {
    weather: {
      type: Object,
      default() {
        return {
          weatherNow: {
            icon: '100',
            temp: '30',
          },
        };
      },
    },
  },

我们执行看,这个 warning 也消失了~

相同的问题,相同的处理办法:

/Users/yemeishu/Documents/code/codes/fanlymenu/packages/renderer/src/components/DateViewSub.vue
  101:5  warning  Prop 'weather' requires default value to be set  vue/require-default-prop

再看一个相似的问题:

/Users/yemeishu/Documents/code/codes/fanlymenu/packages/renderer/src/components/SettingSub.vue
  210:5   warning  Prop 'location' requires default value to be set  vue/require-default-prop

增加默认的经纬度值:

location: {
  type: Object,
  default() {
    return {
      longitude: 114.52,
      latitude: 38.02,
    };
  },
},

使用 Provide / Inject 重构

其实上文发现一个变量:weather 在多个子组件出现,其实我们完全可以用 Provide / Inject 来代替 Prop 传递给子组件的。

改造开始:

// FullCalendarMain.vue
  setup() {
    // 使用 ref 保证 weather 可响应式
    const weather = ref({});
    provide('weather', weather);
    return {
      weather,
      ...
    };
  },
  
//子组件通过 inject 获取 weather

// FullcalendarSub.vue
  setup() {
    const weather = inject('weather');
    const store = useStore();
    const themeVars = ref(useThemeVars());
    return {
      weather,
      darkTheme,
      store,
      themeVars,
    };
  },
  
// WeatherSub.vue
  setup() {
    const weather = inject('weather', {
      weatherNow: {
        icon: '100',
        temp: '30',
      },
    });
    return {
      weather,
    };
  },

好了,我们这么操作就不用考虑 Prop Object 默认值的问题了。

小结

我们不断的去优化我们的代码,既保证了代码的质量和规范性,也让我们的代码经得住大家的推敲和使用。

未完待续!