2017-02-24 17 views
1

我正在使用Vue.js來放置一個簡單的CRUD應用程序。我有一個演示(遵循教程)工作,但對於我的生活,我不明白如何通過點擊它們來對錶格列進行排序。我找到了一個如何做的代碼示例,但我不明白如何將其集成。我將非常感謝任何幫助如何做到這一點。如何添加此代碼以使我的表格列在點擊時排序?

演示至今:https://codepen.io/figaro/pen/XMWOyj

<div class="container"> 
    <header class="page-header"> 
    <div class="branding"> 
     <img src="https://vuejs.org/images/logo.png" alt="Logo" title="Home page" class="logo"/> 
     <h1>Vue.js 2 CRUD application</h1> 
     <p>Ported from: <a href="http://codepen.io/-a/pen/amOYGp">Vue.js CRUD application</a></p> 
    </div> 
    </header> 
    <main id="app"> 
    <router-view></router-view> 
    </main> 
</div> 

<template id="product-list"> 
    <div> 
    <div class="actions"> 
     <router-link class="btn btn-default" v-bind:to="{path: '/add-product'}"> 
     <span class="glyphicon glyphicon-plus"></span> 
     Add product 
     </router-link> 
    </div> 
    <div class="filters row"> 
     <div class="form-group col-sm-3"> 
     <label for="search-element">Product name</label> 
     <input v-model="searchKey" class="form-control" id="search-element" requred/> 
     </div> 
    </div> 
    <table class="table"> 
     <thead> 
     <tr> 
     <th>Name</th> 
     <th>Description</th> 
     <th>Price</th> 
     <th class="col-sm-2">Actions</th> 
     </tr> 
     </thead> 
     <tbody> 
     <tr v-for="product in filteredProducts"> 
     <td> 
      <router-link v-bind:to="{name: 'product', params: {product_id: product.id}}">{{ product.name }}</router-link> 
     </td> 
     <td>{{ product.description }}</td> 
     <td> 
      {{ product.price }} 
      <span class="glyphicon glyphicon-euro" aria-hidden="true"></span> 
     </td> 
     <td> 
      <router-link class="btn btn-warning btn-xs" v-bind:to="{name: 'product-edit', params: {product_id: product.id}}">Edit</router-link> 
      <router-link class="btn btn-danger btn-xs" v-bind:to="{name: 'product-delete', params: {product_id: product.id}}">Delete</router-link> 
     </td> 
     </tr> 
     </tbody> 
    </table> 
    </div> 
</template> 

<template id="add-product"> 
    <div> 
    <h2>Add new product</h2> 
    <form v-on:submit="createProduct"> 
     <div class="form-group"> 
     <label for="add-name">Name</label> 
     <input class="form-control" id="add-name" v-model="product.name" required/> 
     </div> 
     <div class="form-group"> 
     <label for="add-description">Description</label> 
     <textarea class="form-control" id="add-description" rows="10" v-model="product.description"></textarea> 
     </div> 
     <div class="form-group"> 
     <label for="add-price">Price, <span class="glyphicon glyphicon-euro"></span></label> 
     <input type="number" class="form-control" id="add-price" v-model="product.price"/> 
     </div> 
     <button type="submit" class="btn btn-primary">Create</button> 
     <router-link class="btn btn-default" v-bind:to="'/'">Cancel</router-link> 
    </form> 
    </div> 
</template> 

<template id="product"> 
    <div> 
    <h2>{{ product.name }}</h2> 
    <b>Description: </b> 
    <div>{{ product.description }}</div> 
    <b>Price:</b> 
    <div>{{ product.price }}<span class="glyphicon glyphicon-euro"></span></div> 
    <br/> 
    <span class="glyphicon glyphicon-arrow-left" aria-hidden="true"></span> 
    <router-link v-bind:to="'/'">Back to product list</router-link> 
    </div> 
</template> 

<template id="product-edit"> 
    <div> 
    <h2>Edit product</h2> 
    <form v-on:submit="updateProduct"> 
     <div class="form-group"> 
     <label for="edit-name">Name</label> 
     <input class="form-control" id="edit-name" v-model="product.name" required/> 
     </div> 
     <div class="form-group"> 
     <label for="edit-description">Description</label> 
     <textarea class="form-control" id="edit-description" rows="3" v-model="product.description"></textarea> 
     </div> 
     <div class="form-group"> 
     <label for="edit-price">Price, <span class="glyphicon glyphicon-euro"></span></label> 
     <input type="number" class="form-control" id="edit-price" v-model="product.price"/> 
     </div> 
     <button type="submit" class="btn btn-primary">Save</button> 
     <router-link class="btn btn-default" v-bind:to="'/'">Cancel</router-link> 
    </form> 
    </div> 
</template> 

<template id="product-delete"> 
    <div> 
    <h2>Delete product {{ product.name }}</h2> 
    <form v-on:submit="deleteProduct"> 
     <p>The action cannot be undone.</p> 
     <button type="submit" class="btn btn-danger">Delete</button> 
     <router-link class="btn btn-default" v-bind:to="'/'">Cancel</router-link> 
    </form> 
    </div> 
</template> 
<script> 

var products = [ 
    {id: 1, name: 'Angular', description: 'Superheroic JavaScript MVW Framework.', price: 100}, 
    {id: 2, name: 'Ember', description: 'A framework for creating ambitious web applications.', price: 100}, 
    {id: 3, name: 'React', description: 'A JavaScript Library for building user interfaces.', price: 100}, 
]; 

function findProduct (productId) { 
    return products[findProductKey(productId)]; 
}; 

function findProductKey (productId) { 
    for (var key = 0; key < products.length; key++) { 
    if (products[key].id == productId) { 
     return key; 
    } 
    } 
}; 



var List = Vue.extend({ 
    template: '#product-list', 
    data: function() { 
    return {products: products, searchKey: ''}; 
    }, 
    computed: { 
    filteredProducts: function() { 
     return this.products.filter(function (product) { 
     return this.searchKey=='' || product.name.indexOf(this.searchKey) !== -1; 
     },this); 
    } 
    } 
}); 

var Product = Vue.extend({ 
    template: '#product', 
    data: function() { 
    return {product: findProduct(this.$route.params.product_id)}; 
    } 
}); 

var ProductEdit = Vue.extend({ 
    template: '#product-edit', 
    data: function() { 
    return {product: findProduct(this.$route.params.product_id)}; 
    }, 
    methods: { 
    updateProduct: function() { 
     var product = this.product; 
     products[findProductKey(product.id)] = { 
     id: product.id, 
     name: product.name, 
     description: product.description, 
     price: product.price 
     }; 
     router.push('/'); 
    } 
    } 
}); 

var ProductDelete = Vue.extend({ 
    template: '#product-delete', 
    data: function() { 
    return {product: findProduct(this.$route.params.product_id)}; 
    }, 
    methods: { 
    deleteProduct: function() { 
     products.splice(findProductKey(this.$route.params.product_id), 1); 
     router.push('/'); 
    } 
    } 
}); 

var AddProduct = Vue.extend({ 
    template: '#add-product', 
    data: function() { 
    return {product: {name: '', description: '', price: ''}} 
    }, 
    methods: { 
    createProduct: function() { 
     var product = this.product; 
     products.push({ 
     id: Math.random().toString().split('.')[1], 
     name: product.name, 
     description: product.description, 
     price: product.price 
     }); 
     router.push('/'); 
    } 
    } 
}); 

var router = new VueRouter({routes:[ 
    { path: '/', component: List}, 
    { path: '/product/:product_id', component: Product, name: 'product'}, 
    { path: '/add-product', component: AddProduct}, 
    { path: '/product/:product_id/edit', component: ProductEdit, name: 'product-edit'}, 
    { path: '/product/:product_id/delete', component: ProductDelete, name: 'product-delete'} 
]}); 
app = new Vue({ 
    router:router 
}).$mount('#app')</script> 

工作代碼示例:

 <div class="container"> 
     <header class="page-header"> 
     <div class="branding"> 
      <img src="https://vuejs.org/images/logo.png" alt="Logo" title="Home page" class="logo"/> 
      <h1>Vue.js 2 CRUD application</h1> 
      <p>Ported from: <a href="http://codepen.io/-a/pen/amOYGp">Vue.js CRUD application</a></p> 
     </div> 
     </header> 
     <main id="app"> 
     <router-view></router-view> 
     </main> 
    </div> 

    <template id="product-list"> 
     <div> 
     <div class="actions"> 
      <router-link class="btn btn-default" v-bind:to="{path: '/add-product'}"> 
      <span class="glyphicon glyphicon-plus"></span> 
      Add product 
      </router-link> 
     </div> 
     <div class="filters row"> 
      <div class="form-group col-sm-3"> 
      <label for="search-element">Product name</label> 
      <input v-model="searchKey" class="form-control" id="search-element" requred/> 
      </div> 
     </div> 
     <table class="table"> 
      <thead> 
      <tr> 
      <th>Name</th> 
      <th>Description</th> 
      <th>Price</th> 
      <th class="col-sm-2">Actions</th> 
      </tr> 
      </thead> 
      <tbody> 
      <tr v-for="product in filteredProducts"> 
      <td> 
       <router-link v-bind:to="{name: 'product', params: {product_id: product.id}}">{{ product.name }}</router-link> 
      </td> 
      <td>{{ product.description }}</td> 
      <td> 
       {{ product.price }} 
       <span class="glyphicon glyphicon-euro" aria-hidden="true"></span> 
      </td> 
      <td> 
       <router-link class="btn btn-warning btn-xs" v-bind:to="{name: 'product-edit', params: {product_id: product.id}}">Edit</router-link> 
       <router-link class="btn btn-danger btn-xs" v-bind:to="{name: 'product-delete', params: {product_id: product.id}}">Delete</router-link> 
      </td> 
      </tr> 
      </tbody> 
     </table> 
     </div> 
    </template> 

    <template id="add-product"> 
     <div> 
     <h2>Add new product</h2> 
     <form v-on:submit="createProduct"> 
      <div class="form-group"> 
      <label for="add-name">Name</label> 
      <input class="form-control" id="add-name" v-model="product.name" required/> 
      </div> 
      <div class="form-group"> 
      <label for="add-description">Description</label> 
      <textarea class="form-control" id="add-description" rows="10" v-model="product.description"></textarea> 
      </div> 
      <div class="form-group"> 
      <label for="add-price">Price, <span class="glyphicon glyphicon-euro"></span></label> 
      <input type="number" class="form-control" id="add-price" v-model="product.price"/> 
      </div> 
      <button type="submit" class="btn btn-primary">Create</button> 
      <router-link class="btn btn-default" v-bind:to="'/'">Cancel</router-link> 
     </form> 
     </div> 
    </template> 

    <template id="product"> 
     <div> 
     <h2>{{ product.name }}</h2> 
     <b>Description: </b> 
     <div>{{ product.description }}</div> 
     <b>Price:</b> 
     <div>{{ product.price }}<span class="glyphicon glyphicon-euro"></span></div> 
     <br/> 
     <span class="glyphicon glyphicon-arrow-left" aria-hidden="true"></span> 
     <router-link v-bind:to="'/'">Back to product list</router-link> 
     </div> 
    </template> 

    <template id="product-edit"> 
     <div> 
     <h2>Edit product</h2> 
     <form v-on:submit="updateProduct"> 
      <div class="form-group"> 
      <label for="edit-name">Name</label> 
      <input class="form-control" id="edit-name" v-model="product.name" required/> 
      </div> 
      <div class="form-group"> 
      <label for="edit-description">Description</label> 
      <textarea class="form-control" id="edit-description" rows="3" v-model="product.description"></textarea> 
      </div> 
      <div class="form-group"> 
      <label for="edit-price">Price, <span class="glyphicon glyphicon-euro"></span></label> 
      <input type="number" class="form-control" id="edit-price" v-model="product.price"/> 
      </div> 
      <button type="submit" class="btn btn-primary">Save</button> 
      <router-link class="btn btn-default" v-bind:to="'/'">Cancel</router-link> 
     </form> 
     </div> 
    </template> 

    <template id="product-delete"> 
     <div> 
     <h2>Delete product {{ product.name }}</h2> 
     <form v-on:submit="deleteProduct"> 
      <p>The action cannot be undone.</p> 
      <button type="submit" class="btn btn-danger">Delete</button> 
      <router-link class="btn btn-default" v-bind:to="'/'">Cancel</router-link> 
     </form> 
     </div> 
    </template> 
    <script>var vm = new Vue({ 
    el: '#demo', 
    data: { 
    sections: [ 
     { 
      id: 1, 
      city: 'Dallas', 
      state: 'TX', 
      zip: 75201, 
      price: 162500 
     }, { 
      id: 2, 
      city: 'Bevery Hills', 
      state: 'CA', 
      zip: 90210, 
      price: 319250 
     }, { 
      id: 3, 
      city: 'New York', 
      state: 'NY', 
      zip: 00010, 
      price: 962500 
     } 
     ], 
    columns: { 
     city : { 
     displayname : "City", 
     sortorder : 1 
     }, 
     zip : { 
     displayname : "Zip", 
     sortorder : 1 
     }, 
     price : { 
     displayname : "Price ($)", 
     sortorder : 1 
     } 
    }, 
    query: '', 
    sortkey: 'city', 
    sortOrders: { 
     city: 1, 
     zip: 1, 
     price: -1 
     } 
    }, 
    computed: { 
    tableFilter: function() { 
     return this.orderBy(this.findBy(this.sections, this.query, 'city'),this.sortOrders[this.sortkey], this.sortkey) 
    } 
    }, 
    methods: { 
    findBy: function (list, value, column) { 
     return list.filter(function (item) { 
     return item[column].includes(value) 
     }) 
    }, 
    orderBy: function (list, order, column) { 
     return list.sort(function (a, b) { 
     return order * (a[column] - b[column]) 
     }) 
    }, 
    sort: function (colKey) { 
     this.sortkey = colKey 
     this.sortOrders[colKey] = this.sortOrders[colKey] * -1 
    } 
    } 
})<script> 

回答

2

你需要一個v-on:click屬性添加到您的<th>

<th v-on:click="sortByColumn('name')">Name</th> 

然後添加一個方法爲該列設置一個變量並更新您的c使用它的財產:

data: function() { 
    return { products: products, searchKey: '', sortBy: '' }; 
}, 
computed: { 
    filteredProducts: function() { 
    return this.products.filter((product) => { 
     ... 
    }).sort((a, b) => { return (a[this.sortBy] < b[this.sortBy]) ? -1 : 1; }); 
    } 
}, 
methods: { 
    sortByColumn: function(columnName) { 
    this.sortBy = columnName; 
    } 
} 

我在這裏更新了您的代碼示例,並且還在切換升序和降序之間添加了代碼。 https://codepen.io/anon/pen/vxYMLE

相關問題