[vue] Propriedades computadas e suas características de cache

Exemplo básico

Embora as expressões nos modelos sejam convenientes, elas só podem ser usadas para operações simples. Se você escrever muita lógica em um modelo, ele ficará inchado e difícil de manter. Por exemplo, temos um objeto contendo arrays aninhados:

export default {
    
    
  data() {
    
    
    return {
    
    
      author: {
    
    
        name: 'John Doe',
        books: [
          'Vue 2 - Advanced Guide',
          'Vue 3 - Basic Guide',
          'Vue 4 - The Mystery'
        ]
      }
    }
  }
}

Queremos exibir informações diferentes dependendo se o autor já possui alguns livros:

<p>Has published books:</p>
<span>{
   
   { author.books.length > 0 ? 'Yes' : 'No' }}</span>

O modelo aqui parece um pouco complicado. Temos que procurar um pouco para entender que seu cálculo depende do autor.livros. Mais importante ainda, se mais de um cálculo for necessário no modelo, não queremos repetir esse código várias vezes no modelo.

Portanto, recomendamos o uso de propriedades computadas para descrever lógica complexa que depende do estado reativo. Aqui está o exemplo refatorado:

js
export default {
    
    
  data() {
    
    
    return {
    
    
      author: {
    
    
        name: 'John Doe',
        books: [
          'Vue 2 - Advanced Guide',
          'Vue 3 - Basic Guide',
          'Vue 4 - The Mystery'
        ]
      }
    }
  },
  computed: {
    
    
    // 一个计算属性的 getter
    publishedBooksMessage() {
    
    
      // `this` 指向当前组件实例
      return this.author.books.length > 0 ? 'Yes' : 'No'
    }
  }
}
template
<p>Has published books:</p>
<span>{
    
    {
    
     publishedBooksMessage }}</span>

Experimente no campo de treinamento

Definimos uma propriedade computada publicadaPublishBooksMessage aqui.

Depois de alterar o valor da matriz books nos dados deste aplicativo, você pode ver que PublicBooksMessage também mudará de acordo.

As propriedades computadas são usadas em modelos da mesma forma que as propriedades regulares. O Vue detectará que this.publishedBooksMessage depende de this.author.books, portanto, quando this.author.books for alterado, quaisquer ligações que dependam de this.publishedBooksMessage serão atualizadas ao mesmo tempo.

Cache de propriedade computado versus método

Você pode notar que obtemos o mesmo resultado que uma propriedade computada quando chamamos uma função como esta em uma expressão:

template
<p>{
    
    {
    
     calculateBooksMessage() }}</p>
js
// 组件中
methods: {
    
    
  calculateBooksMessage() {
    
    
    return this.author.books.length > 0 ? 'Yes' : 'No'
  }
}

Se definirmos a mesma função como um método em vez de uma propriedade computada, os resultados serão exatamente os mesmos, porém, a diferença é que o valor da propriedade computada é armazenado em cache com base em suas dependências reativas. Uma propriedade computada só é recalculada quando suas dependências reativas são atualizadas . Isso significa que, desde que author.books não mude, não importa quantas vezes você acesse publicadoBooksMessage, o resultado do cálculo anterior será retornado imediatamente, sem executar repetidamente a função getter.

Isso também explica por que a propriedade computada a seguir nunca é atualizada, porque Date.now() não é uma dependência reativa:

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

Por outro lado, as chamadas de método sempre executam a função novamente quando ocorre uma nova renderização.

Por que você precisa de cache? Imagine que temos uma lista de propriedades computadas com alto desempenho que requer loop em uma matriz enorme e muita lógica de cálculo, e pode haver outras propriedades computadas que dependem da lista. Sem cache, repetiríamos o getter da lista muitas vezes, mas na verdade isso é desnecessário! Se tiver certeza de que não precisa de cache, você também pode usar chamadas de método.

Propriedades computadas graváveis

As propriedades computadas são somente leitura por padrão. Ao tentar modificar uma propriedade computada, você receberá um aviso de tempo de execução. Somente em alguns casos especiais você pode precisar usar propriedades "graváveis", que você pode criar fornecendo um getter e um setter:

export default {
    
    
  data() {
    
    
    return {
    
    
      firstName: 'John',
      lastName: 'Doe'
    }
  },
  computed: {
    
    
    fullName: {
    
    
      // getter
      get() {
    
    
        return this.firstName + ' ' + this.lastName
      },
      // setter
      set(newValue) {
    
    
        // 注意:我们这里使用的是解构赋值语法
        [this.firstName, this.lastName] = newValue.split(' ')
      }
    }
  }
}

Agora, quando você executar this.fullName = 'John Doe', o setter será chamado e this.firstName e this.lastName serão atualizados de acordo.

Melhores Práticas

Getters não devem ter efeitos colaterais #O
getter de uma propriedade computada deve apenas realizar cálculos sem quaisquer outros efeitos colaterais. Isso é muito importante, lembre-se. Por exemplo, não faça solicitações assíncronas nem altere o DOM em getters ! A declaração de uma propriedade computada descreve como derivar um valor de outros valores. Portanto, a responsabilidade do getter deveria ser apenas calcular e retornar o valor.

Evite modificar diretamente valores de propriedades calculados

O valor retornado de uma propriedade computada é um estado derivado. Pense nisso como um “instantâneo temporário”, um novo instantâneo é criado sempre que o estado de origem muda. Não faz sentido alterar o instantâneo, portanto o valor de retorno de uma propriedade computada deve ser considerado somente leitura e nunca deve ser alterado - o estado de origem do qual depende deve ser atualizado para acionar um novo cálculo.

おすすめ

転載: blog.csdn.net/weixin_43361722/article/details/129817093