vue-day15----渲染时因异步易报错的点、分类页面数据渲染、CategoryContainer.vue进入Classify.vue-动态路由、tab切换动画-vant

### 渲染时因异步易报错的点

    深层次的找到某个值:
        <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中就会将所有数据返回前端,用起来方便点。












posted @ 2020-03-09 22:46  吴小明-  阅读(635)  评论(0编辑  收藏  举报