### 渲染时因异步易报错的点
深层次的找到某个值:
<div>{{childrenList[0].class2Name.name}}</div>
此时容易报错:
vue.runtime.esm.js?2b0e:619 [Vue warn]: Error in render: "TypeError: Cannot read property 'class2Name' of undefined"
found in
---> <CategoryContainer> at src/pages/Category/CategoryContainer.vue
<Category> at src/pages/Category/index.vue
<App> at src/App.vue
<Root>
解决:
(1)加 v-if 判断:
<div v-if="childrenList[0]">{{childrenList[0].class2Name.name}}</div>
(2)三目运算判断:
<div>{{childrenList[0]?childrenList[0].class2Name.name:""}}</div>
<li v-for="item in childrenList[0].class3Group" :key="item.id"> <img :src="item.class_photo"> <span>{{item.name}}</span> </li>
报class3Group不存在,解决:
<li v-for="item in (childrenList[0]?childrenList[0].class3Group:'')" :key="item.id"> <img :src="item.class_photo"> <span>{{item.name}}</span> </li>
### 分类页面数据渲染
分析思路:分类页面Category中有三个组件:分别是index.vue(主体部分----父组件)、CategoryTab.vue(左侧tab----子组件)、CategoryContainer.vue(右侧列表----子组件)。由index.vue中获取数据,再分别传给子组件渲染页面(父传子)。tab的切换同时有个 class_id 值,将这个值作为参数传给index.vue去执行请求函数(子传父)。
(1)渲染 CategoryTab CategoryContainer 组件:
①api/index.js中添加接口:
// 分类 classify:{ classify:"/v3/classify", classifyList:"/v3/classifylist" }
②api/request.js中请求接口数据:
// 分类页面 export const classifyPageApi=(store_id_list,class_id)=>{ return http({ method:"get", data:{ store_id_list, class_id }, url:api.classify.classify }) }
③pages/Category/index.vue中引入 classifyPageApi() 方法:
import {classifyPageApi} from "@api/request.js";
④pages/Category/index.vue中获取 classifyPageApi() 接口参数
data(){ return{ classOneGroup:[], childrenList:[], store_id_list:1, class_id:"" } }, methods: { async getClassifyPageData(store_id_list,class_id){ let data=await classifyPageApi(store_id_list,class_id); this.classOneGroup=data.data.classOneGroup; this.childrenList=data.data.childrenList; } }, created() { this.getClassifyPageData(this.store_id_list,this.class_id); }
⑤pages/Category/index.vue中将获取到的 classOneGroup childrenList 分别传给 CategoryTab CategoryContainer 组件:
<div class="category_wrapper"> <CategoryTab :classOneGroup="classOneGroup"></CategoryTab> <CategoryContainer :childrenList="childrenList"></CategoryContainer> </div>
⑥pages/Category/CategoryTab.vue中通过props拿到数据:
props:["classOneGroup"],
⑦pages/Category/CategoryTab.vue中通过 classOneGroup 渲染页面:
<ul> <v-touch tag="li" v-for="(item,index) in classOneGroup" :key="item.id">{{item.name}}</v-touch> </ul>
⑧pages/Category/CategoryContainer.vue中通过props拿到数据:
props:["childrenList"],
⑨pages/Category/CategoryContainer.vue中通过 childrenList 渲染页面:
<ul> <li v-for="item in (childrenList[0]?childrenList[0].class3Group:'')" :key="item.id"> <img :src="item.class_photo"> <span>{{item.name}}</span> </li> </ul>
(2)通过点击 CategoryTab 获得id,再次请求数据渲染 CategoryContainer :
①pages/Category/index.vue中绑定自定义事件 getClassId :
<CategoryTab :classOneGroup="classOneGroup" @getClassId="toggleTab"></CategoryTab>
toggleTab(id){ this.getClassifyPageData(this.store_id_list,id); }
②pages/Category/CategoryTab.vue中绑定tap事件(clickCurrent(index,item.id)):
<ul> <v-touch tag="li" v-for="(item,index) in classOneGroup" :key="item.id" :class="activeIndex==index?'active':''" @tap="clickCurrent(index,item.id)">{{item.name}}</v-touch> </ul>
③pages/Category/CategoryTab.vue中点击li切换颜色时通过 $emit() 触发父组件中的 getClassId 事件,将id传过去:
data() { return { activeIndex:0 } }, methods: { clickCurrent(index,id){ this.activeIndex=index; this.$emit("getClassId",id); } }
### CategoryContainer.vue进入Classify.vue-动态路由
①CategoryContainer.vue中为每个li绑定tap事件(goClassify()):
<ul> <v-touch tag="li" v-for="item in (childrenList[0]?childrenList[0].class3Group:'')" :key="item.id" @tap="goClassify(item.class2Id,item.id)"> <img :src="item.class_photo"> <span>{{item.name}}</span> </v-touch> </ul>
methods: { goClassify(class2_id,class3_id){ this.$router.push("/classify/"+this.store_id_list+"/"+class2_id+"/"+class3_id) } }
②router/classify/index.js中:
path:"/classify" 添加动态路由参数 path:"/classify/:store_id_list/:class2_id/:class3_id"
③Classify.vue中取值:
this.$route.params
④还可以用路由解耦接收值:
先在当前路由表中 props:true 再在 Classify.vue 中 props:["store_id_list","class2_id","class3_id"] 取值。
### tab切换动画-vant
①下载:npm i vant
②pages/Classify/index.vue中引入tab组件:
import Vue from "vue"; import { Tab, Tabs } from "vant"; Vue.use(Tab); Vue.use(Tabs);
③pages/Classify/index.vue中使用 切换动画 组件:
<van-tabs v-model="active" animated class="classify_header-container" @click="handleToggle"> <van-tab v-for="(item,index) in brotherClass" :title="item.name" :key="index"> <ClassifyList :productGroup="productGroup"></ClassifyList> </van-tab> </van-tabs>
点击切换时再次请求数据:
handleToggle(index,name){ let id=""; for(let i=0;i<this.brotherClass.length;i++){ if(this.brotherClass[i].name==name){ id=this.brotherClass[i].id; } } this.dataList.class3_id=id; this.getClassifyList(this.dataList); }
注意:
1、v-model="active"控制刚进入时高亮
2、click事件在van-tabs标签上使用,它的参数是一个对象{index:"",name:""},没有id参数,在使用时自己做处理,而antd中就会将所有数据返回前端,用起来方便点。