前端vue3学习记录二

ref 和 reactive 的补充

在使用 reactive  进行对象数据的响应化时,要注意,将响应式对象分配给一个新的对象的时候,新的对象是不具有响应式性质的

function Changecar() {
 car = { brand: '红旗', price: 20000 } // 没有响应式性质
 car = reactive({ brand: '红旗', price: 20000 }) // 也没有响应式性质
 Object.assign(car, { brand: '红旗', price: 20000 }) // 利用对象的拷贝接口就可以使car仍然具有响应式的性质
}

使用 ref 对对象进行响应式时,就不会发生上述情况

function Changecar() {
// 使用ref就不会发生新对象失去响应式性质的情况
  car.value = { brand: '红旗', price: 20000 }
}

toRefs 和 toRef

toRefs 可以将一个reactive 的响应式对象转化为多个 由ref 定义的响应式对象,当将一个reactive定义的响应式对象解构时就不会丢失他的响应式式属性

let person = reactive({ name: '陈欢', age: 20 })

 let { name, age } = person
let { name, age } = toRefs(person)

toref 的使用

let person = reactive({ name: '陈欢', age: 20 })
let  n1 = ref(person, 'age')

vue3 中的computed计算属性

你可以通过computed函数来定义一个计算属性computed函数接收一个计算函数作为参数,并返回一个响应式的ref对象。下面代码中有两种computed的写法,一种是计算函数做参数的写法,另外一种是对象形式的写法

computed 计算属性以一个计算函数作为参数时,他只有只读的属性,以一个对象作为参数时,里面的 get函数是返回 计算属性的函数, 而set函数是接收一个传递给计算属性的新值

<script lang="ts" , setup>
// 引入包
import { ref, reactive, toRefs, computed } from 'vue'
let firstname = ref('陈')
let lastname = ref('欢')

 let fullname = computed(() => {
   return firstname.value.slice(0, 1).toUpperCase() + firstname.value.slice(1) + '-' + lastname.value })

// computed 计算属性中的get函数 和 set函数??
let fullname = computed({
  get() {
    return (
      firstname.value.slice(0, 1).toUpperCase() + firstname.value.slice(1) + '-' + lastname.value
    )
  },
  // val参数是什么??
  set(val) {
    const [stl1, stl2] = val.split('-')
    firstname.value = stl1
    lastname.value = stl2
  }
})

function Changename() {
  fullname.value = '徐-勇钢'
}
</script>

watch监视

vue3中的watch监视以下四种情况

1.ref 定义的数据

2. reactive 定义的数据

3. 函数返回的一个值(getter 函数)

4.一个包含上述内容的数组

1.ref 的 watch 监视基本属性 

首先,也先在 setup 中引入 watch监视包 

watch 是一个函数, 第一个参数值是你要监视的对象,第二个参数是一个回调函数,函数中的第一个形参为监视对象的新的值,第二个参数为监视对象变化之前的值,可以在回调函数中设置要进行的操作,并且注意 watch 函数 的返回只可以用来结束监视。

let sum = ref(0)
function Changesum() {
  sum.value += 1
}
let stop = watch(sum, (newvalue, oldvalue) => {
  console.log('sum的值变化了', newvalue, oldvalue)
  if (newvalue > 10) stop()
})

2.ref 的watch监视对象属性

ref监视对象时注意:ref 是一个浅层监视监视着对象的地址,只有对象发生变化才会出发监视,对象里面的属性发生变化并不会触发监视,需要在watch中加上 deep: true 来手动开启深层监视

如果修改的是对象中的属性,那么监视里面的 watch 中newvalue 参数和 oldvalue参数都是新的值,因为他们对象的地址没有发生变化

 如果修改的是整个ref 定义的对象,那么对应的newvalue参数和oldvaluea参数对应的就是新值和旧值,因为不是同一个对象了

let person = ref({ name: '陈欢', age: 20 })
function Changename() {
  person.value.name += '徐勇钢'
}
function Changeage() {
  person.value.age += 1
}
function Changeperson() {
  // Object.assign(person, { name: '徐勇', age: 30 })
  person.value = { name: '徐勇', age: 30 }
}

watch(
  person,
  (newvalue, oldvalue) => {
    console.log('person改变了', newvalue, oldvalue)
  },
  { deep: true, immediate: true }
)

 注意上述代码中加了deep 属性开启深度监视,immediate 为开启立即监视,相当于do while一样,没触发监视时,就先执行一遍watch监视里的内容

3.reactive 的watch监视对象属性

监视 reactive 定义的 对象类型数据时,默认开启深度监视且不可关闭
深度监视就是指你对象中的任何一个属性发生变化都会监视到, 相当于隐式创建深层监听
为什么监视的新值和旧值没有发生变化,因为用的是reactive ,person对象的地址一直都没有变化,你改变名字, 改变年龄,改变对象的时候都没有创建新的对象 ,person的地址一直没有发生变化

监视到对象的某个属性时,新值和旧的值就一定不一样

let person = reactive({ name: '陈欢', age: 20 })
function Changename() {
  person.name = '徐勇钢'
}
function Changeage() {
  person.age += 1
}
function Changeperson() {
  Object.assign(person, { name: '徐勇', age: 30 })
}

watch(person, (newvalue, oldvalue) => {
  console.log('person改变了', newvalue, oldvalue)
})

4.监视ref或reactive对应的对象类型数据中的某一个属性

当只想监视对象类型中的某一个属性时的情况;

监视的是对象里面的基本属性时

注意:当监视的对象里面的基本属性时,watch 监视函数里面的监视对象要写成函数式,可以简写成箭头函数的形式

let person = reactive({ name: '陈欢', 
age: 20, 
car: { first: 'su7', second: '宝马' } 
})

watch(
   () => person.name,
  (newvalue, oldvalue) => {
    console.log('person改变了', newvalue, oldvalue)
  }
)

 如上述所示,监视的是person对象里面的基本属性:name属性,所以监视对象写成箭头函数的简写形式

监视的是对象里面的对象属性, 这种情况比较复杂

 监视的是对象中的对象属性时,并没有要求一定要写成函数的形式,可以直接写要监视的对象,如:person.car, 但是这种情况的话,只有监视的对象里面的属性发生变化才会触发监视,写成函数的形式的话,() => person.car, 虽然他最大的对象时reactive 定义的响应式,但是此时只有你监视的对象的对象整体发生变化时,才会触发监视器,综上,当监视的是对象里面的一个对象属性时,监视的那个对象也尽量写成函数的形式,并且在第三个参数处加上手动开启深度监视的代码,这样你所监视的对象的对象的属性无论里面的属性改变还是整个对象改变都会监视到。

对于 写person.car 的理解:对于修改这里的属性可以触发监视器,但是当对象发生变化时,地址发生了变化,就触发不了监视器

let person = reactive({ name: '陈欢', age: 20, car: { first: 'su7', second: '宝马' } })

watch(
  // () => person.name,
  () => person.car,
  // person.car,
  (newvalue, oldvalue) => {
    console.log('person改变了', newvalue, oldvalue)
  },
  { deep: true }
)

5.上述数据的组合监视

只要以数组的方式写出要监视的对象就可以

let person = reactive({ name: '陈欢', age: 20, car: { first: 'su7', second: '宝马' } })

watch(
  
  [() => person.car, () = >person.name ],
 
  (newvalue, oldvalue) => {
    console.log('person改变了', newvalue, oldvalue)
  },
  { deep: true }
)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值