表單選項互斥問題(vue)

最近有一個需求:
表單中有3個多選框,而他們的選項是一樣的,但是如果其中一個選項被選擇之後,在另外2個多選框裏面就不能再選了。
這樣的問題,讓我想到了“將乒乓球放入不同盒子”的例子。

上代碼

// index.html

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <meta http-equiv="X-UA-Compatible" content="ie=edge" />
        <title>Document</title>

        <link rel="stylesheet" href="./styles.css" />
        <script src="https://cdn.bootcss.com/vue/2.6.5/vue.min.js"></script>
    </head>
    <body>
        <div id="app">
            <p>乒乓球放入不同的盒子(選項互斥)</p>
            <div class="ping-pong-list">
                <span
                    v-for="ball in ballList"
                    :key="ball.id"
                    :class="ball.className"
                    @click="onBallClick(ball.id)"
                    v-text="ball.id"
                ></span>
            </div>

            <div class="box-wrapper">
                <div
                    v-for="(category,index) in categories"
                    :key="index"
                    :class="['box', category, currCategory === category ? 'active' : null]"
                    @click="onBoxClick(category)"
                >
                    <span
                        v-for="ball in ballList"
                        :key="ball.id"
                        :class="ball.className"
                        v-show="ball.category === category"
                        v-text="ball.id"
                    ></span>
                </div>
            </div>
        </div>

        <script src="./main.js"></script>
    </body>
</html>
// main.js

const balls = Array(12)
    .fill(undefined)
    .map((v, i) => ({ id: i < 9 ? `0${i + 1}` : i + 1, category: null }))

const vm = new window.Vue({
    el: "#app",

    data: () => ({
        msg: "hahahhaha",
        balls,
        categories: ["red", "green", "blue"],
        currCategory: "red"
    }),

    computed: {
        ballList() {
            return this.balls.map(v => {
                let className = ["ping-pong-ball"]
                if (v.category) {
                    className.push(v.category)
                    if (v.category !== this.currCategory) {
                        className.push("disable")
                    }
                }
                return { ...v, className }
            })
        }
    },

    methods: {
        onBoxClick(category) {
            if (category !== this.currCategory) {
                this.currCategory = category
            }
        },

        onBallClick(id) {
            const ball = this.balls.find(v => v.id === id)
            if (ball) {
                ball.category = ball.category ? null : this.currCategory
            }
        }
    }
})
// styles.css

#app {
    user-select: none;
}

.ping-pong-list {
    display: flex;
    margin: 20px;
    justify-content: center;
    flex-wrap: wrap;
}

.ping-pong-ball {
    width: 50px;
    height: 50px;
    margin: 5px;
    border-radius: 50%;
    box-shadow: 0 0 10px 0 #aaa;
    text-align: center;
    line-height: 50px;
}

.ping-pong-list .ping-pong-ball {
    cursor: pointer;
}

.box-wrapper {
    display: flex;
    justify-content: space-around;
    margin-top: 30px;
}

.box {
    display: flex;
    align-content: flex-start;
    flex-wrap: wrap-reverse;
    width: 300px;
    height: 200px;
    border: 10px solid;
    border-top-width: 0;
    cursor: pointer;
    transition: all 0.25s;
}

.box.red {
    border-color: rgb(238, 97, 97);
}

.box.green {
    border-color: rgb(97, 238, 156);
}

.box.blue {
    border-color: rgb(97, 146, 238);
}

.box.active {
    box-shadow: 0 10px 20px 0 #aaa;
}

.ping-pong-ball.red,
.box.red .ping-pong-ball {
    background-color: rgb(238, 97, 97);
}

.ping-pong-ball.green,
.box.green .ping-pong-ball {
    background-color: rgb(97, 238, 156);
}

.ping-pong-ball.blue,
.box.blue .ping-pong-ball {
    background-color: rgb(97, 146, 238);
}

.ping-pong-ball.disable {
    opacity: 0.25;
    pointer-events: none;
}

每個ball對象都有一個category屬性,用來表示它屬於哪個盒子。然後在渲染的時候,根據category來計算使用的類名。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章