<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="https://codesandbox.io/public/sse-hooks/sse-hooks.e56ff94f429f544c6c7aed41e9b064f1.js"></script>
<script type="text/javascript" src="https://codesandbox.io/static/js/banner.bab7510b3.js"></script>
<title>Grid Component</title>
<script src="https://unpkg.com/vue"></script>
<link rel="stylesheet" type="text/css" href="/style.css" />
<!-- component template -->
<script type="text/x-template" id="grid-template">
<table>
<thead>
<tr>
<th v-for="key in columns"
@click="sortBy(key)"
:class="{ active: sortKey == key }">
{{ key | capitalize }}
<span class="arrow" :class="sortOrders[key] > 0 ? 'asc' : 'dsc'">
</span>
</th>
</tr>
</thead>
<tbody>
<tr v-for="entry in filteredHeroes">
<td v-for="key in columns">
{{entry[key]}}
</td>
</tr>
</tbody>
</table>
</script>
</head>
<body>
<!-- demo root element -->
<div id="demo">
<form id="search">
Search <input name="query" v-model="searchQuery" />
</form>
<demo-grid
:heroes="gridData"
:columns="gridColumns"
:filter-key="searchQuery"
>
</demo-grid>
</div>
<script>
// register the grid component
Vue.component("demo-grid", {
template: "#grid-template",
props: {
heroes: Array,
columns: Array,
filterKey: String
},
data: function() {
var sortOrders = {};
this.columns.forEach(function(key) {
sortOrders[key] = 1;
});
return {
sortKey: "",
sortOrders: sortOrders
};
},
computed: {
filteredHeroes: function() {
var sortKey = this.sortKey;
var filterKey = this.filterKey && this.filterKey.toLowerCase();
var order = this.sortOrders[sortKey] || 1;
var heroes = this.heroes;
if (filterKey) {
heroes = heroes.filter(function(row) {
return Object.keys(row).some(function(key) {
return (
String(row[key])
.toLowerCase()
.indexOf(filterKey) > -1
);
});
});
}
if (sortKey) {
heroes = heroes.slice().sort(function(a, b) {
a = a[sortKey];
b = b[sortKey];
return (a === b ? 0 : a > b ? 1 : -1) * order;
});
}
return heroes;
}
},
filters: {
capitalize: function(str) {
return str.charAt(0).toUpperCase() + str.slice(1);
}
},
methods: {
sortBy: function(key) {
this.sortKey = key;
this.sortOrders[key] = this.sortOrders[key] * -1;
}
}
});
// bootstrap the demo
var demo = new Vue({
el: "#demo",
data: {
searchQuery: "",
gridColumns: ["name", "power"],
gridData: [
{ name: "Chuck Norris", power: Infinity },
{ name: "Bruce Lee", power: 9000 },
{ name: "Jackie Chan", power: 7000 },
{ name: "Jet Li", power: 8000 }
]
}
});
</script>
<script crossorigin type="text/javascript" src="https://codesandbox.io/static/js/watermark-button.76f1e5b66.js"></script>
</body>
</html>
https://cn.vuejs.org/v2/examples/grid-component.html
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="https://codesandbox.io/public/sse-hooks/sse-hooks.e56ff94f429f544c6c7aed41e9b064f1.js"></script>
<script type="text/javascript" src="https://codesandbox.io/static/js/banner.bab7510b3.js"></script>
<title>Tree View</title>
<script src="https://unpkg.com/vue"></script>
<link rel="stylesheet" type="text/css" href="/style.css" />
<!-- item template -->
<script type="text/x-template" id="item-template">
<li>
<div
:class="{bold: isFolder}"
@click="toggle"
@dblclick="makeFolder">
{{ item.name }}
<span v-if="isFolder">[{{ isOpen ? '-' : '+' }}]</span>
</div>
<ul v-show="isOpen" v-if="isFolder">
<tree-item
class="item"
v-for="(child, index) in item.children"
:key="index"
:item="child"
@make-folder="$emit('make-folder', $event)"
@add-item="$emit('add-item', $event)"
></tree-item>
<li class="add" @click="$emit('add-item', item)">+</li>
</ul>
</li>
</script>
</head>
<body>
<p>(You can double click on an item to turn it into a folder.)</p>
<!-- the demo root element -->
<ul id="demo">
<tree-item
class="item"
:item="treeData"
@make-folder="makeFolder"
@add-item="addItem"
></tree-item>
</ul>
<script>
// demo data
var treeData = {
name: "My Tree",
children: [
{ name: "hello" },
{ name: "wat" },
{
name: "child folder",
children: [
{
name: "child folder",
children: [{ name: "hello" }, { name: "wat" }]
},
{ name: "hello" },
{ name: "wat" },
{
name: "child folder",
children: [{ name: "hello" }, { name: "wat" }]
}
]
}
]
};
// define the tree-item component
Vue.component("tree-item", {
template: "#item-template",
props: {
item: Object
},
data: function() {
return {
isOpen: false
};
},
computed: {
isFolder: function() {
return this.item.children && this.item.children.length;
}
},
methods: {
toggle: function() {
if (this.isFolder) {
this.isOpen = !this.isOpen;
}
},
makeFolder: function() {
if (!this.isFolder) {
this.$emit("make-folder", this.item);
this.isOpen = true;
}
}
}
});
// boot up the demo
var demo = new Vue({
el: "#demo",
data: {
treeData: treeData
},
methods: {
makeFolder: function(item) {
Vue.set(item, "children", []);
this.addItem(item);
},
addItem: function(item) {
item.children.push({
name: "new stuff"
});
}
}
});
</script>
<script crossorigin type="text/javascript" src="https://codesandbox.io/static/js/watermark-button.76f1e5b66.js"></script>
</body>
</html>