Vue3学习之路(二)

207 阅读2分钟

Vue3中 watch、watchEffect 和 computed 的多种用法

watch

基本用法 -- 监听基本类型

// 总结:
/**
 * 1、ref
 * (1)、基础类型可以通过监听 【响应式数据】 或者 【匿名函数+value】
 * (2)、复杂类监听全部的【响应式数据+value】监听单一具体的 【匿名函数+value+具体的参数】
 * 2、reactive 对象类型
 * (1)、监听全部的 【响应式对象】
 * (2)、监听单一的:
 *        基础类型:【匿名函数+具体的参数】
 *        复杂类型:1、{deep:true} 2、【匿名函数+具体的参数(嵌套层级比较深的具体的值)】
 */
</template>
  <p>{{state.value}}</p>
  <el-button @click='setState'>改变这个值</el-button>
</template>

<script>

import { wacth,ref } from 'vue'

const state = ref(0)

watch(state,(cur, prev)=>{
    conosle.log('当前的值:',cur)
    conosle.log('之前的值:',prev)
    // 执行逻辑
})

const setState = ()=>{
    state.value++
}

</script>

基本用法 -- 监听引用类型

</template>
  <p>{{state.value}}</p>
  <el-button @click='setState'>改变这个值</el-button>
</template>

<script>
import { wacth,reactive,ref } from 'vue'

// 注释的是当监听对象的 某一个 属性的写法。如果直接监听这个对象,里边所有的变量变化都会被监听到
const state = ref([1,2,3,4,5]) 
// const obj = reactive({name:'小明',age:18})

watch(state,(cur, prev)=>{
    conosle.log('当前的值:',cur)
    conosle.log('之前的值:',prev)
    // 执行逻辑
})

//watch(
//    () => obj.age,
//    (cur, prev)=>{
//        conosle.log('当前的值:',cur)
//        conosle.log('之前的值:',prev)
//        // 执行逻辑
//})

const setState = ()=>{
    state.value = Array.from({ length: 5 }, () => Math.floor(Math.random() * 10));
}

//const setState = ()=>{
//    obj.value.age++
//}
</script>

基本用法 -- 监听多个类型

</template>
  <p>{{num.value}}--{{count.value}}</p>
  <el-button @click='setState'>改变这个值</el-button>
</template>

<script>
import { wacth,ref } from 'vue'

const num = ref(5) 
const count = ref(100)

watch([num,count],([curNum,curCount], [prevNum,prevCount])=>{
    conosle.log('当前的值:',curNum,curCount)
    conosle.log('之前的值:',prevNum,prevCount)
    // 执行逻辑
})

const setState = ()=>{
    num.value++;
    count.value++;
}
</script>

额外用法

</template>
  <p>{{obj.count}}--{{obj.age}}</p>
  <el-button @click='setState'>改变这个值</el-button>
</template>

<script>
import { wacth,ref } from 'vue'

const obj = ref({ count: 0, age: 999 });

watch(
    obj,
    // ()=>obj.value.count, 这样不加deep也可以监听到 count的值
    (cur, prev)=>{
        conosle.log('当前的值:',cur)
        conosle.log('之前的值:',prev)
    // 执行逻辑
    },
    {
      deep:true, // 深度监听 如果不加这个值是监听不到的
      immediate: true, // 立即执行 页面加载初始化的时候就会执行
      once: true, // 回调函数只会运行一次 3.4+版本
    } 
)

const setState = ()=>{
    obj.value.count++;
}
</script>

computed

</template>
  <p>{{ computedValue }}</p>
  <el-button @click='setList'>改变这个值</el-button>
</template>

<script>
import { computed,ref } from 'vue'

const list = ref([2,3,4,5,6]);

const computedValue = computed(() => {
  return list.value.filter(f => f > 3);
});

const setList = () => {
  list.value = Array.from({ length: 5 }, () => Math.floor(Math.random() * 10));
};
</script>

watchEffect

watchEffect 函数会监听函数体内使用到的响应式数据,而不是像 watch 函数一样需要指定要监听的特定响应式数据。这意味着 watchEffect 会自动追踪函数体内访问的所有响应式数据,并在这些数据发生变化时重新运行函数体。

</template>
  <p>{{ state.count }}</p>
  <el-button @click='setState'>改变这个值</el-button>
</template>
<script>
import { computed,ref } from 'vue'

const state = reactive({ count: 0, message: 'Hello' });

const setState = ()=>{
    state.count++
}
 
watchEffect(
  () => {
    console.log(state.count); // 只监听 state.count 的变化
  },
  { 
      // flush 参数用于指定在何时触发副作用函数
      flush: 'pre', // 表示在依赖变化之后立即执行副作用函数(默认值)
      flush: 'post', // post 表示副作用代码会被推迟到 DOM 更新之后执行
      flush: 'sync', // 表示在依赖发生变化时同步执行副作用函数 强制效果始终同步触发。然而,这是低效的,应该很少需要
  } 
);
</script>