javascript - API de composición de Vue 3: uso de accesorios como valor inicial para los datos del componente

CorePress2024-01-25  10

Así que estoy creando una página de búsqueda en Vue 3 usando la API de composición. Tengo un componente que toma un conjunto de datos del padre y muestra un fragmento de los datos que incluye dónde está la palabra clave, por lo que necesita hacer una copia de trabajo de estos datos para crear un valor que se pueda mostrar.

Tuve muchos errores extraños porque inicialmente estaba usando el siguiente código, pensando que simplemente obtendría el valor:

setup(props) {

          const displayEntry = ref(props.entry)

...

pero esto terminó siendo reactivo y cambiando los datos originales. No necesito la reactividad porque creo el componente dinámicamente a partir del padre. Tampoco quiero conservar una copia funcional de los datos en el archivo principal porque eso aumentará la complejidad del código. Luego probé un sinfín de soluciones diferentes para intentar romper la reactividad hasta que llegué a simplemente:

displayEntry.value = props.entry

En ese momento mi linter se vuelve loco...

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

Entonces, ¿cuál es la forma correcta de obtener el valor de un accesorio?

¿Qué quiere decir con “cambiar los datos originales”? Esto se siente como un problema XY: si recibe accesorios en un componente secundario, el componente secundario no debería mutar el accesorio. Aún debes usar ref() para que cada vez que los datos principales muten, la propiedad del componente secundario se actualizará en consecuencia.

-Terry

27/03/2021 a las 17:11

Oh, supongo que estoy pasando datos reactivos al accesorio, pero no estoy muy seguro de por qué es reactivo ya que hago entradas.value.filter()

-Juckix

27/03/2021 a las 17:20

Hola, creo que necesitas usar la función auxiliar toRefs así: const {entrada} = toRefs(props) v3.vuejs.org/guide/composition-api-setup.html#props

- usuario1870482

1 de julio de 2021 a las 20:19



------------------------------------

Resulta que de alguna manera estaba pasando una referencia en el padre. El siguiente es mi código:

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

  return {
      searchTerm, filteredEntries, echo, showPreview
    }
}

Y en la plantilla:

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

No tengo idea de por qué pasa una referencia y no estoy seguro de cómo pasar el valor, pero lo arreglé en el componente con el siguiente truco:

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

(esto deja algunas propiedades anidadas sin definir, pero las paso por separado para que funcione)



------------------------------------

Tú nunca yonitialized fileredEntries como referencia en el ejemplo de código que mostró. ¿Cómo asignas valores allí? Si está utilizando un campo de datos en su componente, debe moverlo a la función de configuración. No mezcle la API de composición y opciones, no funcionan bien juntas.

También usaste un bucle (for... in) para iterar sobre tus entradas filtradas. Para una matriz, debería utilizar un bucle (for... of). (consulte ¿Cuál es la diferencia entre las declaraciones (for... in) y (for... of)?)

Aquí tienes un ejemplo de cómo debería ser sin ningún truco.

<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
    };
  }
})

Su guía para un futuro mejor - libreflare
Su guía para un futuro mejor - libreflare