vue/uni-app 父组件异步获取动态数据传递给子组件 获取不到值

问题:

vue 父组件异步请求获取数据,在请求数据没有返回数据时,子组件就已经加载了,并且它绑定的值也是空的

解决方法(两种):

方法一、

让子组件条件渲染,数据渲染完成后才渲染子组件

 1 <!-- 父组件中 条件渲染子组件prizeRoll -->
 2 <template>
 3   <view>
 4     <block v-if="flag">
 5       <prizeRoll :lists="rankList" :listNum="5"></prizeRoll>
 6     </block>
 7     <view>
 8 </template>
 9 
10 <script>
11 import prizeRoll from '../../components/prize-info/prize-info.vue'
12 export default {
13   components: { prizeRoll },
14   data() {
15     return {
16       rankList: [],
17       flag: flase,
18     }
19   },
20   methods: {
21     // 异步请求数据
22     ranking() {
23       this.$api('gonggao.ranking').then((res) => {
24         this.rankList = res.data
25         // 数据渲染完成后,将flag值改为true
26         this.flag = true
27       })
28     },
29   },
30   onLoad() {
31     this.ranking()
32   },
33 }
34 </script>

方法二、

大概逻辑:使用vuex全局状态管理,其实简单,利用vuex的辅助函数(mapState,mapMutations)mapState是将state里面的数据映射到计算中(computed),mapMutations也是类似,把vuex中mutations的方法映射到组件里面,就可以在组件里面直接使用方法了,在vuex中使用异步(actions)去掉用接口,然后在接口成功的函数里面取触发同步(mutations)里面的方法,把得到数据传给mutations里面的方法里并且给state里面的属性赋值,然后就可以在子组件中使用computed计算中去获取数据并且渲染到页面上
vuex / index.js
 1 <script>
 2 import Vue from 'vue'
 3 import Vuex from 'vuex'
 4 import axios from 'axios'
 5 Vue.use(Vuex)
 6 export default new Vuex.Store({
 7     //定义初始数据
 8     state: {
 9         title: '',
10         list: [],
11         isShow: false
12     },
13     //同步的方法
14     mutations: {
15         //向state 里面设置数据
16         changeListMutation(state, list) {
17             state.list = list
18         },
19         //在list.vue里面点击下拉选项的时候触发 给state.title赋值
20         changeTitleMutation(state, title) {
21             state.title = title
22         },
23         //selectinput.vue里面点击input的时候触发 给state.isShow赋值
24         toggleShow(state, isShow) {
25             state.isShow = isShow
26         }
27     },
28     //异步的方法
29     actions: {
30         //在list.vue里面created生命周期里面触发
31         getListAction({ commit }) {
32             axios.get('/mock/5afd9dc0c088691e06a6ab45/example/dataList')
33                 .then((res) => {
34                     commit('changeListMutation', res.data) //调用mutations下面的changeListMutation方法并且传值过去
35                 })
36                 .catch((error) => {
37                     console.log(error)
38                 })
39 
40         }
41     }
42 })
43 // 触发异步里面的方法是用 this.$store.dispatch('这里是方法名')
44 // 触发同步里面的方法是用 this.$store.commit('这里是方法名')
45 </script>

父组件 select.vue

 1 <template>
 2   <div class="select">
 3     <div class="wrap">
 4         <selectInput></selectInput>
 5         <list></list>
 6     </div>
 7   </div>
 8 </template>
 9 <script>
10   // 引入子组件 
11   import selectInput from '@/components/selectInput'  
12   import list from '@/components/list'
13   export default {
14     components:{   //加载子组件
15       selectInput,
16       list
17     },
18   }
19 </script>
20 <style>
21   .select{
22     background:#4a56fe;
23     width: 400px;
24     margin: 100px auto 0;
25     padding: 40px;
26     border-radius: 10px;
27   }
28   .wrap{
29     background: #e3e5fe;
30     border-radius: 10px;
31     padding: 40px;
32   }
33   ul{
34     list-style: none;
35   }
36 </style>

子组件 list.vue

该组件就是展示下拉选项,并且调用数据渲染

 1 <template>
 2   <div class="list">
 3     <ul>
 4       <li v-for="(item,index) in list" :key="index" v-show="initShow" @click="changeTitle(item.title)">{{item.title}}</li>
 5     </ul>
 6   </div>
 7 </template>
 8 
 9 <script>
10     import {mapState,mapMutations} from 'vuex'  // 将vuex中的state数据和mutations中的方法映射到组件中
11     export default {
12         //vue 生命周期(created)在实例创建之后,在数据初始化之前被调用
13         created(){  
14             this.$store.dispatch('getListAction')  //调用vuex 中的 getListAction异步方法
15         },
16         //计算state数据
17         computed:{
18             ...mapState({
19               list:'list',
20               initShow:'isShow'
21             })
22         },
23         methods:{
24             changeTitle(title){
25               this.$store.commit('changeTitleMutation',title)
26               this.$store.commit('toggleShow',!this.initShow)
27             }
28         }
29     }
30 </script>
31 // 触发异步里面的方法是用 this.$store.dispatch('这里是方法名')
32 // 触发同步里面的方法是用 this.$store.commit('这里是方法名')
33 
34 <style>
35   .list{
36     padding: 10px 0;
37     text-align: center;
38   }
39   li{
40     line-height: 30px;
41     height: 30px;
42     border-radius: 15px;
43     cursor: pointer;
44     color:#535353;
45   }
46   li:hover{
47     background: #ff705b;
48     color: #fff;
49   }
50 </style>

子组件 selectinput.vue

该组件展示选中的数据

 1 <template>
 2   <div class="inputBox">
 3     <input type="text" readonly :value="getTitle" @click="toggleShow" placeholder="你喜欢什么">
 4   </div>
 5 </template>
 6 
 7 <script>
 8 export default {
 9   computed:{
10     // 获取vuex中的state数据并赋值绑定到 value上面  computed 里面的方法名其实就是相当于 data里面的数据,可以用this.getTitle 去访问
11     getTitle(){ 
12       return this.$store.state.title
13     },
14     // 初始化控制下拉选项显示隐藏的状态,如果isShow是false 则不限是下拉菜单,默认是false
15     initShow(){
16         return this.$store.state.isShow
17     }
18   },
19   methods:{
20     //点击input的时候调用该方法,这个方法去触发mutations下面的toggleShow,去改变isShow的状态,默认是isShow等于false, 然后在点击的时候去改变isShow 等于true ,  !this.initShow就是true,如果是true的话,下拉选项才能出来,并将改变过后的值传给toggleShow方法,去给vuex/store.js 里面的state.isShow赋值。
21     toggleShow(){
22       this.$store.commit('toggleShow',!this.initShow)
23     }
24   }
25 }
26 </script>
27 
28 <style>
29 input{
30   outline: none;
31   width: 100%;
32   height: 40px;
33   line-height: 40px;
34   border-radius: 10px;
35   border: 1px solid #d3d3d3;
36   text-indent: 20px;
37   color: #535353;
38 }
39 </style>

转载自:https://www.jianshu.com/p/4450b63a27fe

posted @ 2020-10-30 10:25  九鹤  阅读(4972)  评论(0编辑  收藏  举报