이번에는 vue 계산 속성 및 리스너 사례 코드 분석을 가져 왔습니다. vue 계산 속성 및 리스너 구현 시 주의 사항 은 무엇입니까?
기본 예
<p id="example"> <p>Original message: "{{ message }}"</p> <p>Computed reversed message: "{{ reversedMessage }}"</p> </p> var vm = new Vue({ el: '#example', data: { message: 'Hello' }, computed: { // 计算属性的 getter reversedMessage: function () { // `this` 指向 vm 实例 return this.message.split('').reverse().join('') } } })
결과:
원본 메시지: "Hello"
계산된 역방향 메시지: "olleH"
여기서 계산된 속성 reversedMessage를 선언합니다. 우리가 제공하는 기능은 vm.reversedMessage 속성의 getter 기능으로 사용됩니다.
console.log(vm.reversedMessage) // => 'olleH' vm.message = 'Goodbye' console.log(vm.reversedMessage) // => 'eybdooG'
브라우저 콘솔을 열고 예제에서 VM을 직접 수정할 수 있습니다. vm.reversedMessage
값은 항상 vm.message 값에 따라 달라집니다. vm.reversedMessage
的值始终取决于 vm.message 的值。
你可以像绑定普通属性一样在模板中绑定计算属性。Vue 知道 vm.reversedMessage
依赖于 vm.message,因此当 vm.message 发生改变时,所有依赖 vm.reversedMessage 的绑定也会更新。而且最妙的是我们已经以声明的方式创建了这种依赖关系:计算属性的 getter 函数是没有副作用 (side effect) 的,这使它更易于测试和理解
计算属性缓存 vs 方法
你可能已经注意到我们可以通过在表达式中调用方法来达到同样的效果:
<p>Reversed message: "{{ reversedMessage() }}"</p> // 在组件中 methods: { reversedMessage: function () { return this.message.split('').reverse().join('') } }
我们可以将同一函数定义为一个方法而不是一个计算属性。两种方式的最终结果确实是完全相同的。然而,不同的是计算属性是基于它们的依赖进行缓存的。计算属性只有在它的相关依赖发生改变时才会重新求值。这就意味着只要 message 还没有发生改变,多次访问 reversedMessage 计算属性会立即返回之前的计算结果,而不必再次执行函数。
这也同样意味着下面的计算属性将不再更新,因为 Date.now() 不是响应式依赖:
computed: { now: function () { return Date.now() } }
相比之下,每当触发重新渲染时,调用方法将总会再次执行函数。
我们为什么需要缓存?假设我们有一个性能开销比较大的的计算属性 A,它需要遍历一个巨大的数组并做大量的计算。然后我们可能有其他的计算属性依赖于 A 。如果没有缓存,我们将不可避免的多次执行 A 的 getter!如果你不希望有缓存,请用方法来替代。
计算属性 vs 侦听属性
Vue 提供了一种更通用的方式来观察和响应 Vue 实例上的数据变动:侦听属性。当你有一些数据需要随着其它数据变动而变动时,你很容易滥用 watch——特别是如果你之前使用过 AngularJS。然而,通常更好的做法是使用计算属性而不是命令式的 watch 回调。细想一下这个例子:
<p id="demo">{{ fullName }}</p> var vm = new Vue({ el: '#demo', data: { firstName: 'Foo', lastName: 'Bar', fullName: 'Foo Bar' }, watch: { firstName: function (val) { this.fullName = val + ' ' + this.lastName }, lastName: function (val) { this.fullName = this.firstName + ' ' + val } } })
上面代码是命令式且重复的。将它与计算属性的版本进行比较:
var vm = new Vue({ el: '#demo', data: { firstName: 'Foo', lastName: 'Bar' }, computed: { fullName: function () { return this.firstName + ' ' + this.lastName } } })
好得多了,不是吗?
计算属性的 setter
计算属性默认只有 getter ,不过在需要时你也可以提供一个 setter :
// ... computed: { fullName: { // getter get: function () { return this.firstName + ' ' + this.lastName }, // setter set: function (newValue) { var names = newValue.split(' ') this.firstName = names[0] this.lastName = names[names.length - 1] } } } // ...
现在再运行 vm.fullName = 'John Doe'
vm.reversedMessage
가 vm.message에 의존한다는 것을 알고 있으므로 vm.message가 변경되면 vm.reversedMessage에 의존하는 모든 바인딩도 업데이트됩니다. 그리고 가장 좋은 부분은 선언적 방식으로 이 종속성을 생성했다는 것입니다. 계산된 속성 getter 함수에는 부작용이 없으므로 테스트하고 이해하기가 더 쉽습니다. 표현식 : <p id="watch-example">
<p>
Ask a yes/no question:
<input v-model="question">
</p>
<p>{{ answer }}</p>
</p>
<!-- 因为 AJAX 库和通用工具的生态已经相当丰富,Vue 核心代码没有重复 -->
<!-- 提供这些功能以保持精简。这也可以让你自由选择自己更熟悉的工具。 -->
<script src="https://cdn.jsdelivr.net/npm/axios@0.12.0/dist/axios.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/lodash@4.13.1/lodash.min.js"></script>
<script>
var watchExampleVM = new Vue({
el: '#watch-example',
data: {
question: '',
answer: 'I cannot give you an answer until you ask a question!'
},
watch: {
// 如果 `question` 发生改变,这个函数就会运行
question: function (newQuestion, oldQuestion) {
this.answer = 'Waiting for you to stop typing...'
this.getAnswer()
}
},
methods: {
// `_.debounce` 是一个通过 Lodash 限制操作频率的函数。
// 在这个例子中,我们希望限制访问 yesno.wtf/api 的频率
// AJAX 请求直到用户输入完毕才会发出。想要了解更多关于
// `_.debounce` 函数 (及其近亲 `_.throttle`) 的知识,
// 请参考:https://lodash.com/docs#debounce
getAnswer: _.debounce(
function () {
if (this.question.indexOf('?') === -1) {
this.answer = 'Questions usually contain a question mark. ;-)'
return
}
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
})
},
// 这是我们为判定用户停止输入等待的毫秒数
500
)
}
})
</script>
이는 Date.now()가 반응적 종속성이 아니기 때문에 아래 계산된 속성이 더 이상 업데이트되지 않는다는 의미이기도 합니다.
rrreee반면, 다시 렌더링이 트리거될 때마다 호출 메서드는 항상 함수를 다시 실행합니다. .
캐싱이 왜 필요한가요? 거대한 배열을 순회하고 많은 계산을 수행해야 하는 계산 비용이 많이 드는 속성 A가 있다고 가정해 보겠습니다. 그러면 A에 의존하는 다른 계산된 속성이 있을 수 있습니다. 캐싱이 없으면 필연적으로 A의 getter를 여러 번 실행하게 됩니다! 캐싱을 원하지 않으면 대신 메소드를 사용하십시오.
. 그러나 명령형 감시 콜백 대신 계산된 속성을 사용하는 것이 더 나은 경우가 많습니다. 다음 예를 고려해 보세요.계산된 속성과 청취 속성
Vue는 Vue 인스턴스의 데이터 변경 사항을 관찰하고 응답하는 보다 일반적인 방법인 청취 속성을 제공합니다. 다른 데이터 변경에 따라 변경해야 하는 일부 데이터가 있는 경우 시계를 남용하기 쉽습니다. 특히 AngularJS
rrreee위 코드는 필수적이고 반복적입니다. 계산된 속성 버전과 비교해 보세요. rrreee
훨씬 낫지 않나요? 🎜🎜🎜계산된 속성을 위한 Setter🎜🎜🎜계산된 속성에는 기본적으로 getter만 있지만 필요한 경우 setter를 제공할 수도 있습니다. 🎜rrreee🎜이제 vm.fullName = 'John Doe'
를 실행할 때, setter가 호출되고 vm.firstName 및 vm.lastName이 그에 따라 업데이트됩니다. 🎜🎜🎜Listeners🎜🎜🎜대부분의 경우 계산된 속성이 더 적합하지만 때로는 사용자 정의 리스너가 필요할 수도 있습니다. 이것이 Vue가 watch 옵션을 통해 데이터 변경에 응답하는 보다 일반적인 방법을 제공하는 이유입니다. 이 접근 방식은 데이터가 변경될 때 비동기식 또는 비용이 많이 드는 작업을 수행해야 할 때 가장 유용합니다. 🎜🎜예: 🎜rrreee🎜결과:🎜🎜🎜예/아니요 질문:🎜🎜질문을 하기 전까지는 답변을 드릴 수 없습니다!🎜🎜🎜이 예에서 watch 옵션을 사용하면 비동기 작업을 수행할 수 있습니다. (API에 액세스) 작업 수행 빈도를 제한하고 최종 결과를 얻을 때까지 중간 🎜상태🎜를 설정합니다. 이는 계산된 속성이 수행할 수 없는 작업입니다. 🎜watch 옵션 외에도 명령형 vm.$watch API를 사용할 수도 있습니다.
이 기사의 사례를 읽은 후 방법을 마스터했다고 생각합니다. 더 흥미로운 정보를 보려면 PHP 중국어 웹사이트의 다른 관련 기사를 주목하세요!
추천 자료:
위 내용은 Vue 계산 속성 및 리스너 케이스 코드 분석의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!