详解vue父组件传递props异步数据到子组件的问题

案例一

  父组件parent.vue

// asyncData为异步获取的数据,想传递给子组件使用
<template>
 <div>
  父组件
  <child :child-data="asyncData"></child>
 </div>
</template>

<script>
 import child from ‘./child‘
 export default {
  data: () => ({
   asyncData: ‘‘
  }),
  components: {
   child
  },
  created () {
  },
  mounted () {
   // setTimeout模拟异步数据
   setTimeout(() => {
    this.asyncData = ‘async data‘
    console.log(‘parent finish‘)
   }, 2000)
  }
 }
</script>

  子组件child.vue

<template>
 <div>
  子组件{{childData}}
 </div>
</template>

<script>
 export default {
  props: [‘childData‘],
  data: () => ({
  }),
  created () {
   console.log(this.childData) // 空值
  },
  methods: {
  }
 }
</script>

  上面按照这里的解析,子组件的html中的{{childData}}的值会随着父组件的值而改变,但是created里面的却不会发生改变(生命周期问题)

案例二

  parent.vue

<template>
 <div>
  父组件
  <child :child-object="asyncObject"></child>
 </div>
</template>

<script>
 import child from ‘./child‘
 export default {
  data: () => ({
   asyncObject: ‘‘
  }),
  components: {
   child
  },
  created () {
  },
  mounted () {
   // setTimeout模拟异步数据
   setTimeout(() => {
    this.asyncObject = {‘items‘: [1, 2, 3]}
    console.log(‘parent finish‘)
   }, 2000)
  }
 }
</script>

  child.vue

<template>
 <div>
  子组件<!--这里很常见的一个问题,就是{{childObject}}可以获取且没有报错,但是{{childObject.items[0]}}不行,往往有个疑问为什么前面获取到值,后面获取不到呢?-->
  <p>{{childObject.items[0]}}</p>
 </div>
</template>

<script>
 export default {
  props: [‘childObject‘],
  data: () => ({
  }),
  created () {
   console.log(this.childObject) // 空值
  },
  methods: {
  }
 }
</script>

  created里面的却不会发生改变, 子组件的html中的{{{childObject.items[0]}}的值虽然会随着父组件的值而改变,但是过程中会报错

// 首先传过来的是空,然后在异步刷新值,也开始时候childObject.items[0]等同于‘‘.item[0]这样的操作,所以就会报下面的错
vue.esm.js?8910:434 [Vue warn]: Error in render function: "TypeError: Cannot read property ‘0‘ of undefined"

针对二的解决方法:

1、使用v-if可以解决报错问题,和created为空问题

// parent.vue
<template>
 <div>
  父组件
  <child :child-object="asyncObject" v-if="flag"></child>
 </div>
</template>

<script>
 import child from ‘./child‘
 export default {
  data: () => ({
   asyncObject: ‘‘,
   flag: false
  }),
  components: {
   child
  },
  created () {
  },
  mounted () {
   // setTimeout模拟异步数据
   setTimeout(() => {
    this.asyncObject = {‘items‘: [1, 2, 3]}
    this.flag = true
    console.log(‘parent finish‘)
   }, 2000)
  }
 }
</script>
//child.vue
<template>
 <div>
  子组件//不报错
  <p>{{childObject.items[0]}}</p>
 </div>
</template>

<script>
 export default {
  props: [‘childObject‘],
  data: () => ({
  }),
  created () {
   console.log(this.childObject)// Object {items: [1,2,3]}
  },
  methods: {
  }
 }
</script>

2、子组件使用watch来监听父组件改变的prop,使用methods来代替created

<template>
 <div>
  子组件<!--1-->
  <p>{{test}}</p>
 </div>
</template>

<script>
 export default {
  props: [‘childObject‘],
  data: () => ({
   test: ‘‘
  }),
  watch: {
   ‘childObject.items‘: function (n, o) {
    this.test = n[0]
    this.updata()
   }
  },
  methods: {
   updata () { // 既然created只会执行一次,但是又想监听改变的值做其他事情的话,只能搬到这里咯
    console.log(this.test)// 1
   }
  }
 }
</script>

3、子组件watch computed data 相结合,有点麻烦

<template>
 <div>
  子组件<!--这里很常见的一个问题,就是{{childObject}}可以获取且没有报错,但是{{childObject.items[0]}}不行,往往有个疑问为什么前面获取到值,后面获取不到呢?-->
  <p>{{test}}</p>
 </div>
</template>

<script>
 export default {
  props: [‘childObject‘],
  data: () => ({
   test: ‘‘
  }),
  watch: {
   ‘childObject.items‘: function (n, o) {
    this._test = n[0]
   }
  },
  computed: {
   _test: {
    set (value) {
     this.update()
     this.test = value
    },
    get () {
     return this.test
    }
   }
  },
  methods: {
   update () {
    console.log(this.childObject) // {items: [1,2,3]}
   }
  }
 }
</script>

4、使用emit,on,bus相结合

<template>
 <div>
  子组件
  <p>{{test}}</p>
 </div>
</template>

<script>
 export default {
  props: [‘childObject‘],
  data: () => ({
   test: ‘‘
  }),
  created () {
   // 绑定
   this.$bus.on(‘triggerChild‘, (parmas) => {
    this.test = parmas.items[0] // 1
    this.updata()
   })
  },
  methods: {
   updata () {
    console.log(this.test) // 1
   }
  }
 }
</script>

  这里使用了bus这个库,parent.vue和child.vue必须公用一个事件总线(也就是要引入同一个js,这个js定义了一个类似let bus = new Vue()的东西供这两个组件连接),才能相互触发

5、使用prop default来解决{{childObject.items[0]}}

<template>
 <div>
  父组件
  <child :child-object="asyncObject"></child>
 </div>
</template>

<script>
 import child from ‘./child‘
 export default {
  data: () => ({
   asyncObject: undefined // 这里使用null反而报0的错
  }),
  components: {
   child
  },
  created () {
  },
  mounted () {
   // setTimeout模拟异步数据
   setTimeout(() => {
    this.asyncObject = {‘items‘: [1, 2, 3]}
    console.log(‘parent finish‘)
   }, 2000)
  }
 }
</script>
<template>
 <div>
  子组件<!--1-->
  <p>{{childObject.items[0]}}</p>
 </div>
</template>

<script>
 export default {
  props: {
   childObject: {
    type: Object,
    default () {
     return {
      items: ‘‘
     }
    }
   }
  },
  data: () => ({
  }),
  created () {
   console.log(this.childObject) // {item: ‘‘}
  }
 }
</script>

原文地址:https://www.cnblogs.com/goloving/p/9114389.html

时间: 2024-10-14 01:48:43

详解vue父组件传递props异步数据到子组件的问题的相关文章

【Vue】详解Vue组件系统

Vue渲染的两大基础方式 new 一个Vue的实例 这个我们一般会使用在挂载根节点这一初始化操作上: new Vue({ el: '#app' }) 注册组件并使用 通过Vue.component()去注册一个组件,你就可以全局地使用它了,具体体现在每个被new的 Vue 实例/注册组件, 的template选项属性或者对应的DOM模板中,去直接使用 注册组件 全局注册 例如,放在通过new创建的Vue实例当中: Vue.component('my-component', { template:

【java项目实践】详解Ajax工作原理以及实现异步验证用户名是否存在+源码下载(java版)

一年前,从不知道Ajax是什么,伴随着不断的积累,到现在经常使用,逐渐有了深入的认识.今天,如果想开发一个更加人性化,友好,无刷新,交互性更强的网页,那您的目标一定是Ajax. 介绍 在详细讨论Ajax是什么之前,先让我们花一分钟了解一下Ajax做什么.如图所示: 如上图展示给我们的就是使用Ajax技术实现的效果.伴随着web应用的越来越强大而出现的是等待,等待服务器响应,等待浏览器刷新,等待请求返回和生成新的页面成为了程序员们的最最头疼的难题.随着Ajax的出现使web应用程序变得更完善,更友

详解vue 路由跳转四种方式 (带参数)

详解vue 路由跳转四种方式 (带参数):https://www.jb51.net/article/160401.htm 1.  router-link ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 1. 不带参数  <router-link :to="{name:'home'}"> <router-link :to="{path:'/home'}"> //name,path都行, 建议用name /

父组件如何获取子组件数据,子组件如何获取父组件数据,父子组件如何传值

1.父组件如何主动获取子组件的数据 方案1:$children $children用来访问子组件实例,要知道一个组件的子组件可能是不唯一的,所以它的返回值是个数组 定义Header.HelloWorld两个组件 <template> <div class="index"> <Header></Header> <HelloWorld :message="message"></HelloWorld>

rsync参数详解、利用ssh、rsync 实现数据的定时同步

rsync 简介 rsync(remote synchronize)是一个远程数据同步工具,可通过 LAN/WAN 快速同步多台主机之间的文 件.也可以使用 rsync 同步本??硬盘中的不同目录. rsync 是用于替代 rcp 的一个工具,rsync 使用所谓的 rsync算法 进行数据同步,这种算法只传送两个文件 的不同部分,而不是每次都整份传送,因此速度相当快.您可以参考 How Rsync Works A PracticalOverview 进一步了解 rsync 的运作机制. rsy

vue组件值传递之父组件向子组件传递(props)

<template> <div class="hello"> <h1>{{ msg }}</h1> <ul> <li v-bind="message" v-for="item in message">{{item}} </li> </ul> <test v-bind:child_message="message"><

详解vue全局组件与局部组件使用方法

这篇文章主要为大家详细介绍了vue全局组件与局部组件的使用方法,具有一定的参考价值,对此有需要的朋友可以参考学习下.如有不足之处,欢迎批评指正. vue全局/局部注册,以及一些混淆的组件main.js入口文件的一些常用配置, 在入口文件上定义的public.vue为全局组件,在这里用的是pug模版 .wraper 的形式相当于<div class=wraper></div> -main.js文件 **main.js入口文件的内容** import Vue from 'vue' im

使用-Prop-传递数据(父组件通过 props 向下传递数据给子组件)

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>使用-Prop-传递数据</title> <script src="vue.js"></script> </head> <body> <div id="app"&g

Vue事件在组件中的简单使用以及子组件事件触发父组件自定义事件

在Vue中,通过v-on 来监听DOM事件,可以通过@简写代替. 一个简单的在组件中的事件调用示例 在template的Html中使用v-on或@监听一个click事件,并指定事件执行handleClick方法. handleClick需要在组件的methods集合中定义. <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta