vue多選/單選效果

轉(zhuǎn):https://blog.csdn.net/Number7421/article/details/81002729

不過我以前都寫過這三種方法了,很pang額,怕之后忘記了,偷個懶拿別人的,以免以后忘記了

一、單選:

思路:當(dāng)點(diǎn)擊的索引值 == v-for循環(huán)的索引值時,給你那個li添加選中樣式

html:

<ul class="box">
    <li v-for="c,index of cities" :class="{checked:index==n}" @click="changeList(index)">{{c}}</li>
</ul>

CSS樣式如下:

<style type="text/css">
body{margin:0;}
ul{
    padding:0; list-style:none; 
    margin:150px 150px;
}
li{
    width:80px; height:50px; 
    display:inline-block;
    border-radius:8px; border:1px #000 solid;
    text-align:center; line-height:50px;
    cursor:pointer; 
    transition:all 0.3s linear;
    margin-left:5px;
}
li:hover{
    background-color:#0CF; color:#fff; 
    border:1px #fff solid;
}    
li.checked{
    background-color:#0CF; color:#fff; 
    border:1px #fff solid;
}
</style>

js:

var app = new Vue({
    el : ".box",
    data : {
        cities : ["上海","北京","廣州","重慶","西安"],
        n : 0
    },
    methods :{
        changeList(index){
            this.n = index;//this指向app
        }
    }
})
image.png

二、多選

方法一和方法二的主要的區(qū)別在于數(shù)據(jù)中有沒已有標(biāo)注是選中狀態(tài)還是未選中狀態(tài)

CSS樣式如下:

<style type="text/css">
body{margin:0;}
.box{ margin:150px 150px;}
ul{
    padding:0; 
    list-style:none;
}
li{
    width:50px; height:30px; display:inline-block;
    text-align:center; line-height:30px;
    cursor:pointer;margin-left:5px;
}
li:before{ 
    display:inline-block; width:10px; height:10px; 
    line-height:10px; content:""; border:1px #000 solid; 
    margin-right:2px; transition:all 0.3s linear;
}    
li.checked:before{ 
    background-color:#0CF; 
    border:1px #fff solid;
}
li.checked{color:#0CF;}
</style>

方法一:

思路:新增一個新的空數(shù)組arr(arr的里元素的索引值表示,表示該索引值對應(yīng)的li已經(jīng)處于被選中狀態(tài)),如果arr數(shù)組沒有點(diǎn)擊的索引值,就添加到arr數(shù)組里,如果有就把這個索引,就把這個索引從數(shù)組中刪除。

html:

<ul class="box">
<li v-for="c,index of cities" :class="{checked:arr.includes(index)}" @click="checkedBox(index)">{{c}}</li>
</ul>

js:

var app = new Vue({
    el : ".box",
    data : {
        cities : ["上海","北京","廣州","重慶","西安"],
        arr : []
    },
    methods :{
        checkedBox(i){
            if(this.arr.includes(i)){
                //includes()方法判斷是否包含某一元素,返回true或false表示是否包含元素,對NaN一樣有效
                //filter()方法用于把Array的某些元素過濾掉,filter()把傳入的函數(shù)依次作用于每個元素,然后根據(jù)返回值是true還是false決定保留還是丟棄該元素:生成新的數(shù)組
                this.arr=this.arr.filter(function (ele){return ele != i;});
            }else{
                this.arr.push(i);
            }
        }
    }
})

方法二:

思路:這個就更加通俗易懂了,把點(diǎn)擊的那個是否選中的標(biāo)志取反就可以了

html:

<ul class="box">
    <li v-for="c,index of cities"
    :class="{checked:c.bOn}"
    @click="checkbox(index)">{{c.city}}</li>
</ul>

js:

var app = new Vue({
    el : ".box",
    data : {
        cities : [{city:"北京",bOn:false},
        {city:"上海",bOn:false},
        {city:"重慶",bOn:false},
        {city:"廣州",bOn:false},
        {city:"西安",bOn:false}]
    },
    methods : {
        checkbox(i){
            this.cities[i].bOn = !this.cities[i].bOn;
        }
    }
})
image.png

項目實戰(zhàn)代碼

<template>
    <div>
        <van-search
            v-model="value"
            shape="round"
            show-action
            placeholder="編號/品種/規(guī)格/產(chǎn)地"
            @search="onSearch"
        >
            <template #action>
                <div @click="onSearch" class="onSearchBtn">搜索</div>
            </template>
        </van-search>
        <div class="tips">
            已選 ({{ton}}噸/{{num}}件)
        </div>
        <div class="resultBox">
            <ul>
                <van-list
                v-model="loading"
                :finished="finished"
                finished-text="沒有更多了"
                @load="getStockLists"
                >
                    <li v-for="(item,index) in list">
                        <div class="resultBoxTit">
                            <div>
                                <span class="resultBoxNum">{{item.good_sn}}</span>
                                <span class="resultBoxPosition">{{item.stock_seat}}</span>
                            </div>
                            <div @click="son(item,index)">
                                <div v-if="arr.some(({id})=>id==item.id)" class="resultBoxRemove">取消添加</div>
                                <div v-else class="resultBoxAdd">+添加</div>
                            </div>
                        </div>
                        <div class="resultBoxContent">
                            <div class="resultBoxProduct">
                                <div class="van-ellipsis ellipsisOne">
                                    {{item.cat_name}}
                                </div>
                                <div class="van-ellipsis ellipsisTwo">
                                    {{item.spec_name}}
                                </div>
                                <div class="van-ellipsis ellipsisThree">
                                    {{item.brand_name}}
                                </div>
                                <div class="van-ellipsis ellipsisFour">
                                    {{item.type_name}}
                                </div>
                            </div>
                            <div class="resultBoxProduct">
                                <div>
                                    <span>抄碼/過磅:{{item.show_weight}}噸/{{item.weigh_weight}}噸</span>
                                </div>
                                <div>
                                    {{item.number | parseIntData}}捆
                                </div>
                            </div>
                        </div>
                    </li>
                </van-list>
            </ul>
        </div>
        <div class="footerBtn">
            <div class="footerBtnTop" @click="hideOutBox">
                完成
            </div>
        </div>
    </div>
</template>

<script>
import { Toast } from 'vant';
    export default {
        props: ["newArr"],
        data() {
            return {
                value: '',
                list:[],
                loading: false,
                finished: false,
                page:1,
                arr:[], //多選保存的數(shù)組
            };
        },
        watch: {
            //監(jiān)聽父組件的刪除列表變化,重新賦值
            newArr(newVal,oldVal){
                this.arr = newVal
            }
        },
        computed: {
            num: function () {
                var sum = 0
                for (let index = 0; index < this.arr.length; index++) {
                    sum += parseInt(this.arr[index].number)*1
                }
                return sum
            },
            ton: function () {
                var sum = 0
                for (let index = 0; index < this.arr.length; index++) {
                    // sum += parseFloat(this.arr[index].show_weight)*1
                    sum += (parseFloat(this.arr[index].show_weight)*10)/10;
                }
                return sum.toFixed(3)
            }
        },
        filters: {
            parseIntData: function (value) {
                return parseInt(value)
            }
        },
        mounted() {
            this.getStockLists();
        },
        methods: {
            son(item,i){
                if(this.arr.some(({id})=>id==item.id)){
                    this.arr= this.arr.filter(function (ele){
                        return ele.id != item.id
                    });
                }else{
                    this.arr.push(item);
                }
            },
            hideOutBox(){
                this.$emit('arr',this.arr)
                this.$emit('hideOutBox',false)
            },
            onSearch(val) {
                this.page = 1
                // this.arr = []
                this.list = []
                this.getStockLists();
            },
            //獲取添加貨物數(shù)據(jù)數(shù)組
            getStockLists(){
                this.value = this.value.trim() //去掉搜索框的空格
                this.http.get(this.api.stocks_getStockLists,{
                    keyword :this.value,
                    page :this.page,
                    limit :''
                })
                .then(res => {
                    if(this.value != ''){
                        this.finished = false;
                        if(res.data.lists == ''){
                            this.list =res.data.lists
                            this.finished = true;
                        }else{
                            var newLists = [].concat(this.list,res.data.lists)
                            this.list = newLists
                            this.page = this.page+1
                            // 加載狀態(tài)結(jié)束
                            this.loading = false;
                            if (Math.ceil(this.list.length/20) >= res.data.total) {
                                this.finished = true;
                            }
                        } 
                    }else{
                        var newLists = [].concat(this.list,res.data.lists)
                        this.list = newLists
                        this.page = this.page+1
                        // 加載狀態(tài)結(jié)束
                        this.loading = false;
                        if (Math.ceil(this.list.length/20) >= res.data.total) {
                            this.finished = true;
                        }
                    }
                });
            }
        }
    }
</script>

<style scoped>
.onSearchBtn{
    color: #007ce6;
    font-size: 16Px;
}
.tips{
    text-align: center;
    height: 60px;
    line-height: 60px;
}
/* 列表 */
.resultBox{

}
.resultBox li{
    background: #fff;
    padding: 15Px;
    font-size: 14Px;
    margin-bottom: 20px;
}
.resultBoxTit{
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 30px;
}
.resultBoxNum{
    font-size: 16Px;
    margin-right: 50px;
}
.resultBoxPosition{
    color: #666666;
}
.resultBoxAdd{
    background: #007ce6;
    border-radius: 4Px;
    color: #fff;
    padding: 6Px 16Px;
}
.resultBoxContent{
    background: #f4faff;
    padding: 0 15Px;
}
.resultBoxProduct{
    display: flex;
    justify-content: space-between;
    padding: 15Px 0;
}
.resultBoxProduct:first-child{
    border-bottom: 1Px solid #eff2f4;
}
.ellipsisOne{
    width: 130px;
}
.ellipsisTwo{
    width: 300px;
}
.ellipsisThree{
    width: 80px;
}
.resultBoxRemove{
    background: red;
    border-radius: 4Px;
    color: #fff;
    padding: 6Px 16Px;
}
/* 列表結(jié)束 */
.footerBtn{
    position: fixed;
    bottom: 0;
    left: 0;
    background: #fff;
    width: 100%;
    border-top: 1Px solid #e2e2e2;
    height: 126px;
    display: flex;
    padding: 10Px 15Px;
    box-sizing: border-box;
    justify-content: space-between;
}
.footerBtnTop{
    background: #007ce6;
    border-radius: 4Px;
    width: 100%;
    font-size: 16Px;
    display: flex;
    align-items: center;
    justify-content: center;
    color: #fff;
}
</style>

image.png

image.png

在搜索頁面點(diǎn)擊拿到數(shù)據(jù),點(diǎn)完成,要把數(shù)據(jù)帶到上一個頁面。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 前端開發(fā)面試題 面試題目: 根據(jù)你的等級和職位的變化,入門級到專家級,廣度和深度都會有所增加。 題目類型: 理論知...
    怡寶丶閱讀 2,683評論 0 7
  • 概要 64學(xué)時 3.5學(xué)分 章節(jié)安排 電子商務(wù)網(wǎng)站概況 HTML5+CSS3 JavaScript Node 電子...
    阿啊阿吖丁閱讀 9,849評論 0 3
  • 前端開發(fā)知識點(diǎn) HTML&CSS對Web標(biāo)準(zhǔn)的理解、瀏覽器內(nèi)核差異、兼容性、hack、CSS基本功:布局、盒子模型...
    Hebborn_hb閱讀 896評論 0 1
  • 一:認(rèn)識jquery jquery是javascript的類庫,具有輕量級,完善的文檔,豐富的插件支持,完善的Aj...
    xuguibin閱讀 1,764評論 1 7
  • 一、JS前言 (1)認(rèn)識JS 也許你已經(jīng)了解HTML標(biāo)記(也稱為結(jié)構(gòu)),知道了CSS樣式(也稱為表示),會使用HT...
    凜0_0閱讀 2,922評論 0 8

友情鏈接更多精彩內(nèi)容