Vue3 implements multiple selection of addresses

origin

Vue3 implements a multi-choice selection box for an area
. The user needs to choose the service area. Originally, I wanted to find a selection box cascaded in provinces, cities and counties. One, specially recorded, by the way to help the latecomers

achieve effect

Effect demonstration

Implementation ideas

  1. Use a div to place the added area, set the display to none, and set the display of the div to block when clicking Add to realize the hiding and display of the added area
  2. When the value of the drop-down box changes, change the variable of the selected index (provinceIndex) to realize the change of the city content displayed in the citybox
  3. When the city content is clicked, the select/unselect method is triggered. In fact, it is the same method. By judging the class of the currently clicked element (if the class contains is-selected, it is already selected) to distinguish whether it is selected or unselected
  4. In the selection method, add the selected object to a list (citys) that stores the selected content, and add the is-selected class to the class of the clicked element. If it is unselected, it will perform a filter in the citys list and cancel content to remove
  5. The clearing method is to clear the citys list and set the class with the is-selected class to normal

Implementation code

  • template part
    <template>
    <div class="form-item">
        <label for="city" class="form-label">服务区域</label>
        
        <span>
            <span style="background-color: rgb(245,247,249);margin-right: 5px;" v-for="item in citys" :key="item">{
         
         {
                item.name }}</span>
            <span @click="ClickAddCity" style="color: #0bbfbc;">点击添加</span>
        </span>
    
        <!-- 显示/隐藏部分 -->
        <div ref="citysDom" class="citysbox">
            <div class="citysbox-top">
           
                <div class="top-left">
                    <label for="city" class="form-label1">省份:</label>
                    <select required id="city" name="city" class="form-input form-input-select"
                        style="width: auto;color: #303030;" v-model="provinceIndex">
                        <option v-for="(item, index) in Provinces" :key="index" :value="index">
                        {
         
         { item.name}}
                        </option>
                    </select>
                </div>
                
                <div class="top-right">
                    <button type="button" class="btn-close" @click="ClickAddCity">关闭</button>
                    <button type="button" class="btn-confirm" @click="ClickReastBtn">清空</button>
                    <button type="button" class="btn-confirm" @click="ClickAddCity">确认</button>
                </div>
            </div>
            <!-- 城市内容部分 -->
            <div class="citysbox-body">
                <div v-for="item in Provinces[provinceIndex].city" :key="item.id"
                :class="citys.includes(item) ? 'box-item is-selected' : 'box-item'"
                @click="SelectChange(item, $event)">
                    {
         
         { item.name }}</div>
            </div>
            
        </div>
    </div>
    
```
  • script part

    <script setup>
    import { ref } from 'vue';
    // 省市信息
    const Provinces = [
        {
            "id": 24,
            "name": "北京市",
            "city": [
                {
                    "id": 268,
                    "name": "东城区",
                    "province": 24
                },
                {
                    "id": 269,
                    "name": "西城区",
                    "province": 24
                }
            ]
    
        },
        {
            "id": 9,
            "name": "福建省",
            "city": [
                {
                    "id": 109,
                    "name": "福州市",
                    "province": 9
                },
                {
                    "id": 110,
                    "name": "厦门市",
                    "province": 9
                },
                {
                    "id": 116,
                    "name": "龙岩市",
                    "province": 9
                }
            ]
        }
    ]
    // 添加服务区域相关
    var citysDom = ref() // dom对象
    var provinceIndex = ref(0) // 当前选择获取值
    var citys = ref([]) // 已选择城市
    
    // 点击添加时显示地址选择div
    function ClickAddCity() {
        if (citysDom.value.style.display !== 'block')
            citysDom.value.style.display = 'block';
        else citysDom.value.style.display = 'none';
    }
    
    // 选中地址
    function SelectChange(item, e) {
        
        let domClass = e.currentTarget.getAttribute("class")
        // 判断item的class区别两种情况,一种是点击未选中的item选中 , 一种是点击已选中的取消选中
        if (domClass == "box-item") {
            e.currentTarget.className = "box-item is-selected"
            // 将选中对象添加到citys列表中
            citys.value.push(item)
        } else {
            e.currentTarget.className = "box-item"
            // 将取消选中对象从citys列表中去除
            citys.value = citys.value.filter(val => val.id != item.id)
        }
        console.log('citys:', citys.value)
    }
    
    // 清空地址区域
    function ClickReastBtn() {
        citys.value = []
        let items = document.getElementsByClassName("is-selected");
        console.log('length',items.length);
        console.log('items:',items, typeof(items));
        // 清空已选择的样式
        Array.prototype.forEach.call(items, function (item) {
            item.className = "box-item" 
        });
    }
    </script>
    
  • css part

    <style scoped>
    
    .form-item {
        margin-right: 24px;
        margin-bottom: 24px;
    }
    
    .form-label {
        height: 14px;
        font-size: 14px;
        color: #39475A;
        letter-spacing: 0;
        text-align: right;
        line-height: 14px;
        font-weight: 400;
        margin-right: 12px;
    }
    .citysbox {
        width: 700px;
        max-width: 750px;
        min-width: 360px;
        padding: 10px;
        min-height: 100px;
        display: none;
        position: absolute;
        background: rgb(245, 247, 249);
        border-radius: 10px;
    }
    
    .citysbox-top{
        display: flex;
        flex-direction: row;
        justify-content: space-between;
    }
    .citysbox-body {
        display: flex;
        flex-direction: row;
        flex-wrap: wrap;
    }
    
    .box-item {
        margin: 10px 10px 0 0;
        border: rgb(197, 208, 223) solid 1px;
        border-radius: 4px;
        padding: 3px;
    }
    
    .is-selected {
        border: rgb(11, 192, 188) solid 1px;
        color: rgb(11, 192, 188);
    }
    </style>
    

Summarize

that's all

The content has been said in more detail, hereby record


If it helps you, you can give me a thumbs up, thank you

Guess you like

Origin blog.csdn.net/aifengaopeng/article/details/129772223