vue3第二次传递数据方法无法获取到最新的值

vue3第二次传递数据方法无法获取到最新的值

使用reactive父组件第二次传递给子组件的数据:方法中可以获取到最新数据

<template>   <div>     <div>       <h1>子组件</h1>       <child :infoObj='infoObj' ref="childRef"></child>     </div>     <button @click='updateHandler'>跟新值</button>     <div>       <h1>父页面</h1>       <p>{{ infoObj }}</p>     </div>   </div> </template>  <script setup lang="ts"> import child from '@/components/child.vue' import { ref,reactive } from 'vue' let infoObj = reactive({   name:'张三',   age:26 }) const childRef = ref() function updateHandler(){   infoObj.name = '李四'   infoObj.age = 28   // 跟新值后,调用父组件的方法。   childRef.value.getData() } </script> 
<template>   <div>     <h1> {{ props.infoObj }}</h1>   </div> </template>  <script setup lang="ts"> let props = defineProps({   infoObj:Object, }) function getData(){   console.log('infoObj', props.infoObj) } defineExpose({   getData }) </script> 

vue3第二次传递数据方法无法获取到最新的值

使用ref父组件第二次传递给子组件的数据:不能获取到最新的数据

<template>   <div>     <div>       <h1>子组件</h1>       <child :infoObj='infoObj' ref="childRef"></child>     </div>     <button @click='updateHandler'>跟新值</button>     <div>       <h1>父页面</h1>       <p>{{ infoObj }}</p>     </div>   </div> </template> <script setup lang="ts"> import child from '@/components/child.vue' import { ref } from 'vue' let infoObj = ref({   name:'张三',   age:26 }) const childRef = ref() function updateHandler(){   infoObj.value = {     name:'李四',     age:28   }   // 跟新值后,调用父组件的方法。看下getData是否可以获取到最新的值   childRef.value.getData() } </script> 
<template>   <div>     <h1> {{ props.infoObj }}</h1>   </div> </template> <script setup lang="ts"> let props = defineProps({   infoObj:Object, }) function getData(){   console.log('infoObj', props.infoObj) } defineExpose({   getData }) </script> 

vue3第二次传递数据方法无法获取到最新的值

办法1:将数据作为函数的参数进行传递

<template>   <div>     <div>       <h1>子组件</h1>       <child :infoObj='infoObj' ref="childRef"></child>     </div>     <button @click='updateHandler'>跟新值</button>     <div>       <h1>父页面</h1>       <p>{{ infoObj }}</p>     </div>   </div> </template> <script setup lang="ts"> import child from '@/components/child.vue' import { ref } from 'vue' let infoObj = ref({   name:'张三',   age:26 }) const childRef = ref() function updateHandler(){   infoObj.value = {     name:'李四',     age:28   }   // 将数据作为函数的参数进行传递   childRef.value.getData(infoObj.value) } </script> 
<template>   <div>     <h1> {{ props.infoObj }}</h1>   </div> </template> <script setup lang="ts"> let props = defineProps({   infoObj:Object, }) function getData(mess:any){   console.log('infoObj', props.infoObj)   console.log('将数据作为函数的参数进行传递:mess', mess) } defineExpose({   getData }) </script> 

vue3第二次传递数据方法无法获取到最新的值

解决办法2:在调用方法时使用 nextTick

<template>   <div>     <div>       <h1>子组件</h1>       <child :infoObj='infoObj' ref="childRef"></child>     </div>     <div>       <h1>父页面</h1>       <p>{{ infoObj }}</p>     </div>     <button @click='updateHandler'>跟新值</button>   </div> </template> <script setup lang="ts"> import child from '@/components/child.vue' import { nextTick, ref } from 'vue' let infoObj = ref({   name:'张三',   age:26 }) const childRef = ref() function updateHandler(){   infoObj.value = { name: '李四', age: 28 };   // 推荐在这里使用nextTick   nextTick(() => {     childRef.value.getData()   }) } </script> 
<template>   <div>     <h1> {{ props.infoObj }}</h1>   </div> </template> <script setup lang="ts"> let props = defineProps({   infoObj:Object, }) function getData(){   // 或者在这里使用nextTick。   console.log('getData 方法获取值',  props.infoObj.name, props.infoObj.age) } defineExpose({   getData }) </script> 

vue3第二次传递数据方法无法获取到最新的值

结论

使用ref父组件第二次传递给子组件的数据(基本数据和引用数据):不能获取到最新的数据。

使用reactive和ref传递参数给子组件,为啥ref第二次子组件无法获取最新的数据?而reactive可以

在 Vue 3 中,reactive 和 ref 在传递给子组件时的行为有所不同。
这也说明了 reactive 和 ref 是有区别的(屁话)。

ref 和 reactive 的区别

1,ref可以试用于任何数据类型,而reactive只适用于对象类型。
2,在js模块ref获取值,设置值,需要点value, ‌在模板中使用不需要点value。 而reactive都不需要。
3,ref可以完全替换整个对象,不会失去响应式。
reactive不能直接替换整个对象(否则会失去响应式)。需要逐个修改属性或使用 Object.assign
4,返回值不同。ref返回一个‌包装对象‌。reactive返回一个‌Proxy 对象‌

ref完全替换 不会失去响应式

<template>   <button type="button" @click="updateHandler">更改数据</button>   <p>数据{{ objRef }}</p> </template> <script setup lang="ts"> import { ref } from 'vue'; const objRef = ref({ age: 1 }) function updateHandler(){   //完全替换 不会失去响应式   objRef.value = { age: 100 }  } </script> 

reactive不能直接替换整个对象(会失去响应式)

const objReactive = reactive({ a: 1 }) // 错误方式(失去响应性) objReactive = { b: 2 }  // 正确方式 或者逐个修改属性 Object.assign(objReactive, { b: 2 }) 

[错误]:ref解构不会失去响应式。reactive解构或展开会失去响应式。[这句话不正确]

ref和reactive解构都会失去响应式。都需要通过toRefs 或者toRef 来进行解决。

reactive 解构会失去响应式

<template>   <button type="button" @click="updateHandler">更改数据</button>   <p>数据{{ name }} {{  age}}</p> </template> <script setup lang="ts"> import { reactive } from 'vue'; const state = reactive({ name: '张三', age: 20 }) // reactive解构会失去响应式 let { name, age } = state function updateHandler(){   // 更新数据后,页面不会跟新   name = '王麻子'   age = 1000 } </script> 

vue3第二次传递数据方法无法获取到最新的值

ref 解构会失去响应式

<template>   <div>     <p>Name: {{ name }}</p>     <p>Age: {{ age }}</p>     <button @click="changeName">Change Name</button>   </div> </template>  <script setup> import { ref } from 'vue' // 使用 ref 创建响应式对象 const user = ref({   name: 'Alice',   age: 25 }) // 解构 ref 对象 - 会失去响应式,视图不会跟新 let { name, age } = user.value function changeName() {   name = 'Bob' // 直接修改解构出来的属性 } </script> 

vue3第二次传递数据方法无法获取到最新的值

toRefs()​解构ref,解构后仍然保持响应式

<template>   <div>     <p>Name: {{ name }}</p>     <p>Age: {{ age }}</p>     <button @click="changeName">Change Name</button>   </div> </template> <script setup> import { ref,toRefs } from 'vue' // 使用 ref 创建响应式对象 const user = ref({   name: 'Alice',   age: 25 }) // 通过toRefs解构不会失去响应式 let { name, age } = toRefs(user.value)  function changeName() {   name.value = '大大再大' // 直接修改解构出来的属性 } </script> 

vue3第二次传递数据方法无法获取到最新的值

toRef()​解构reactive,解构后仍然保持响应式

<template>   <button type="button" @click="updateHandler">更改数据</button>   <p>数据{{ name }} {{  age}}</p> </template> <script setup lang="ts"> import { reactive, toRefs } from 'vue'; const state = reactive({ name: '张三', age: 20 }) // 通过toRefs解构不会失去响应式 let { name, age } =  toRefs(state)  function updateHandler(){   // 更新数据后,页面不会跟新   name.value = '王麻子'   age.value = 1000 } </script> 

vue3第二次传递数据方法无法获取到最新的值

toRefs()​

官网:将一个响应式对象转换为一个普通对象。
这个普通对象的[每个属性]都是指向源对象[相应属性的] ref。
每个单独的 ref 都是使用 toRef() 创建的。
我的理解:
toRefs 可以把一个响应式对象转换为普通的对象。
该普通对象的每一个值都是ref。
由于变成了ref,所以我们使用每个属性的时候需要点value。

ref和reactive的使用场景

ref 适合于基本数据类型,reactive适合于对象类型。
ref 适合完全替换整个对象
我喜欢用ref定义基本数据类型和数组。对象使用reactive。

ref的本质

我理解的ref本质上是reactive的再封装。
使用reactive定义响应式数据时,若数据不是对象类型直接就返回了。
就不会进行后续的数据响应式处理了。
这也就是我只用reactive定义对象型响应式数据的原因

发表评论

您必须 [ 登录 ] 才能发表留言!

相关文章