Pregunta de la entrevista 5: Uso de computación

Inscripción

La frecuencia de uso de la computación en la mayoría de los trabajos es muy baja, por lo que hoy presentaré este artículo en detalle, porque una de las almas de Vue es la computación.

 Las expresiones dentro de las plantillas son muy convenientes, pero están diseñadas para operaciones simples. Poner demasiada lógica en una plantilla hará que la plantilla tenga sobrepeso y sea difícil de mantener, por lo que, para lógica compleja, Vue recomienda el uso de propiedades calculadas. Nota especial: la función getter de una propiedad calculada no tiene efectos secundarios, lo que hace que sea más fácil de probar y comprender, desde las propiedades calculadas de Vue.
 

introducción 

Antes de discutir  la diferencia entre computed y  watch , veamos primero  cuál es la diferencia entre computed y  methods .

calculado o métodos

En teoría, todas las implementaciones de computación se pueden reemplazar completamente mediante métodos.

<p>Reversed message: "{
   
   { reversedMessage() }}"</p>
<p>Reversed message: "{
   
   { reversedMessage }}"</p>

 

// 计算属性
computed: {
  reversedMessage () {
    return this.message.split('').reverse().join('')
  }
}
// 方法
methods: {
  reversedMessage: function () {
    return this.message.split('').reverse().join('')
  }
}

 

Las propiedades calculadas se almacenan en caché en función de sus dependencias de respuesta. Solo se reevalúan cuando cambian las dependencias reactivas asociadas. Esto significa que mientras el mensaje no haya cambiado, múltiples accesos a la propiedad calculada de ReversedMessage devolverán inmediatamente el resultado calculado anterior sin tener que ejecutar la función nuevamente. Pero el método será ejecutado.

Esto también significa que las siguientes propiedades calculadas ya no se actualizarán porque Date.now() no es una dependencia reactiva:
 

computed: {
  now: function () {
    return Date.now()
  }
}

¿Por qué necesitamos el almacenamiento en caché? Supongamos que tenemos un atributo computacional A que es relativamente costoso y requiere atravesar una matriz enorme y realizar muchos cálculos. Entonces podríamos tener otras propiedades calculadas que dependan de A. ¡Sin almacenamiento en caché, inevitablemente ejecutaríamos el captador de A varias veces! Si no desea el almacenamiento en caché, utilice métodos en su lugar.

Lo mismo: los métodos calculados y se mezclarán en la instancia de Vue. vm.reversedMessage/vm.reversedMessage() puede obtener propiedades/métodos calculados relacionados.
A continuación, veamos  computed cuál  watch es la diferencia.

texto

computado o observado

Vue proporciona una forma más general de observar y responder a los cambios de datos en instancias de Vue: propiedades de escucha. Es fácil abusar de las inspecciones cuando hay algunos datos que deben cambiar a medida que cambian otros datos. Sin embargo, a menudo es mejor usar propiedades calculadas en lugar de devoluciones de llamadas de inspecciones imperativas.

El método de vigilancia es más útil cuando necesita realizar operaciones asincrónicas o costosas cuando cambian los datos. Nos permite realizar una operación asincrónica (acceder a una API), limitar la frecuencia con la que realizamos la operación y establecer estados intermedios antes de obtener el resultado final. Éstas son cosas que las propiedades calculadas no pueden hacer.
 

methods: {
  getAnswer: function () {
    this.answer = 'Thinking...'
    var vm = this
    axios.get('https://yesno.wtf/api')
      .then(function (response) {
        vm.answer = _.capitalize(response.data.answer)
      })
      .catch(function (error) {
        vm.answer = 'Error! Could not reach the API. ' + error
      })
  }
},
created: function () {
  // debounce 反弹函数
  this.debouncedGetAnswer = _.debounce(this.getAnswer, 500)
}

 

Desde este punto de vista, ¿ watch se puede sustituir por completo  computed ? ¿ En qué circunstancias sólo se puede utilizar computed?

Mirando hacia atrás,  computed la característica más importante es el almacenamiento en caché, por lo que la pregunta anterior se puede convertir en: ¿En qué circunstancias debemos confiar en el almacenamiento en caché?

Ejemplo: el componente principal pasa un valor al componente secundario y el tipo de valor es un tipo de referencia.

componente principal

<template>
  <div>
    <child :user="user"></child>
    <label for="user">parent:</label>
    <input id="user" type="text" v-model="user.name">
  </div>
</template>
<script>
import Child from './child.vue'
export default {
  data () {
    return {
      user: { name: 'ligang' }
    }
  },
  components: { Child }
}
</script>

 Subconjunto

<template>
  <div>child: {
   
   {user}}</div>
</template>
<script>
export default {
  name: 'child',
  props: ['user']
}
</script>

Ahora existe el requisito de que el subcomponente muestre los valores antes y después del cambio al mismo tiempo.

Muy fácil, simplemente  watch guárdelo en  oldVal .

<template>
  <div>
    <div>child:</div>
    <div>修改前:{
   
   {oldUser}} 修改后:{
   
   {user}}</div>
  </div>
</template>
<script>
export default {
  name: 'child',
  props: ['user'],
  data () {
    return {
      oldUser: {}
    }
  },
  watch: {
    user: {
      handler (val, oldVal) {
        this.oldUser = oldVal || val
      },
      deep: true,
      immediate: true
    }
  }
}
</script>

Mira los resultados, WTF, qué pasó ~~

 

El problema es que el usuario es un tipo de referencia y el reloj no se almacena en caché, por lo que se modifica el mismo objeto. Por lo tanto, **val === olVal en el método de reloj es verdadero. ! **

¿Cómo cumplir con los requisitos? Aquí podemos tomar prestadas las características del caché calculado para completar la situación anterior.

Los resultados de las propiedades calculadas se almacenan en caché y no se volverán a calcular a menos que cambien las propiedades de respuesta dependientes. Tenga en cuenta que si una dependencia (como una propiedad no reactiva) está fuera del alcance de la instancia, la propiedad calculada no se actualizará. — vue-api calculada
 

<template>
  <div>
    <div>child:</div>
    <div>修改前:{
   
   {oldUser}} 修改后:{
   
   {user}}</div>
  </div>
</template>
<script>
export default {
  name: 'child',
  props: ['user'],
  data () {
    return {
      oldUser: {}
    }
  },
  // 缓存 userInfo   
  computed: {
    userInfo () {
      return { ...this.user }
    }
  },
  watch: {
    userInfo: {
      handler (val, oldVal) {
        this.oldUser = oldVal || val
      },
      deep: true,
      immediate: true
    }
  }
}
</script>

Nota: ¡ { ...this.user } O úselo  Object.assign({}, this.user) para crear una nueva referencia!

Supongo que te gusta

Origin blog.csdn.net/2201_75705263/article/details/132901376
Recomendado
Clasificación