如何用组件和v-bind:class过滤Vue中的帖子



我正试图以我从这里得到的这支笔为基础做一个例子:https://codepen.io/conradolandia/pen/YzyPmrv

但是我想使用vue路由器,我已经尝试过了:(笔:https://codepen.io/conradolandia/pen/vYNERPW)

HTML:

<main class="wrap">
<div id="app">
<router-view></router-view>
</div>
</main>
<template id="post-list-template">
<div class="container">
<div class="row">
<h4>Filter by album:</h4>
<div class="filters">
<button class="btn" v-bind:class="{ active: currentFilter === 'ALL' }" v-on:click="setFilter('ALL')">all</button>
<button class="btn" v-bind:class="{ active: currentFilter === 'art' }" v-on:click="setFilter('art')">art</button>
<button class="btn" v-bind:class="{ active: currentFilter === 'doodles' }" v-on:click="setFilter('doodles')">doodles</button>
<button class="btn" v-bind:class="{ active: currentFilter === 'workshops' }" v-on:click="setFilter('workshops')">workshops</button>
</div>
</div>
<div class="columns is-multiline">
<div class="column is-3" v-if="currentFilter === post.category || currentFilter === 'ALL'" v-bind:key="post.title" v-for="post in posts">
<div class="card post">
<img class="card-img-top" v-bind:src="post.image">
<div class="card-body">
<div class="card-title">{{ post.title }}</div>
<small class="tags">{{ post.category }}</small>
</div>
</div> <!-- .post -->
</div> <!-- .col-md-4 -->
</div> <!-- .row -->
</div> <!-- .container -->
</template>

CSS:

body{
background-color: #ccc;
box-sizing:border-box;
-webkit-box-sizing:border-box;
-moz-box-sizing:border-box;
}
.post {
margin-bottom: 20px;
}
.post img{ width: 100%;}
.tags {background-color: #ccc; padding: 3px 5px;}
.filters {
margin-bottom: 20px;
}

JS:

var postList = Vue.extend({
template: "#post-list-template",
data: function(){
return {
currentFilter:'ALL',
posts: [
{title: "Artwork", image: "https://picsum.photos/g/200?image=122", category: 'art'},
{title: "Charcoal", image: "https://picsum.photos/g/200?image=116", category: 'art'},
{title: "Sketching", image: "https://picsum.photos/g/200?image=121", category: 'doodles'},
{title: "Acrillic", image: "https://picsum.photos/g/200?image=133", category: 'workshops'},
{title: "Pencil", image: "https://picsum.photos/g/200?image=134", category: 'doodles'},
{title: "Pen", image: "https://picsum.photos/g/200?image=115", category: 'art'},
{title: "Inking", image: "https://picsum.photos/g/200", category: 'workshops'},
{title: "Artwork", image: "https://picsum.photos/g/200?image=121", category: 'art'},
{title: "Charcoal", image: "https://picsum.photos/g/200?image=115", category: 'art'},
{title: "Sketching", image: "https://picsum.photos/g/200?image=124", category: 'doodles'},
{title: "Acrillic", image: "https://picsum.photos/g/200?image=13", category: 'workshops'},
{title: "Pencil", image: "https://picsum.photos/g/200?image=14", category: 'doodles'},
]
}
},
methods: {
setFilter: function(filter) {
this.currentFilter = filter;
}
},
})
// Start a new instance of router (instead of router.map)
var router = new VueRouter({
routes: [
{ path: '/', component: postList }
]
})
// Start a new instance of the Application required (instead of router.start)
new Vue({
el: '#app',
router: router,
})

到目前为止,没有运气。过滤器类型的工作,我第一次点击就会激活一个过滤选项,但随后所有过滤器都停止工作,firefox会抱怨"TypeError:"e is undefined"。

有人能给我指正确的方向吗?我不明白为什么第一个代码笔链接有效,而第二个却无效。

澄清:当我点击任何过滤器时,过滤器都会起作用,但如果我点击"全部"过滤器,一切都会停止工作。

尝试使用计算函数

computed:{
filteredPosts:function(){
if(this.currentFilter==='ALL'){
return this.posts;
}
return this.posts.filter(post=>{
return post.category === this.currentFilter;
})
}
}

循环时可以使用filteredPosts而不是posts

<div class="columns is-multiline">
<div class="column is-3" :key="post.title" v-for="post in filteredPosts">
<div class="card post">
<img class="card-img-top" :src="post.image">
<div class="card-body">
<div class="card-title">{{ post.title }}</div>
<small class="tags">{{ post.category }}</small>
</div>
</div> <!-- .post -->
</div> <!-- .col-md-4 -->
</div> <!-- .row -->

循环时不需要使用任何条件,因为computed函数可以完成这项工作。

最新更新