Loading... > **问题:** vue 父组件异步请求获取数据,在请求数据没有返回数据时,子组件就已经加载了,并且它绑定的值也是空的 **解决方法(两种):** #### 方法一、 让子组件条件渲染,数据渲染完成后才渲染子组件 ```html <!-- 父组件中 条件渲染子组件prizeRoll --> <template> <view> <block v-if="flag"> <prizeRoll :lists="rankList" :listNum="5"></prizeRoll> </block> <view> </template> <script> import prizeRoll from '../../components/prize-info/prize-info.vue' export default { components: { prizeRoll }, data() { return { rankList: [], flag: flase, } }, methods: { // 异步请求数据 ranking() { this.$api('gonggao.ranking').then((res) => { this.rankList = res.data // 数据渲染完成后,将flag值改为true this.flag = true }) }, }, onLoad() { this.ranking() }, } </script> ``` #### 方法二、 > 大概逻辑:使用vuex全局状态管理,其实简单,利用vuex的辅助函数(mapState,mapMutations)mapState是将state里面的数据映射到计算中(computed),mapMutations也是类似,把vuex中mutations的方法映射到组件里面,就可以在组件里面直接使用方法了,在vuex中使用异步(actions)去掉用接口,然后在接口成功的函数里面取触发同步(mutations)里面的方法,把得到数据传给mutations里面的方法里并且给state里面的属性赋值,然后就可以在子组件中使用computed计算中去获取数据并且渲染到页面上 **vuex / index.js** ```html <script> import Vue from 'vue' import Vuex from 'vuex' import axios from 'axios' Vue.use(Vuex) export default new Vuex.Store({ //定义初始数据 state: { title: '', list: [], isShow: false }, //同步的方法 mutations: { //向state 里面设置数据 changeListMutation(state, list) { state.list = list }, //在list.vue里面点击下拉选项的时候触发 给state.title赋值 changeTitleMutation(state, title) { state.title = title }, //selectinput.vue里面点击input的时候触发 给state.isShow赋值 toggleShow(state, isShow) { state.isShow = isShow } }, //异步的方法 actions: { //在list.vue里面created生命周期里面触发 getListAction({ commit }) { axios.get('/mock/5afd9dc0c088691e06a6ab45/example/dataList') .then((res) => { commit('changeListMutation', res.data) //调用mutations下面的changeListMutation方法并且传值过去 }) .catch((error) => { console.log(error) }) } } }) // 触发异步里面的方法是用 this.$store.dispatch('这里是方法名') // 触发同步里面的方法是用 this.$store.commit('这里是方法名') </script> ``` **父组件 select.vue** ```html <template> <div class="select"> <div class="wrap"> <selectInput></selectInput> <list></list> </div> </div> </template> <script> // 引入子组件 import selectInput from '@/components/selectInput' import list from '@/components/list' export default { components:{ //加载子组件 selectInput, list }, } </script> <style> .select{ background:#4a56fe; width: 400px; margin: 100px auto 0; padding: 40px; border-radius: 10px; } .wrap{ background: #e3e5fe; border-radius: 10px; padding: 40px; } ul{ list-style: none; } </style> ``` **子组件 list.vue** > 该组件就是展示下拉选项,并且调用数据渲染 ```html <template> <div class="list"> <ul> <li v-for="(item,index) in list" :key="index" v-show="initShow" @click="changeTitle(item.title)">{{item.title}}</li> </ul> </div> </template> <script> import {mapState,mapMutations} from 'vuex' // 将vuex中的state数据和mutations中的方法映射到组件中 export default { //vue 生命周期(created)在实例创建之后,在数据初始化之前被调用 created(){ this.$store.dispatch('getListAction') //调用vuex 中的 getListAction异步方法 }, //计算state数据 computed:{ ...mapState({ list:'list', initShow:'isShow' }) }, methods:{ changeTitle(title){ this.$store.commit('changeTitleMutation',title) this.$store.commit('toggleShow',!this.initShow) } } } </script> // 触发异步里面的方法是用 this.$store.dispatch('这里是方法名') // 触发同步里面的方法是用 this.$store.commit('这里是方法名') <style> .list{ padding: 10px 0; text-align: center; } li{ line-height: 30px; height: 30px; border-radius: 15px; cursor: pointer; color:#535353; } li:hover{ background: #ff705b; color: #fff; } </style> ``` **子组件 selectinput.vue** > 该组件展示选中的数据 ```html <template> <div class="inputBox"> <input type="text" readonly :value="getTitle" @click="toggleShow" placeholder="你喜欢什么"> </div> </template> <script> export default { computed:{ // 获取vuex中的state数据并赋值绑定到 value上面 computed 里面的方法名其实就是相当于 data里面的数据,可以用this.getTitle 去访问 getTitle(){ return this.$store.state.title }, // 初始化控制下拉选项显示隐藏的状态,如果isShow是false 则不限是下拉菜单,默认是false initShow(){ return this.$store.state.isShow } }, methods:{ //点击input的时候调用该方法,这个方法去触发mutations下面的toggleShow,去改变isShow的状态,默认是isShow等于false, 然后在点击的时候去改变isShow 等于true , !this.initShow就是true,如果是true的话,下拉选项才能出来,并将改变过后的值传给toggleShow方法,去给vuex/store.js 里面的state.isShow赋值。 toggleShow(){ this.$store.commit('toggleShow',!this.initShow) } } } </script> <style> input{ outline: none; width: 100%; height: 40px; line-height: 40px; border-radius: 10px; border: 1px solid #d3d3d3; text-indent: 20px; color: #535353; } </style> ``` 最后修改:2021 年 10 月 28 日 © 允许规范转载 打赏 赞赏作者 微信 赞 0 如果觉得我的文章对你有用,请随意赞赏