問題:
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>