Vue 3组合API中的默认属性是未定义的(TS)

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

Default props in Vue 3 composition api are undefined (TS)

问题

如果我不传递一个值,那么该属性将只是undefined,而不是采用默认值。

例如switchViewactiveView。我已经像这样定义了props:

interface Props {
  config: {
    switchView?: boolean;
    activeView?: number;
    urls: {
      someUrl: string;
    };
    labels?: {
      someLabels: string;
    };
  };
}

const props = withDefaults(defineProps<Props>(), {
  config: () => ({
    switchView: true,
    activeView: 0,
    urls: {
      someUrl: '',
    },
    labels: {
      someLabel: '',
    },
  }),
});

然后在父组件中,我像这样传递了prop config对象:

const config = {
  urls: {
    someUrl: '/example',
  },
  labels: {
    someLabel: 'Example label',
  },
};

在我的Vue Dev Tools中,我只看到传递的props,但没有看到我设置的默认值。
我做错了什么?

英文:

If I don't pass a value, the prop is just undefined, instead of taking the default value.

For example switchView and activeView. I have defined the props like this:

interface Props {
  config: {
    switchView?: boolean;
    activeView?: number;
    urls: {
      someUrl: string;
    };
    labels?: {
      someLabels: string;
    };
  };
}

const props = withDefaults(defineProps&lt;Props&gt;(), {
  config: () =&gt; ({
    switchView: true,
    activeView: 0,
    urls: {
      someUrl: &#39;&#39;,
    },
    labels: {
      someLabel: &#39;&#39;,
    },
  }),
});

And in the parent component, I'm passing the prop config object like so:

const config = {
  urls: {
    someUrl: &#39;/example&#39;,
  },
  labels: {
    someLabel: &#39;Example label&#39;,
  },
};

And in my Vue Dev Tools I only see the passed props, but none of the default values that I've set.
What am I doing wrong?

If I pass them in the config object, I get them as a prop. But I expect if I don't pass those optional values, then the defaults will take place.

答案1

得分: 1

我找到了问题。Vue在嵌套的props方面存在问题,更具体地说,父级配置对象是问题所在。
通过将其移除,它可以正常工作。

interface Props {
  switchView?: boolean;
  activeView?: number;
  urls: {
    someUrl: string;
  };
  labels?: {
    someLabel: string;
  };
}

const props = withDefaults(defineProps<Props>(), {
  switchView: true,
  activeView: 0,
  urls: () => ({
    someUrl: '',
  }),
  labels: () => ({
    someLabel: '',
  }),
});
英文:

I found the issue. Vue has a problem with nested props, more specifically, the parent config object is the problem.
By removing it it works fine.

interface Props {
  switchView?: boolean;
  activeView?: number;
  urls: {
    someUrl: string;
  };
  labels?: {
    someLabel: string;
  };
}

const props = withDefaults(defineProps&lt;Props&gt;(), {
  switchView: true,
  activeView: 0,
  urls: () =&gt; ({
    someUrl: &#39;&#39;,
  }),
  labels: () =&gt; ({
    someLabel: &#39;&#39;,
  }),
});

答案2

得分: 0

所以,当你使用 switchView?: boolean 来声明接口中的属性时,基本上意味着接口中的 property 是可选的。

所以,JavaScript 不关心它的值,目前只关心是否应用了类型强制。如果它是可选的,而你没有传递它或者不小心漏掉了它。

JavaScript 不会抱怨,因为它是可选的。如果不是可选的,JavaScript 会迅速抱怨对象缺少 'switchView' 属性。

简而言之,它与其值没有关系。所以如果你不传递它,它总是会取得 undefined

当你创建 config 时,你需要使用 withDefaults

这样,config 变量会经过初始化过程,并在声明时被赋予默认值。

可能是这样的:

let config: Props = withDefaults({}) // 这样返回具有默认值的初始对象
// 更新对象
config.urls.someUrl = "/example";
config.labels.someLabel = "Example label";

简而言之,你的初始化过程中缺少一些步骤。

英文:

So, when you use switchView?: boolean to declare the property in the interface. It basically means the property is optional in the interface.

So, JS does not care about it value, at the moment it only care about it's type enforcement to be applied or not. If it optional and you are not passing it or by mistake missed it.

JS never complain about it because it optional. If it is not optional. JS quickly complain 'switchView' is missing on the object.

TLDR version: It doesn't have any relation with its value. So if you do not pass it. It always take undefined

You need to use withDefaults when you are creating the config.
So that config variable go through the initialisation process and assigned the default value at the time of declaration.

Might be something like this

let config: Props = withDefaults({}) // so this return initial object with default value
// update the object
config.urls.someUrl = &quot;/example&quot;;
config.labels.someLabel = &quot;Example label&quot;;

In short your initialisation process is missing in between.

huangapple
  • 本文由 发表于 2023年7月3日 22:53:28
  • 转载请务必保留本文链接:https://go.coder-hub.com/76605885.html
匿名

发表评论

匿名网友

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

确定