【问题标题】:Vue 3 Composition API: using props as initial value for component dataVue 3 Composition API:使用 props 作为组件数据的初始值
【发布时间】:2021-06-24 06:57:03
【问题描述】:

所以我正在使用组合 API 在 Vue 3 中构建一个搜索页面。我有一个组件,它从父级获取一组数据并显示数据的 sn-p,包括关键字所在的位置,因此它需要制作此数据的工作副本以生成可显示的值。

我遇到了很多奇怪的错误,因为我最初使用以下代码,认为它只会获取值:

setup(props) {

          const displayEntry = ref(props.entry)

...

但这最终是被动的并改变了原始数据。我不需要反应,因为我从父级动态创建组件。我也不想在父级中保留数据的工作副本,因为这会增加代码的复杂性。然后我尝试了无数种不同的解决方案来试图打破反应,直到我得到简单的:

displayEntry.value = props.entry

这时我的 linter 变成了香蕉……

error    Getting a value from the `props` in root scope of `setup()` will cause the value to lose reactivity  vue/no-setup-props-destructure

那么从道具中获取价值的正确方法是什么?

【问题讨论】:

  • “更改原始数据”是什么意思?这感觉像是一个 XY 问题:如果您在子组件中接收道具,则子组件不应该改变道具。您仍然应该使用ref(),这样每当父数据发生变化时,子组件的 prop 就会相应地更新。
  • 哦,我想我正在将响应式数据传递给 prop,但我不确定为什么它是响应式的,因为我执行了 entry.value.filter()
  • 您好,相信您需要像这样使用 toRefs 辅助函数:const { entry } = toRefs(props)v3.vuejs.org/guide/composition-api-setup.html#props

标签: javascript vue.js vue-component vuejs3 vue-composition-api


【解决方案1】:

原来我以某种方式在父级中传递了一个引用。以下是我的代码:

setup(props) {
  watchEffect(() => {
      if (searchTerm.value == "") {
        filteredEntries.value = []
      } else {
        filteredEntries.value = entries.value.filter(searchFilter)
      }
    })

  return {
      searchTerm, filteredEntries, echo, showPreview
    }
}

在模板中:

<SearchPreview
    v-for="( entry, index ) in filteredEntries"
    :key="index"
    :entry="entry"
    :search-term="searchTerm"
  />

不知道为什么它会传递一个 ref 并且我不确定如何传递值,但我使用以下 hack 将其修复在组件中:

const displayEntry = ref(JSON.parse(JSON.stringify(props.entry)))

(这会留下一些未定义的嵌套属性,但我将它们分别传递以使其工作)

【讨论】:

    【解决方案2】:

    在您展示的代码示例中,您从未将 fileredEntries 初始化为 ref。您如何在那里分配任何值? 如果您在组件上使用数据字段,则应将其移至设置功能。不要混合使用 composition 和 options api,它不能很好地协同工作。

    您还使用了 (for ... in) 循环来遍历您的过滤条目。 对于数组,您应该使用 (for ... of) 循环。 (见What is the difference between ( for... in ) and ( for... of ) statements?

    这是一个没有任何 hack 的示例。

    <template>
      <div>
        <SearchPreview
          v-for="( entry, index ) of filteredEntries"
          :key="index"
          :entry="entry"
          :search-term="searchTerm"
        />
      </div>
    </template>
    <script>
    
    const MyComponent = defineComponent({
    setup(props) {
      const entries = ref(['John', 'Jane']);
      const searchTerm = ref('');
      const filteredEntries = ref([]);
      const searchFilter = (item) => {
        // do some filtering
      };
    
      watchEffect(() => {
          if (searchTerm.value == "") {
            filteredEntries.value = []
          } else {
            filteredEntries.value = entries.value.filter(searchFilter)
          }
        });
    
      return {
          searchTerm, filteredEntries
        };
      }
    })
    

    【讨论】:

      猜你喜欢
      • 2021-09-15
      • 2021-10-24
      • 2021-10-14
      • 1970-01-01
      • 2022-11-29
      • 1970-01-01
      • 2023-02-10
      • 2023-01-10
      • 1970-01-01
      相关资源
      最近更新 更多