【vue】vueの計算プロパティとリスニングプロパティの詳細解説

計算されたプロパティとリスナー

計算されたプロパティ

1. 計算されたプロパティ

リアクティブ状態に依存する複雑なロジックを記述するために使用されます

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

  data() {
    
    
    return {
    
    
      author: {
    
    
        name: 'John Doe',
        books: [
          'Vue 2 - Advanced Guide',
          'Vue 3 - Basic Guide',
          'Vue 4 - The Mystery'
        ]
      }
    }
  },
  computed: {
    
    
    // 计算属性的 getter,publishedBooksMessage的内容为yes或者no
    publishedBooksMessage() {
    
    
      // `this` 指向 vm 实例
      return this.author.books.length > 0 ? 'Yes' : 'No'
    }
  }

意味: データ内の書籍配列の値を変更しようとすると、次のようになります。出版された書籍メッセージ変更に応答する方法は、通常のプロパティをバインドするのと同じように、計算されたプロパティのデータ値をテンプレートにバインドできます。Vue は vm.publishedBookMes​​sage が vm.author.books に依存していることを認識しているため、vm.author.books が変更されると、すべてのvm.publishedBookMes​​sage に依存するバインディングも更新されます。そして最も良い点は、この依存関係を宣言的な方法で作成したことです。計算されたプロパティのゲッター関数には副作用がないため、テストと理解が容易になります。

計算されたプロパティとキャッシュ

計算されたプロパティは、その応答性の依存関係に基づいてキャッシュされます。計算されたプロパティは、関連する応答性の依存関係が変更されると再評価されます。つまり、author.books は変更されません。publishedBookMes​​sage 計算プロパティに複数回アクセスすると、ゲッターを使用せずに、前の計算結果がすぐに返されます。関数が繰り返し実行されます。

による属性値変更すると、計算結果が再計算されます

これは、以下の計算されたプロパティが次のようになることも意味します。もう更新しませんDate.now() はリアクティブな依存関係ではないためです。

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

対照的に、トリガーするたびに、再レンダリング、呼び出しメソッドは常に再度実行する関数。キャッシュを望まない場合は、代わりにメソッドメソッドを使用してください。

計算されたプロパティにはデフォルトでゲッターのみが含まれますが、必要に応じてセッターを提供することもできます。

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(' ')
      }
    }
  }
}

実行時に this.fullName = ‘John Doe’ 、セッターが呼び出され、 this.firstName 和 this.lastNameそれに応じて更新されます。または次のように:

computed: {
    
    
  fullName: {
    
    
    // getter
    get() {
    
    
      return this.firstName + ' ' + this.lastName
    },
    // setter
    set(newValue) {
    
    
      const names = newValue.split(' ')
      this.firstName = names[0]
      this.lastName = names[names.length - 1]
    }
  }
}

注:
1): 非同期リクエストを作成したり、ゲッター内の dom を変更したりしないでください。
2): 計算されたプロパティを直接変更しないでください。

要約:計算済み (複数の変数が結果を計算します)
計算済み属性: 他の属性に依存しており、キャッシュがあります。依存する属性の値が変更された場合にのみ、計算済み属性が再計算され、同期がサポートされます。

リスナー

リアクティブプロパティが変更されるたびに関数を起動します。データ変更が必要な場合に非同期操作または高コストの操作を実行する場合は、watch 属性を使用します。

<div id="watch-example">
  <p>
    Ask a yes/no question:
    <input v-model="question" />
  </p>
  <p>{
   
   { answer }}</p>
</div>
<!-- 因为 AJAX 库和通用工具的生态已经相当丰富,Vue 核心代码没有重复 -->
<!-- 提供这些功能以保持精简。这也可以让你自由选择自己更熟悉的工具。 -->
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/axios.min.js"></script>
<script>
  const watchExampleVM = Vue.createApp({
      
      
    data() {
      
      
      return {
      
      
        question: '',
        answer: 'Questions usually contain a question mark. ;-)'
      }
    },
    watch: {
      
      
      // 每当 question 改变时,getAnswer这个函数就会执行
      question(newQuestion, oldQuestion) {
      
      
        if (newQuestion.indexOf('?') > -1) {
      
      
          this.getAnswer()
        }
      }
    },
    methods: {
      
      
      getAnswer() {
      
      
        this.answer = 'Thinking...'
        axios
          .get('https://yesno.wtf/api')
          .then(response => {
      
      
            this.answer = response.data.answer
          })
          .catch(error => {
      
      
            this.answer = 'Error! Could not reach the API. ' + error
          })
      }
    }
  }).mount('#watch-example')
</script>

watch オプションは、.: で区切られたパスへのキーの設定もサポートしています。

 watch: {
    
    
    // 注意:只能是简单的路径,不支持表达式。
    'some.nested.key'(newValue) {
    
    
      // ...
    }
  }

ディープリスナー:

ディープ リスニングでは、リッスンするオブジェクト内のすべてのネストされたプロパティを走査する必要があり、大規模なデータ構造に使用すると非常にコストがかかります。したがって、必要な場合にのみ使用し、パフォーマンスに注意してください。

 watch: {
    
    
    someObject: {
    
    
      handler(newValue, oldValue) {
    
    
        // 注意:在嵌套的变更中,
        // 只要没有替换对象本身,
        // 那么这里的 `newValue` 和 `oldValue` 相同
      },
      deep: true,
       // 强制立即执行回调,
      immediate: true
    }
  }
 

即時コールバック: コールバックは、データ ソースが変更された場合にのみ実行されます。ただし、シナリオによっては、リスナーの作成時にすぐにコールバックを実行したい場合があります。たとえば、初期データをリクエストし、関連する状態が変化したときにデータを再リクエストしたいとします。

this.$watch()

これは、特定の条件下でリスナーを設定する場合、またはユーザー インタラクションに応答するコンテンツのみをリッスンする場合に便利です。また、リスナーを早期に停止することもできます。

 created() {
    
    
    this.$watch('question', (newQuestion) => {
    
    
      // ...
    })
  }

リスナーを停止する

const unwatch = this.$watch('foo', callback)

// ...当该侦听器不再需要时
unwatch()

計算されたプロパティとリスナー

Vue は、現在アクティブなインスタンスのデータ変更を観察してそれに応答するためのより一般的な方法、つまりリスナー プロパティを提供します。他のデータの変更に合わせて一部のデータを変更する必要がある場合は、次を使用します。計算されたプロパティ命令型の監視コールバックではなく。

<div id="demo">{
   
   { fullName }}</div>
<script>
// watch
const vm = Vue.createApp({
      
      
  data() {
      
      
    return {
      
      
      firstName: 'Foo',
      lastName: 'Bar',
      fullName: 'Foo Bar'
    }
  },
  watch: {
      
      
    firstName(val) {
      
      
      this.fullName = val + ' ' + this.lastName
    },
    lastName(val) {
      
      
      this.fullName = this.firstName + ' ' + val
    }
  }
}).mount('#demo')



//  compute
const vm = Vue.createApp({
      
      
  data() {
      
      
    return {
      
      
      firstName: 'Foo',
      lastName: 'Bar'
    }
  },
  computed: {
      
      
    fullName() {
      
      
      return this.firstName + ' ' + this.lastName
    }
  }
}).mount('#demo')
</script>

要約:計算プロパティとリスナー選択の違い:
1. 計算プロパティの選択: 一部のデータは他のデータ変更に合わせて変更する必要がある2. リスナーの選択:
データ変更時に非同期操作または負荷の高い操作を実行する
必要がある場合 3 .Listening 属性: 監視および応答に使用されます。現在アクティブなインスタンスのデータ変更への影響

おすすめ

転載: blog.csdn.net/liqiannan8023/article/details/129752137