翼度科技»论坛 编程开发 JavaScript 查看内容

Vue组件传值过程接收不成功的问题及解决

5

主题

5

帖子

15

积分

新手上路

Rank: 1

积分
15
Vue组件传值过程接收不成功


第一个方式
  1.   watch: {
  2.     currentleCode: {
  3.       handler() {
  4.         this.setOptions()
  5.       },
  6.       deep: true
  7.     }
  8.   },
复制代码
deep: true 使用深度监听监听传过来的数据 (如果数组的情况)

第二种方式
  1. mounted() {
  2.     this.getoptions()
  3.   }
复制代码
  1. methods: {
  2.     getoptions() {
  3.       if (this.options) {
  4.         this.setOptions()
  5.       } else {
  6.         setTimeout(() => {
  7.           this.getoptions()
  8.         }, 100)
  9.       }
  10.     }
  11.    }
复制代码
如果值传过来了 再进行后续部分 避免页面报错
额外注意的是 组件赋值的时候我们都喜欢用 =
又因为 = 不会触发Vue的set()和get()
所以推荐大家以后用set
  1. // this.filterOptions[this.cuoduleCode] = res.data
  2. this.$set(this.filterOptions, this.curreeCode, res.data)
复制代码
Vue.set()和this.$ set()的区别在于:Vue.set()是将set函数绑定在Vue构造函数上,this.$set()是将set函数绑定在Vue原型上。
使用Vue.set()和this.$ set()可以解决不重新渲染的问题

Vue组件异步数据传值问题

在组件传值中有时会遇到传的值是异步请求的数据,从而导致一些可能的问题。
如:父传子。父组件中发起请求拿到数据,将数据传给子组件,子组件却接收不到值。
在网上搜索了很多,也看了很大大佬的解决方法,如使用监听器监听传过来的数值等,但是都没有解决问题(可能是我没有学到家),但是最后还是靠其他大佬解决了问题,做了总结,让学习Vue的小伙伴们可以更好的学习。

场景解析

传值的数据是引用数据类型,你使用了reactive
  1. <template>
  2.     <Child :data='data'></Child>
  3. </template>

  4. <script setup>
  5. let data = reactive([])

  6. onMounted(()=>{
  7.     请求.then(res=>{
  8.         data = res.data
  9.     })
  10. })
  11. </script>
复制代码
乍一看,是不是没有啥问题,但是子组件那边用definProps拿到的值,它就是空的。
起初我的想法是,因为请求是异步的,子组件拿到的是初始化的空数组,然后父组件中才拿到请求回来的值。为了验证我的想法,我在父子组件中都设置了一个按钮,用来获取当前的数值。
页面加载完毕后,点击父组件的按钮,有值;点击子组件的按钮,空值;手动影响父组件,致使父组件再次渲染,此时再去点击子组件的按钮,嗯哼?有值了,所以想法应该是没有大问题的。

v-if

为了解决这个问题,我使用了监听等各种方法,都没有成功,最后,我使用了v-if
  1. <template>
  2.     <Child v-if='flag' :data='data'></Child>
  3. </template>

  4. <script setup>
  5. let data = reactive([])
  6. let flag= ref(false)

  7. onMounted(()=>{
  8.     请求.then(res=>{
  9.         data = res.data
  10.         flag.value = true
  11.     })
  12. })
  13. </script>
复制代码
在拿到请求后再去加载子组件,说白了就是让子组件的渲染时机跟着请求走。
这样子确实解决了,但是,总感觉不是很优雅。
所以,找了大佬,发现,数据那里出问题了。

ref
  1. let data = reactive([])
  2. data = res.data
复制代码
一个简单的赋值语句,相信基础好的已经看出来了。
我的data是reactive修饰的,是响应式数据,但是,我居然直接将请求回来的数据赋值给了`data`,于是原对象被覆盖,失去了响应性。
于是,它成为了一个平凡的数据,失去了响应性的它,不再被`实时`的关注,子组件也不会第一时间的注意它,它只能循规蹈矩,只有父组件发生变动,它的存在才会被注意一下。
所以!为了不让它平凡,我是使用了ref!!!
  1. <template>
  2.     <Child :data='data'></Child>
  3. </template>

  4. <script setup>
  5. let data = ref([])
  6. let flag= ref(false)

  7. onMounted(()=>{
  8.     请求.then(res=>{
  9.         data.value = res.data
  10.     })
  11. })
  12. </script>
复制代码
哦,好奇妙,.value后它依然保持着响应性,传到子组件的它被'实时'的关注着,一旦有了变化有了值,马上就会被公之于众,渲染在页面上,good!
事情到这里似乎就解决了

reactive

但是!我就是想用reactive,即使平凡,我也想要保持初心,所以我寻求了朋友的帮助
  1. <template>
  2.     <Child :data='data'></Child>
  3. </template>

  4. <script setup>
  5. let friend = reactive({
  6.     data:[]
  7. })
  8. let flag= ref(false)

  9. onMounted(()=>{
  10.     请求.then(res=>{
  11.         friend.data= res.data
  12.     })
  13. })
  14. </script>
复制代码
哦,在朋友的拥护与支持下,data成为了属性。
问题解决,proxy会监听对象属性的变化,即使属性改变,依然会保持整个对象的响应性。

总结

原因:数据失去了响应性,不管你用的ref还是reactive,要认真查看,数据是否失去了响应性
3个解决方案:

  • 1.v-if
  • 2.ref
  • 3.reactive包装
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

来源:https://www.jb51.net/javascript/322368k3d.htm
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!

举报 回复 使用道具