如何从 typescript 访问 vue 中组件的 props

Posted

技术标签:

【中文标题】如何从 typescript 访问 vue 中组件的 props【英文标题】:How to access props of a component in vue from typescript 【发布时间】:2020-09-22 21:16:52 【问题描述】:

我正在尝试从另一个 vue 组件(父级)访问下面我的 vue 组件(子级)中的道具。我基本上是在用户从下拉菜单中选择一个选项后尝试将 :selected 值重置为 null。

 <template>
    <ul class="dropdown-menu" v-if="showMenu">
      <li v-for="option in options">
        <a href="javascript:void(0)"></a>
      </li>
    </ul>
  </div>
</template>
<script>
import  directive as onClickaway  from "vue-clickaway";
export default 
  directives: 
    onClickaway
  ,
  data() 
    return 
      showMenu: false,
      placeholderText: "Please select an item"
    ;
  ,
  props: 
    selected: ,
    placeholder: [String],
  ,
  ,

  methods: 
    updateOptions(option) 
      this.showMenu = false;
      this.$emit("input", this.selectedOption);
    ,
  
;

</script>

【问题讨论】:

父组件中updateOption()的代码是什么样的? @LannyBose 哦,父组件中没有代码,它来自子组件。 对不起,我的意思是onColourSelection @LannyBose public onColourSelection(val: any) this.colourId = val.id; 差不多了,colourOptions 是以数组形式从 API 获得的颜色。 【参考方案1】:

我在您的父模板中注意到的第一件事是您将selected 属性硬编码为,这意味着它永远不会改变。此外,您会立即丢弃孩子挂载钩子中的选定道具:

  mounted() 
    this.selectedOption = this.selected;
  

...这意味着即使您从父级更改道具,它也不会做任何事情。

我将建议重构您的代码以使用 v-model,使 Dropdown 从不实际存储所选值,而是依赖父级存储状态 (link to Vue docs)。

Parent.vue

<template>
  <dropdown
    // other options skipped for clarity

    v-model="selected"
  ></dropdown>
</template>

<script>
export default 
  data() 
    return 
      selected: undefined
    
  

</script>

正如您在 Vue 文档中看到的,v-model 只是传递名为 value 的道具并监听名为 input 的事件的约定。所以在你的孩子身上,你需要稍微重构一下。具体来说,我们要去掉你的中介值selectedOption

Child.vue

<template>
  <!-- other divs hidden for clarity -->

  <input
    @click="toggleMenu()"
    v-model="value[attr]" // I am unsure that this is the right choice 
    type="text">

    <ul class="dropdown-menu" v-if="showMenu">
      <li v-for="option in options">
        <a href="javascript:void(0)" @click="updateOption(option)"> option[attr] </a>
      </li>
    </ul>
  </div>
</template>

<script>
export default 
  data() 
    return 
      showMenu: false,
      placeholderText: "Please select an item"
    ;
  ,
  props: 
    value: , // changed from selected
    attr: String,
  ,

  methods: 
    updateOption(option) 
      this.showMenu = false;
      this.$emit('input', this.selectedOption);
    ,
  
;

</script>

我不确定您的预期行为的唯一地方是您的 Child &lt;input&gt; 标签。您有一个用于输入的 v-model,但是当有人输入该输入(例如搜索颜色名称或其他)时,您似乎没有做任何事情。由于输入该输入当前不执行任何操作。将其设置为 看起来 像输入但实际上不能输入的 &lt;div&gt; 可能更有意义。或许……

  <div @click="toggleMenu()">
     value[attr] 
  </div>

【讨论】:

oo,请问是否有必要删除下拉组件的一些方法以及删除输入标签的一些属性。我现在就试一试! 对不起,没有。我删除了一堆东西只是为了更容易突出我改变的地方。像你的占位符、必需的等东西看起来都不错。 未定义是有意义的,因为(我假设)当您启动表单时,父组件中没有选择。也许value[attr] 应该被包裹在if (value) 中,以防止首次加载时出现渲染错误 是的,我完全删除了selectedOption 的概念。孩子不再单独存储选择。它完全依赖于道具selected

以上是关于如何从 typescript 访问 vue 中组件的 props的主要内容,如果未能解决你的问题,请参考以下文章

如何在单独的非 Vue 组件、JavaScript/TypeScript 文件中访问 Vuex 状态?

如何使用 Vue 类组件访问 VueJS 3 和 Typescript 中的 HTML 引用?

在 Vue 3 Typescript 中使用提供/注入访问组件中的方法,错误对象可能是“未定义”

使用Typescript和类组件装饰器时如何在Vue Router中传递props

TypeScript Vue 组件中的泛型

使用 vue typescript 铸造组件 - 访问子方法