質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.33%

  • JavaScript

    17542questions

    JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

  • Vue.js

    842questions

    Vue.jsは、Webアプリケーションのインターフェースを構築するためのオープンソースJavaScriptフレームワークです。

  • Lodash

    14questions

    Lodashは、JavaScriptのユーティリティライブラリ。Underscoreの派生ライブラリで、配列・オブジェクトの操作に便利です。また、コードの可読性も高めることができます。

Vueでチェックボックスによる絞り込み表示

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 515

gununu

score 268

現在、JavaScriptとVueの勉強中で、チェックボックスによる絞り込み表示をしたいと考えております。

チェックボックスの tag1 を一つだけチェックした場合は tag1 に該当するもの、tag1 と tag2 のように複数チェックした場合は、tag1 または tag2 に該当するものだけを表示したいです。

チェックボックスを1つだけ選択したときは問題なく絞り込み表示されますが、複数選択すると表示されません(><)

matchedの絞り込みするメソッドの記述に問題があるのでしょうか?

items.tags と checkedNames の配列同士の項目が部分一致するか確かめる方法がわからないため、toString()で文字列にして lodashライブラリ の _.includes を使って判定するようにしました。

複数選択しても絞り込み表示される方法を教えてくださいm(__)m

<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>test</title>
</head>
<style>
body {
    font-size: 14px;
}
.list {
    max-width: 800px;
    margin: 0;
    padding: 0;
    display: flex;
    flex-wrap: wrap;
}
.list_item {
    width: 33.333%;
    margin: 0;
    padding: 15px;
    box-sizing: border-box;
    border-right: 1px solid #ccc;
    border-bottom: 1px solid #ccc;
    list-style: none;
}
.list_item:nth-child(1),
.list_item:nth-child(2),
.list_item:nth-child(3) {
    border-top: 1px solid #ccc;
}
.list_item:nth-child(3n-2) {
    border-left: 1px solid #ccc;
}

</style>
<body>

<div id="app">

    <select name="" v-model="selected">
        <option value="新着順">新着順</option>
        <option value="人気順">人気順</option>
    </select>

    <p>選択中:{{ selected }}</p>

    <br>

    <label><input type="checkbox" name="tag" value="all" v-model="checkedNames"> all</label><br>
    <label><input type="checkbox" name="tag" value="tag1" v-model="checkedNames"> tag1</label><br>
    <label><input type="checkbox" name="tag" value="tag2" v-model="checkedNames"> tag2</label><br>
    <label><input type="checkbox" name="tag" value="tag3" v-model="checkedNames"> tag3</label><br>
    <label><input type="checkbox" name="tag" value="tag4" v-model="checkedNames"> tag4</label><br>

    <p>選択中:{{ checkedNames }}</p>

    <ul class="list">
        <li v-for="item in sorted" class="list_item">
            <h3><a :href="item.link">{{ item.title }}</a></h3>
            <p>{{ item.date }}</p>
            <p>{{ item.text }}</p>
            <ul v-for="tag in item.tags">
                <li>{{ tag }}</li>
            </ul>
            <p>表示数 {{ item.view }}</p>
        </li>
    </ul>

</div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.10/lodash.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
<script>
new Vue({
    el: '#app',
    data: {
        items: [
            {
                title: 'タイトル:あああああああああ', 
                text: '本文:ああああああああああああああああああああああ',
                tags: ['tag2', 'tag3'],
                link: 'http://example.com',
                date: '2018-06-20 00:00:00',
                view: 32
            },
            {
                title: 'タイトル:いいいいいいいいいい', 
                text: '本文:いいいいいいいいいいいいいいいいいいいいい',
                tags: ['tag1', 'tag2', 'tag3', 'tag4'],
                link: 'http://example.com',
                date: '2018-06-19 00:00:00',
                view: 89
            },
            {
                title: 'タイトル:ううううううううう', 
                text: '本文:うううううううううううううううううううううううう',
                tags: ['tag1', 'tag2'],
                link: 'http://example.com',
                date: '2018-06-21 00:00:00',
                view: 12
            },
            {
                title: 'タイトル:えええええええ', 
                text: '本文:ええええええええええええええええええええ',
                tags: ['tag2', 'tag4'],
                link: 'http://example.com',
                date: '2018-06-02 00:00:00',
                view: 9
            },
            {
                title: 'タイトル:おおおおおお', 
                text: '本文:おおおおおおおおおおおおおおおおおおおおおおおおおおお',
                tags: ['tag4'],
                link: 'http://example.com',
                date: '2018-06-12 00:00:00',
                view: 4
            },
        ],
        selected: '新着順',
        checkedNames: ['all']
    },
    computed: {

        matched: function() {

            return this.items.filter(function(el) {

                var result = '';

                if( _.includes(this.checkedNames, 'all') ) {

                    return true;

                } else if( _.includes(el.tags, this.checkedNames.toString())) {

                    result = true;

                } else {

                    result = false;

                }
                return result;

            }, this)

        },
        sorted: function() {

            if( this.selected === '新着順' ) {

                return _.orderBy( this.matched, 'date', 'desc' )

            } else if( this.selected === '人気順' ) {

                return _.orderBy( this.matched, 'view', 'desc' )

            } else {
                return this.matched;
            }
        }
    }
});
</script>

</body>
</html>
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

+1

matchedの部分を以下に変えてみてください

matched: function() {
    return this.items.filter(el => {
        if(_.includes(this.checkedNames, 'all')) return true;
        else if(_.intersection(this.checkedNames, el.tags).length > 0) return true;
        else return false;
    })
},


みそは_.intersection()、つまり、積集合をつかっているところですね。
[1, 2, 3]と[2, 4, 6]の積集合は[2]っていうやつです。
積集合の配列が0より大きければ、何かがマッチしたと考えられますよね。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/06/22 18:49 編集

    おおお!表示されました!!!
    intersectionで配列の積集合を取得した結果、配列があれば部分一致してるという手法なんですね!神!
    勉強になりました。ありがとうございますm(__)m

    キャンセル

同じタグがついた質問を見る

  • JavaScript

    17542questions

    JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

  • Vue.js

    842questions

    Vue.jsは、Webアプリケーションのインターフェースを構築するためのオープンソースJavaScriptフレームワークです。

  • Lodash

    14questions

    Lodashは、JavaScriptのユーティリティライブラリ。Underscoreの派生ライブラリで、配列・オブジェクトの操作に便利です。また、コードの可読性も高めることができます。