実現したいこと
- クリックされたらスタイルが動的に変わるようなcheckboxを実装したい
実装イメージ
追記事項
- @jsdtue55 さんより、cssでより簡単に実装可能というご指摘をいただきましたのでコメント欄もぜひご覧いただければと思います!
サンプルコード
sample.vue
<template>
<ul class="c-searchCondition c-searchCondition--gender"
<li>
<!-- v-modelでチェック状況を判定します -->
<input id="female"
type='checkbox'
v-model='femaleChecked'
value='woman'
name='filter'
/>
<!-- v-bind:classでチェックがされている状態であれば「checked」クラスを付与 -->
<label for='female' :class='{ checked: femaleChecked }'>女性</label>
</li>
<!-- 上記同様に記述 -->
<li>
<input id="male"
type='checkbox'
v-model='maleChecked'
value='man'
name='filter'
/>
<label for='male' :class='{ checked: maleChecked }'>男性</label>
</li>
</ul>
</template>
<script lang="ts">
import { Component, Vue } from 'nuxt-property-decorator'
@Component
export default class SectionSearchConditions extends Vue {
// 最初はどちらも選択された状態で表示したいため、初期値はtrueにしてます!
maleChecked: boolean = true
femaleChecked: boolean = true
}
</script>
一応スタイルも載せておきます!
sample.scss
// チェックボックスは不要のため非表示
input {
display: none;
}
.c-searchCondition {
// ulの中身を横並び,上下中央寄せ,幅を調整
display: flex;
align-items: center;
gap: 5px;
li {
label {
// 男性女性のボタンのスタイルを定義
border-radius: 50px;
padding: 1px 12px 3px 12px;
display: flex;
justify-content: center;
align-items: center;
height: 24px;
font-size: 13px;
background-color: #fff;
color: #d7d7d7;
border solid 1px #d7d7d7;
}
// チェックされたら色が変化するようにスタイルを定義
label.checked {
background-color: #0094DA;
color: #fff;
border: solid 1px #0094DA;
}
// 下記は装飾目的なので定義は任意です!
&:before {
content: "";
display: block;
width: 20px;
height: 14px;
background-position: center center;
background-repeat: no-repeat;
background-size: contain;
}
&--gender:before {
background-image: url('~/assets/images/icon_filter.svg');
}
}
}
バージョン情報も載せておきます!
package.json
{
"name": "app-name",
"version": "1.0.0",
"private": true,
"scripts": {
"dev": "nuxt",
"build": "nuxt build",
"start": "nuxt start",
"generate": "nuxt generate",
"generate:development": "cross-env NODE_ENV=development nuxt generate",
"generate:staging": "cross-env NODE_ENV=staging nuxt generate",
"generate:production": "cross-env NODE_ENV=production nuxt generate",
"lint:js": "eslint --ext \".js,.ts,.vue\" --ignore-path .gitignore .",
"lint:prettier": "prettier --check .",
"lint": "yarn lint:js && yarn lint:prettier",
"lintfix": "prettier --write --list-different . && yarn lint:js --fix"
},
"dependencies": {
"core-js": "^3.25.3",
"cross-env": "^7.0.3",
"js-cookie": "^3.0.5",
"nuxt": "^2.15.8",
"nuxt-property-decorator": "^2.9.1",
"pug": "^3.0.2",
"pug-plain-loader": "^1.1.0",
"vue": "^2.7.10",
"vue-server-renderer": "^2.7.10",
"vue-template-compiler": "^2.7.10",
"webpack": "^4.46.0"
},
"devDependencies": {
"@babel/eslint-parser": "^7.19.1",
"@nuxt/types": "^2.15.8",
"@nuxt/typescript-build": "^2.1.0",
"@nuxtjs/eslint-config-typescript": "^11.0.0",
"@nuxtjs/eslint-module": "^3.1.0",
"@nuxtjs/style-resources": "^1.2.1",
"@prettier/plugin-pug": "1.15.2",
"@types/js-cookie": "^3.0.4",
"eslint": "^8.24.0",
"eslint-config-prettier": "^8.5.0",
"eslint-plugin-nuxt": "^4.0.0",
"eslint-plugin-vue": "^9.5.1",
"prettier": "2.7.1",
"stylus": "^0.54.8",
"stylus-loader": "^4.3.3"
}
}