Vue3 / typescript: 如何为二维数组类型组件属性进行类型定义

huangapple go评论65阅读模式
英文:

Vue3 / typescript: how to type component props for 2d array

问题

I am converting an existing vue project (written in JS) to Typescript. I am mostly getting on well, but am having a problem with passing an array as props to a component.

I am using Composition API / SFC.

For one component (which doesn't need an array), I have this structure:

<script setup lang="ts">
  import type { TrackTile } from '../../env.d';

  interface Props {
    tile: TrackTile,
    item: number
  }
  const props = defineProps<Props>()
  console.log('keyItem script setup');
  console.log(props.tile);
</script>

This transpiles without errors and then runs fine, so I assume my basic syntax is OK here.

But another component mainGrid needs to be given an array of TrackCell types:

<script setup lang="ts">
  import type { TrackCell } from '../../env.d';
  interface Props {
    grid: TrackCell[][];
  }
  const props = defineProps<Props>()

  console.log('mainGrid script setup');
  console.log(props.grid[0][0]);
</script>

The component is called from its parent like this:

<mainGrid :grid="trackGrid">
</mainGrid>

In this case, I get an error that props.grid[0] is undefined.

As a check to ensure that the trackGrid array (and its constituent trackCells) was defined and populated correctly, I temporarily moved the template for the mainGrid component into its parent, and everything then works as expected. So it appears that it's just the defineProps section which is incorrect.

trackGrid is reactive:

export const trackGrid: TrackCell[][] = reactive([]);
英文:

I am converting an existing vue project (written in JS) to Typescript. I am mostly getting on well, but am having a problem with passing an array as props to a component.
I am using Composition API / SFC.

For one component (which doesn't need an array), I have this structure:

&lt;script setup lang=&quot;ts&quot;&gt;
  import type { TrackTile } from &#39;../../env.d&#39;;

  interface Props {
    tile: TrackTile,
    item: number
  }
  const props = defineProps&lt;Props&gt;()
  console.log(&#39;keyItem script setup&#39;);
  console.log(props.tile);

&lt;/script&gt;

This transpiles without errors and then runs fine, so I assume my basic syntax is OK here.
But another component mainGrid needs to be given an array of TrackCell types:

&lt;script setup lang=&quot;ts&quot;&gt;

  import type { TrackCell } from &#39;../../env.d&#39;;
  interface Props {
    grid: TrackCell[][];
  }
  const props = defineProps&lt;Props&gt;()

  console.log(&#39;mainGrid script setup&#39;);
  console.log(props.grid[0][0]);
    
&lt;/script&gt;

The component is called from its parent like this:

 &lt;mainGrid :grid = trackGrid&gt;
 &lt;/mainGrid&gt;

In this case I get an error that props.grid[0] is undefined.

As a check to ensure that the trackGrid array (and its constituent trackCells) was defined and populated correctly, I temporarly moved the template for the mainGrid component into its parent, and everything then works as expected. So it appears that it's just the `defineProps' section which is incorrect.

trackGrid is reactive:

export const trackGrid: TrackCell[][] = reactive([] );

答案1

得分: 1

我认为这不是一个 TypeScript 错误,很可能问题出现在日志语句中:

console.log(props.grid[0][0]);

可能在初始化后 `grid` 是一个空数组?

尝试

console.log(props.grid[0]?.[0]);

或者完全删除这个语句


----------

作为一个快速修复,你可以用一个空行初始化 `trackGrid`:

export const trackGrid: TrackCell[][] = reactive([[]]);

英文:

I don't think that's a typescript error, most likely the problem occurs in the log statement:

console.log(props.grid[0][0]);

Probably grid is an empty array after initialization?

Try

console.log(props.grid[0]?.[0]);

or remove the statement altogether


As a quick fix, you could initialize trackGrid with an empty row:

export const trackGrid: TrackCell[][] = reactive([[]]);

答案2

得分: 0

Here's the translated content:

原来,与组件的 props 提交的内容没有问题!
我添加了 console.log(props.grid[0][0]); 来解决模板中使用的网格单元格在使用时未定义的问题。
但那是一个愚蠢的做法,因为当然组件的 <setup> 在数据被获取之前(在 onBeforeMount 中)被调用。

在添加了错误的调试行之后,我已经纠正了实际的错误:我将数组的声明从

export const trackGrid: TrackCell[][] = reactive([...Array(8)].map(_=>Array(8)) );

更改为

export const trackGrid: TrackCell[][] = reactive([] );

但然后我没有移除错误的调试日志!

仍然不确定是否应该是

export const trackGrid: TrackCell[][] = reactive([] );

还是

export const trackGrid: TrackCell[][] = reactive([[]] );

因为这两种方式似乎都可以工作。

无论如何,我希望我的原始问题可以帮助将来使用 TS 与 Vue 处理数组的人。

英文:

Turns out there wasn't any problem with the component props as posted!
I added console.log(props.grid[0][0]); to solve a problem with the grid cells being undefined when they were used in the template.
But that was a silly thing to do because of course the component's &lt;setup&gt; is called before the data has been fetched (in onBeforeMount).

After adding that erroneous debug line, I had corrected the actual error: I changed the declation of the array from

export const trackGrid: TrackCell[][] = reactive([...Array(8)].map(_=&gt;Array(8)) );

to

export const trackGrid: TrackCell[][] = reactive([] );

but then I didn't remove the erroneous debug log!

Still not sure through if it should be

export const trackGrid: TrackCell[][] = reactive([] );

or

export const trackGrid: TrackCell[][] = reactive([[]] );

as both seem to work.

Anyway I hope that my original question may help someone in the future deal with arrays using TS with Vue.

huangapple
  • 本文由 发表于 2023年5月11日 06:55:54
  • 转载请务必保留本文链接:https://go.coder-hub.com/76223077.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定