此代码段按原样运行。但是我实现此功能的方法与vuejs.org上的演示中使用的方法略有不同。我真正需要知道的是哪种方法最适合从原始数据中实现过滤的用户列表。我的filter()方法是好主意还是更好是计算或观看。
如果snipet不起作用:Mockaroo(有时)有ssl证书问题。因此,您必须首先在浏览器新标签页中打开数据网址(https://api.mockaroo.com/api/b5f38710?count=20&key=cdbbbcd0),确认安全例外,删除已下载的json a然后再次运行此代码段。
var dataurl ='https://api.mockaroo.com/api/b5f38710?count=20&key=cdbbbcd0'
new Vue({
el: '#datagrid',
data: {
columns: {
id: 'ID',
nick: 'Nick name',
first: 'First name',
last: 'Last name'
},
users: [],
query: '',
prevKey: 'id',
orderDesc: false
},
computed: {
filteredUsers () {
return _.filter(this.users, user =>
_.find(user, prop =>
new RegExp(this.query, 'i').test(prop)
)
)
}
},
methods: {
async loadUsers () {
var result = await axios.get(dataurl)
this.users = result.data
this.query = ''
this.prevKey = 'id'
this.orderDesc = false
},
clearQuery () {
this.query = ''
},
sortUsers (e) {
var key = e.target.dataset.key
if (this.prevKey === key) {
this.users.reverse()
this.orderDesc = !this.orderDesc
} else {
this.users = _.sortBy(this.users, key)
this.orderDesc = false
this.prevKey = key
}
},
updateQuery: _.debounce(function (e) {
this.query = e.target.value
}, 300)
}
})

#datagrid {
width: 98%;
margin: 10px auto;
padding: 2px;
background-color: white;
border: 2px solid #3F51B5;
overflow: hidden;
}
.table {
display: table;
width: 100%;
font-size: 14px;
font-family: Arial, sans-serif;
color: #263238;
}
.thead {
display: table-header-group;
}
.tbody {
display: table-row-group;
}
.tr {
display: table-row;
}
.td {
display: table-cell;
position: relative;
}
.thead .td {
padding: 5px 14px;
background-color: #3F51B5;
color: white;
font-weight: bold;
text-align: center;
cursor: pointer;
}
.tbody .td {
padding: 4px;
color: #263238;
text-align: center;
}
.tr .td:not(:last-child) {
border-right: 2px solid white;
}
.tbody .tr:hover .td {
background-color: #C5CAE9;
}
.tbody .tr:hover .td:not(:last-child) {
border-right: 2px solid #C5CAE9;
}
.tools {
margin: 10px;
box-sizing: border-box;
}
.tools:after {
content: "";
display: block;
clear: both;
}
.source {
display: block;
float: left;
}
.search {
float: right;
}
.arrow {
display: inline-block;
position: absolute;
width: 0;
height: 0;
margin-left: 5px;
margin-top: 5px;
border-left: 6px solid transparent;
border-right: 6px solid transparent;
transition: all .6s;
}
.asc {
border-bottom: 6px solid white;
}
.desc {
border-top: 6px solid white;
}
.users-move {
transition: transform .6s;
}
.users-enter-active, .users-leave-active {
transition: all .6s;
}
.users-enter, .users-leave-to {
opacity: 0;
transform: translateY(30px);
}

<script src="https://unpkg.com/underscore@1.8.3/underscore-min.js"></script>
<script src="https://unpkg.com/vue@2.4.3/dist/vue.min.js"></script>
<script src="https://unpkg.com/axios@0.16.2/dist/axios.min.js"></script>
<div id="datagrid">
<div class="tools">
<button class="source" @click="loadUsers">
Load some fake data from mockaroo.com
</button>
<div class="search">
<input type="text" @input="updateQuery" :value="query">
<button class="clear" @click="clearQuery">clear</button>
</div>
</div>
<div class="table">
<div class="thead" @click="sortUsers">
<div class="tr">
<span v-for="(col, key) in columns" class="td" :data-key=key>
{{ col }}
<span
v-if="prevKey === key"
:class="['arrow', orderDesc ? 'desc' : 'asc']">
</span>
</span>
</div>
</div>
<transition-group name="users" tag="div" class="tbody">
<div class="tr" v-for="row in filteredUsers" :key="row.id">
<span class="td" v-for="column in row">{{ column }}</span>
</div>
</transition-group>
</div>
</div>
&#13;