우리는 데이터의 일부 데이터가 템플릿의 보간 구문을 통해 직접 표시될 수 있다는 것을 알고 있지만 경우에 따라 데이터를 표시하기 전에 데이터에 일부 변환을 수행해야 하거나 여러 데이터를 결합해야 할 수도 있습니다. 표시
템플릿에서 표현식을 사용하면 매우 편리할 수 있지만 원래는 간단한 작업을 위해 설계되었습니다. 템플릿에 너무 많은 논리를 넣으면 템플릿이 과중해지고 유지 관리가 어려워지며, 여러 곳에 사용하면 문제가 발생합니다. 중복되는 코드가 많을 것입니다
그래서 비즈니스 로직과 UI 인터페이스를 분리하려고 합니다. 한 가지 방법은 로직을 메소드로 추출하는 것이지만 이 접근 방식에는 다음과 같은 단점이 있습니다
모든 데이터 사용이 메소드가 됩니다. call
데이터를 여러 번 얻으려면 캐싱 없이 해당 로직을 실행하기 위해 메소드를 여러 번 호출해야 합니다
사실 는 모든 응답 유형에 대한 것입니다. 복잡한 데이터 로직의 경우 계산된 속성 사용
对于任何包含响应式数据的复杂逻辑,你都应该使用计算属性
<div id="app"> <!-- 计算属性的使用和普通状态的使用方式是一致的 --> <h3>{{ fullname }}</h3> </div> <script> Vue.createApp({ data() { return { firstname: 'Klaus', lastname: 'Wang' } }, computed: { fullname() { return this.firstname + ' ' + this.lastname } } }).mount('#app')
计算属性会基于它们的依赖关系进行缓存,在数据不发生变化时,计算属性是不需要重新计算的
但是如果依赖的数据发生变化,在使用时,计算属性依然会重新进行计算
并且界面会使用最新的计算属性的值进行重新渲染
计算属性在大多数情况下,只需要一个getter方法即可,所以我们会将计算属性直接写成一个函数
<div id="app"> <!-- 计算属性的使用和普通状态的使用方式是一致的 --> <h3>{{ fullname }}</h3> <button @click="change">change</button> </div> <script> Vue.createApp({ data() { return { firstname: 'Klaus', lastname: 'Wang' } }, methods: { change() { this.fullname = 'Alex Li' } }, computed: { // 计算属性的完整写法 fullname: { get() { return this.firstname + ' ' + this.lastname }, set(v) { this.firstname = v.split(' ')[0] this.lastname = v.split(' ')[1] } } } }).mount('#app') </script>
在data返回的对象中定义了数据,这个数据通过插值语法等方式绑定到template中,当数据变化时,template会自动进行更新来显示最新的数据
但是在某些情况下,我们希望在代码逻辑中监听某个数据的变化,这个时候就需要用侦听器watch来完成了
Vue.createApp({ data() { return { info: { name: 'Klaus' } } }, watch: { // 可以使用watch监听响应式数据的改变 // 对应有两个参数 // 参数一 --- 新值 // 参数二 --- 旧值 info(newV, oldV) { // 如果监听的值是对象,获取到的新值和旧值是对应对象的代理对象 console.log(newV, oldV) // 代理对象 转 原生对象 // 1. 使用浅拷贝获取一个新的对象,获取的新的对象为原生对象 console.log({...newV}) // 2. 使用Vue.toRaw方法获取原生对象 console.log(Vue.toRaw(newV)) } }, methods: { change() { this.info = { name: 'Steven' } } } }).mount('#app')
属性 | 说明 |
---|---|
deep | 是否开启深度监听 值为boolean 未开启的时候,如果监听的是对象,那么只有对象的引用发生改变的时候,才会触发watch回调 开始后,如果监听的是对象,那么只要对象中的任意一个属性发生了改变,就会触发watch回调 |
immediate | 是否立即开始监听 默认情况下,初次渲染是不会触发watch监听,只有当值发生改变后,才会触发watch监听 将immediate设置为true后,初次渲染也会触发watch监听,此时oldValue的值为undefined |
Vue.createApp({ data() { return { info: { name: 'Klaus' } } }, watch: { info: { // 开启了深度监听后,当info的属性发生改变的时候,就会触发对应的watch回调 // 注意: 和直接修改info引用不同的是,如果直接修改的是对象的属性 // 那么此时newV和oldV是同一个对象的引用, 此时也就获取不到对应的旧值 handler(newV, oldV) { console.log(newV, oldV) console.log(newV === oldV) // => true }, deep: true, immediate: true } }, methods: { change() { this.info.name = 'Steven' } } }).mount('#app')
直接监听对象属性
watch: { 'info.name'(newV, oldV){ console.log(newV, oldV) } }
字符串写法
Vue.createApp({ data() { return { info: { name: 'Klaus' } } }, watch: { // watch的值如果是一个字符串的时候 // 会自动以该字符串作为函数名去methods中查找对应的方法 'info.name': 'watchHandler' }, methods: { change() { this.info.name = 'Steven' }, watchHandler(newV, oldV){ console.log(newV, oldV) } } }).mount('#app')
数组写法
Vue.createApp({ data() { return { info: { name: 'Klaus' } } }, watch: { 'info.name': [ 'watchHandler', function handle() { console.log('handler2') }, { handler() { console.log('handler3') } } ] }, methods: { change() { this.info.name = 'Steven' }, watchHandler(){ console.log('handler1') } } }).mount('#app')
$watch
Vue.createApp({ data() { return { info: { name: 'Klaus' } } }, created() { /* $watch 参数列表 参数一 --- 侦听源 参数二 --- 侦听回调 参数三 --- 配置对象 */ this.$watch('info.name', (newV, oldV) => console.log(newV, oldV), { immediate: true }) }, methods: { change() { this.info.name = 'Steven' } } }).mount('#app')
속성 | 설명 |
---|---|
deep | 심층 모니터링 활성화 여부 값은 부울입니다. 활성화되지 않은 경우 개체가 모니터링되면 개체의 참조만 변경됩니다. watch 콜백 시작 후 객체가 모니터링되면 객체의 속성이 변경되는 한 watch 콜백이 트리거됩니다. |
즉시 | 모니터링 즉시 시작 여부 기본적으로 첫 번째 렌더링에서는 시계 모니터링이 트리거되지 않습니다. 값이 변경될 때만 시계 모니터링이 트리거됩니다. immediate를 true로 설정합니다. 초기 렌더링은 시계 모니터링도 트리거합니다. 이때 oldValue의 값은 정의되지 않습니다. |
객체 속성 직접 모니터링
🎜rrreee🎜문자열 쓰기
🎜rrreee🎜배열 쓰기
🎜rrreee🎜$watch
🎜rrreee위 내용은 Vue3에서 계산된 속성과 리스너를 사용하는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!