【问题标题】:Multiple Vue 3 watchers & Typescript ... how to use?多个 Vue 3 观察者和 Typescript ......如何使用?
【发布时间】:2021-10-10 14:51:36
【问题描述】:

注意我正在使用@vueuse/core 库来获取以下示例的一些值,但我相信这个问题的库知识是没有实际意义的。

我有以下三重观察者:

// Reactive Mouse Positionining
const { x, y } = useMouse()

//  Detect if the Mouse has been pressed:
const { pressed } = useMousePressed({ 
  target: celestiaSkyViewerRoot, 
  touch: true 
})

watch([pressed, x, y], ([newPressed, newX, newY], [prevPressed, prevX, prevY]) => {
  if (showConstellations.value) {
    if (!newPressed && newX !== prevX) {
      activeConstellation.value = getActiveConstellation(newX, newY)
    }
  }

  dragging.value = pressed.value

  if (newPressed && newX !== prevX) {
    azimuthalOffset.value -= (newX - prevX) / 6
  }
})

但是,我发现出现以下 Typescript 错误:

对于newX,相关线路:activeConstellation.value = getActiveConstellation(newX, newY)

Argument of type 'number | boolean' is not assignable to parameter of type 'number'. Type 'boolean' is not assignable to type 'number'.

对于newX,相关线路:azimuthalOffset.value -= (newX - prevX) / 6

The left-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type.

但是,Vetur 仅显示newY 的问题,与以下行有关:azimuthalOffset.value -= (newX - prevX) / 6

The right-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type.

有人知道可能的解决方案吗?从本质上讲,这些错误正在停止重新加载我的开发服务器......而且它正在成为一个令人沮丧的开发瓶颈......

【问题讨论】:

    标签: javascript typescript vuejs3 vue-composition-api vetur


    【解决方案1】:

    我找不到函数的类型定义,你也没有提供一个可行的例子,所以我只能猜测:

    错误说newX,newY,prevX,prevY 的类型为number | boolean,但我不能告诉你为什么。根据您的代码编写方式,您希望它们仅为 number

    三种解决方案的行为都略有不同,但它们都应该使用 typescript 进行编译:

    如果任何变量不是number,则不要继续执行:

    watch([pressed, x, y], ([newPressed, newX, newY], [prevPressed, prevX, prevY]) => {
      if (typeof newX !== 'number' || typeof newY !== 'number' ||
          typeof prevX !== 'number' || typeof prevY !== 'number') return;
      if (showConstellations.value) {
      ...
    

    如果变量的类型不是number,则使用默认值:

    watch([pressed, x, y], ([newPressed, newX, newY], [prevPressed, prevX, prevY]) => {
      if (typeof newX !== 'number') newX = 0;
      if (typeof newY !== 'number') newY = 0;
      if (typeof prevX !== 'number') prevX = 0;
      if (typeof prevY !== 'number') prevY = 0;
      if (showConstellations.value) {
      ...
    

    强制这些变量为number。如果这些变量中的任何一个实际上可以是boolean(我不确定),那么在这种情况下,这将导致意外行为:

    watch([pressed, x, y], ([newPressed, newX, newY], [prevPressed, prevX, prevY]) => {
      ...
        activeConstellation.value = getActiveConstellation(newX as number, newY as number);
      ...
        azimuthalOffset.value -= ((newX as number) - (prevX as number)) / 6
      
    

    【讨论】:

      【解决方案2】:

      如果有人像我一样陷入困境,这是以下解决方案,无需根据上述答案检查任何类型:

      watch([pressed, x, y] as const, ([newPressed, newX, newY], [_, prevX, prevY]) => {
         ... // do something here
      })
      

      因此,您只需将 Vue 3 观察者的多个数组强制转换为:[] as const

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-04-13
        • 1970-01-01
        • 2021-08-12
        • 2013-03-05
        • 2012-02-15
        • 2023-02-17
        • 2020-03-26
        相关资源
        最近更新 更多