Tab Learning

Posted by MrJW on Tue, 08 Oct 2019 11:35:24 +0200

Implementing tab comment switching

(1)
The data structure of ratings in data.json is as follows:


Explain:
Tab there are three states all / recommended / Tucao.
Distinguished by the value of selectType
selectType=2 - "All" is the selected state
selectType=0 - "Recommendation" is the selected state
selectType=1--- "Tucao" is the selected state.
Mark the selected state with class="active"
Marking Text Information with "desc"
ratingselect.vue component template section
<template>

<div class="ratingselect">
    <div class="rating-type border-1px">
        <!--whole s-->
        <span class="block positive" @click="select(2,$event)" 
            :class="{'active':selectType===2}">
            {{desc.all}}
            <span class="count">
                {{ratings.length}}
            </span>
        </span>
        <!--whole e-->
        <!--Recommend s-->
        <span class="block positive" @click="select(0,$event)"
            :class="{'active':selectType===0}">
            <span class="count">{{positives.length}}</span>
            {{desc.positive}}
        </span>
        <!--Recommend e-->
        <!--Recommend s-->
        <span class="block negative" @click="select(1,$event)"
            :class="{'active':selectType==1}">
            {{desc.negative}}
            <span class="count">{{nagatives.length}}</span>
        </span>
        <!--Recommend e-->
    </div>
    <!--Text content/Switching of non-text content-->
    <div class="switch" @click="toggleContent($event)" :class="{'on':onlyContent}">
        <i class="iconfont icon-gou"></i>
        <span class="text">Content-only evaluation</span>
    </div>
</div>

</template>
SCRIPT:
<script>
// Define variables in three states:
// Recommendation status
const POSITIVE=0;
/ / Tucao state
const NEGATIVE = 1;
const ALL=0;
export default{

props:{
    ratings:{
        type:Array,
        default(){
            return [];
        }
    },
    selectType:{
        type:Number,
        default:ALL
    },
    onlyContent:{
        type:Boolean,
        default:false
    },
    desc:{
        type:Object,
        default(){
            return {
                all:'whole',
                positive:'Satisfied',
                negative:'Make complaints'
            };
        }
    }
},
computed:{
    positives(){
        //Filter rateType==== POSITIVE and return it to the recommendation (to show the number of evaluations of this type)
        return this.ratings.filter((rating)=>{
            return rating.rateType===POSITIVE;
        });
    },
    nagatives(){
        return this.ratings.filter((rating)=>{
            return rating.rateType===NEGATIVE
        });
    }

},
methods:{
    //Click on the selected tab to trigger the increment event of the parent component
    //The parameters passed in are the tab type (0, 1, 2), and the click event.
    select(type,event){
        this.$emit('increment','selectType',type);
    },
    //Switching between Text Content and Non-Text Content
    toggleContent(event){
        if(!event._constructed){
          return;
        }
        this.onlyContent=!this.onlyContent;
        this.$emit('increment','onlyContent',this.onlyContent);
    },
    //List display (needShow(rating.rateType,rating.text) triggered by parent component)
    needShow(type,text){
        if(this.onlyContent&&!text){
            return false;
        }
        if(this.selectType===ALL){
            return true;
        }
        else{
            return type===this.selectType
        }
    
    }

}}</script>

(2) the parent component part food.vue
It is divided into two parts: tab switching (introducing the previous components) and list display.
The template section:
<div class="rating">

<h1 class="title">Commodity evaluation</h1>
<!--Listener subcomponent sent increment,Triggering parent component incrementTotal-->
<ratingselect @increment="incrementTotal" 
  :select-type="selectType"
  :only-content="onlyContent" :desc="desc" :ratings="food.ratings">
</ratingselect>
<!--List part-->
<div class="rating-wrapper">
    <ul v-show="food.ratings&&food.ratings.length">
        <!--Subcomponent needShow Determine whether it is displayed or not-->
        <li v-show="needShow(rating.rateType,rating.text)" class="rating-item border-1px" v-for="rating in food.ratings">
            <div class="user">
                <span class="name">{{rating.username}}</span>
                <img width="12" height="12" :src="rating.avatar" class="avatar">
            </div>
            <div class="time">
                {{rating.rateTime |formateDate}}
            </div>
            <!--rating.rateType=0/rating.rateType=1(Recommend/Display in Tucao)-->
            <p class="text">
                <i class="iconfont"
                :class="{'icon-damuzhi':rating.rateType==0,
                'icon-down':rating.rateType===1}"></i>
                {{rating.text}}
            </p>
        </li>
    </ul>
</div></div>

Part SCRIPT
// Default Show Full Evaluation
const ALL=2;
export default{

props:{
    food:{
        type:Object
    }
},
data(){
    return{
        showFlag:false,
        selectType:ALL,
        onlyContent:true,
        desc:{
            all:'whole',
            positive:'Recommend',
            negative:'Make complaints'
        }
    };
}
methods:{
    //The show method is triggered by the parent component's Click
    show(){
        this.showFlag=true;
        //By default, all tabs are selected; all comments are displayed
        this.selectType=ALL;
        //Text-only prompts are also selected
        this.onlyContent=true;
        this.$nextTick(()=>{
            if(!this.scroll){
                this.scroll=new BScroll(this.$el,{
                    click:true
                });
            }
            else{
                this.scroll.refresh();
        
            }
        
        })
        
    
    },
    incrementTotal(type,data){
        //type:selectType
        //data: The exact value of the item's selectType when clicked
        this[type]=data;
        this.$nextTick(()=>{
            this.scroll.refresh();
        });
    },
    needShow(type,text){
       //radio, which only looks at content, is selected, but has no content
        if(this.onlyContent&&!text){
            return false;
        }
        //The selected state of the tab is "ALL" and the list is displayed.
        if(this.selectType===ALL){
            return true;
        }
        else{
            return type === this.selectType;
        }
    }

}

}

Topics: Javascript JSON Vue