赞
踩
简写写法(只实现了 get ):
<template> <div> <ul> <li v-for="item of carts" :key="item.id"> {{ item.name }} </li> </ul> <hr /> <h3>合计:{{ totalPrice }}</h3> </div> </template> <script> import { computed, reactive, toRefs } from 'vue' export default { setup() { let state = reactive({ carts: [ { id: 1, name: '小米', price: 1, num: 1 }, { id: 2, name: '大米', price: 1, num: 1 } ], total: 0 }) // 计算属性 -- get let totalPrice = computed(() => { return state.carts.reduce((p, { price, num }) => { p += price * num return p }, 0) }) // let totalPrice = computed({ // get() { // return state.carts.reduce((p, { price, num }) => { // p += price * num // return p // }, 0) // } // }) return { ...toRefs(state), totalPrice } } } </script> <style lang="scss" scoped> </style>
标准写法(可以实现 get 和 set 方法):
<template> <div> <ul> <li v-for="item of carts" :key="item.id"> {{ item.name }} </li> </ul> <hr /> <h3>合计:{{ totalPrice }}</h3> </div> </template> <script> import { computed, reactive, toRefs } from 'vue' export default { setup() { let state = reactive({ carts: [ { id: 1, name: '小米', price: 1, num: 1 }, { id: 2, name: '大米', price: 1, num: 1 } ], total: 0 }) let totalPrice = computed({ get() { return state.carts.reduce((p, { price, num }) => { p += price * num return p }, 0) }, // 了解一下 set(v) { console.log('set', v) } }) // 如果你给计算属性赋值,则一定要写标准方式,set方法一定要写 totalPrice.value = 'abc' return { ...toRefs(state), totalPrice } } } </script> <style lang="scss" scoped> </style>
完整的购物车案例:
<template> <div> <h3>{{ total }}</h3> <ul> <li v-for="(item, index) of carts" :key="item.id"> <span>{{ item.name }}</span> <span> <button @click="setNum(index, 1)">+</button> <button @click="totalPrice = { index, n: 1 }">另一种实现求和的方式</button> <span>{{ item.num }}</span> <button @click="setNum(index, -1)">-</button> </span> </li> </ul> <hr /> <h3>合计:{{ totalPrice }}</h3> </div> </template> <script> import { computed, reactive, toRefs } from 'vue' export default { setup() { let state = reactive({ carts: [ { id: 1, name: '小米', price: 1, num: 1 }, { id: 2, name: '大米', price: 1, num: 1 } ], total: 0 }) let totalPrice = computed({ get() { return state.carts.reduce((p, { price, num }) => { p += price * num return p }, 0) }, // 求和方式2: set(v) { if (v.n) { state.carts[v.index].num += v.n } } }) // 求和方式1: const setNum = (index, n) => { state.carts[index].num += n if (state.carts[index].num <= 1) state.carts[index].num = 1 if (state.carts[index].num >= 10) state.carts[index].num = 10 } return { ...toRefs(state), totalPrice, setNum } } } </script> <style lang="scss" scoped></style>
<template> <div> <h3>{{ num }}</h3> <!-- 输入的内容发生变化时,控制台不会打印,因为 name 不是侦听器的依赖项 --> <input type="text" v-model="name" /> <button @click="num++">+++</button> <!-- <button @click="stop">停止侦听</button> --> </div> </template> <script> // watchEffect 自动去根据方法中的调用来确定依赖项 // watch 手动指定依赖项 -- 用它可能会多一些 import { ref, watch, watchEffect } from 'vue' export default { setup() { const num = ref(100) const name = ref('') // 侦听,它必须要有依赖项 // 它在初始化时,会主动执行1次,如果没有依赖项,则不会再次执行 // watchEffect(() => { // // 这里只会在初始时打印一次222 // console.log(222) // }) watchEffect(() => { // 此时它的依赖项为 num变量,如果它有改变,则回调函数会自动触发 // 它的依赖项可以是1到N个 console.log(222, num.value) }) return { num,name } } } </script> <style lang="scss" scoped> </style>
watchEffect 的返回值:
<template> <div> <h3>{{ num }}</h3> <button @click="num++">+++</button> <button @click="stop">停止侦听</button> </div> </template> <script> // watchEffect 自动去根据方法中的调用来确定依赖项 // watch 手动指定依赖项 -- 用它可能会多一些 import { ref, watch, watchEffect } from 'vue' export default { setup() { const num = ref(100) const stopHandle = watchEffect(() => { console.log(222, num.value) }) const stop = () => stopHandle() return { num, stop } } } </script> <style lang="scss" scoped> </style>
watchEffect 的 onCleanup 回调参数:
watchEffect 还有一个回调参数,此参数它也是一个函数,作用是清理副作用。
<template> <div> <h3>{{ num }}</h3> <button @click="num++">+++</button> <button @click="stop">停止侦听</button> </div> </template> <script> // watchEffect 自动去根据方法中的调用来确定依赖项 // watch 手动指定依赖项 -- 用它可能会多一些 import { ref, watch, watchEffect } from 'vue' export default { setup() { const num = ref(100) let timer // 此方法它还有一个回调参数,此参数它也是一个函数,作用,清理副作用 const stopHandle = watchEffect( onCleanup => { console.log(num.value) // console.log(222, num.value, name.value) onCleanup(() => { console.log('清理上一次的处理') timer && clearTimeout(timer) }) timer = setTimeout(() => { console.log('输出的') }, 1000) }, { // flush?: 'pre' | 'post' | 'sync'; // pre 模板渲染之前触发 // post 模板渲染之后触发 // sync 和模板渲染同步来触发 // 默认为 pres flush: 'pre' } ) const stop = () => stopHandle() return { num, stop } } } </script> <style lang="scss" scoped> </style>
监听一个变量值的变化:
<template> <div> <div>{{ num }} <button @click="num++">+++</button></div> <input type="text" v-model="name" /> </div> </template> <script> import { ref, watch } from 'vue' export default { setup() { const num = ref(100) const name = ref('') // 监听num变量它的变化,如果有变化,则触发 watch( num, (newValue, oldValue) => { console.log(newValue) }, { // 初始化执行1次,默认为false immediate: false } ) return { num, name } } } </script> <style lang="scss" scoped> </style>
监听多个变量值的变化:
<template> <div> <div>{{ num }} <button @click="num++">+++</button></div> <input type="text" v-model="name" /> </div> </template> <script> import { ref, watch } from 'vue' export default { setup() { const num = ref(100) const name = ref('') // 以数组的方式来写,它可以监听多个变量的值的变化,回调参数为一个数组 watch([num, name], (nArr, oArr) => { console.log(nArr) }) // 在工作中,通常只关心新的值,所以只会写一个参数,就像下面这样 // watch([num, name], ([numValue, nameValue]) => { // console.log(numValue, nameValue) // }) return { num, name } } } </script> <style lang="scss" scoped> </style>
监听对象中具体的值:
<template> <div> <input type="text" v-model="user.name" /> </div> </template> <script> import { ref, watch } from 'vue' export default { setup() { const user = ref({ id: 1, name: '张三' }) // 目前对于ref定义的引用类型,默认无法监听 // watch(user, (n, o) => { // console.log(n) // }) // 但是可以指定监听对象中具体的值 watch( // 'obj.name'(n,o){} () => user.value.name, (n, o) => { console.log(n) } ) return { user } } } </script> <style lang="scss" scoped> </style>
监听ref的引用对象(添加参数3):
<template> <div> <input type="text" v-model="user.name" /> </div> </template> <script> import { ref, watch } from 'vue' export default { setup() { const user = ref({ id: 1, name: '张三' }) // 监听ref的引用对象 添加参数3 watch(user, (n, o) => { console.log(n) },{ deep:true }) return { user } } } </script> <style lang="scss" scoped> </style>
监听 reactive 定义的响应变量:
<template> <div> <input type="text" v-model="user.name" /> </div> </template> <script> import { reactive, watch } from 'vue' export default { setup() { const user = reactive({ id: 1, name: '张三' }) // 监听的是一个reactive定义的响应变量,它默认就可以进行深层监听 // 所以在工作中,如果你定义的值它是一个引用类型,建议使用reactive,基本类型用ref const stop = watch(user, (n, o) => { console.log(n) }) return { user, stop } } } </script> <style lang="scss" scoped> </style>
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。