可以参考https://wow.techbrood.com/sta...
这个网址
第一次进去浏览器url变为....29170.html#!/
然后第一次添加或者编辑或者删除任意一条后,url变为.....29170.html?#!/
并且表单并未有任何变化,为什么?
url变成有?#!之后在进行任意修改操作后又能正常修改并显示修改后内容了,这又是为什么?
源码如下:
<div class="container">
<header class="page-header">
<div class="branding">

<h1>Vue.js CRUD application</h1>
</div>
</header>
<main id="app">
<router-view></router-view>
</main>
</div>
<template id="product-list">
<div class="actions">
<a class="btn btn-default" v-link="{path: '/add-product'}">
<span class="glyphicon glyphicon-plus"></span> Add product
</a>
</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 products | filterBy searchKey in 'name'">
<td>
<a v-link="{name: 'product', params: {product_id: product.id}}">{{ product.name }}</a>
</td>
<td>{{ product.description }}</td>
<td>
{{ product.price }}
<span class="glyphicon glyphicon-euro" aria-hidden="true"></span>
</td>
<td>
<a class="btn btn-warning btn-xs" v-link="{name: 'product-edit', params: {product_id: product.id}}">Edit</a>
<a class="btn btn-danger btn-xs" v-link="{name: 'product-delete', params: {product_id: product.id}}">Delete</a>
</td>
</tr>
</tbody>
</table>
</template>
<template id="add-product">
<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>
<a v-link="'/'" class="btn btn-default">Cancel</a>
</form>
</template>
<template id="product">
<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>
<a v-link="'/'">Backt to product list</a>
</template>
<template id="product-edit">
<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>
<a v-link="'/'" class="btn btn-default">Cancel</a>
</form>
</template>
<template id="product-delete">
<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>
<a v-link="'/'" class="btn btn-default">Cancel</a>
</form>
</template>
<script src='https://cdnjs.cloudflare.com/ajax/libs/vue/1.0.26/vue.min.js'></script>
<script src='https://cdnjs.cloudflare.com/ajax/libs/vue-router/0.7.13/vue-router.min.js'></script><script src="http://wow.techbrood.com/libs/prefixfree.min.js"></script><script src="http://wow.techbrood.com/libs/modernizr.js"></script><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: ''
};
}
});
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.$get('product');
products[findProductKey(product.id)] = {
id: product.id,
name: product.name,
description: product.description,
price: product.price
};
router.go('/');
}
}
});
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.go('/');
}
}
});
var AddProduct = Vue.extend({
template: '#add-product',
data: function() {
return {
product: {
name: '',
description: '',
price: ''
}
}
},
methods: {
createProduct: function() {
var product = this.$get('product');
products.push({
id: Math.random().toString().split('.')[1],
name: product.name,
description: product.description,
price: product.price
});
router.go('/');
}
}
});
var router = new VueRouter();
router.map({
'/': {
component: List
},
'/product/:product_id': {
component: Product,
name: 'product'
},
'/add-product': {
component: AddProduct
},
'/product/:product_id/edit': {
component: ProductEdit,
name: 'product-edit'
},
'/product/:product_id/delete': {
component: ProductDelete,
name: 'product-delete'
}
})
.start(Vue.extend({}), '#app');</script><div class="container">
<header class="page-header">
<div class="branding">
<img src="[https://vuejs.org/images/logo.png](https://vuejs.org/images/logo.png)" alt="Logo" title="Home page" class="logo" />
<h1>Vue.js CRUD application</h1>
</div>
</header>
<main id="app">
<router-view></router-view>
</main>
</div>
<template id="product-list">
<div class="actions">
<a class="btn btn-default" v-link="{path: '/add-product'}">
<span class="glyphicon glyphicon-plus"></span> Add product
</a>
</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 products | filterBy searchKey in 'name'">
<td>
<a v-link="{name: 'product', params: {product_id: product.id}}">{{ product.name }}</a>
</td>
<td>{{ product.description }}</td>
<td>
{{ product.price }}
<span class="glyphicon glyphicon-euro" aria-hidden="true"></span>
</td>
<td>
<a class="btn btn-warning btn-xs" v-link="{name: 'product-edit', params: {product_id: product.id}}">Edit</a>
<a class="btn btn-danger btn-xs" v-link="{name: 'product-delete', params: {product_id: product.id}}">Delete</a>
</td>
</tr>
</tbody>
</table>
</template>
<template id="add-product">
<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>
<a v-link="'/'" class="btn btn-default">Cancel</a>
</form>
</template>
<template id="product">
<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>
<a v-link="'/'">Backt to product list</a>
</template>
<template id="product-edit">
<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>
<a v-link="'/'" class="btn btn-default">Cancel</a>
</form>
</template>
<template id="product-delete">
<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>
<a v-link="'/'" class="btn btn-default">Cancel</a>
</form>
</template>
<script src='[https://cdnjs.cloudflare.com/ajax/libs/vue/1.0.26/vue.min.js](https://cdnjs.cloudflare.com/ajax/libs/vue/1.0.26/vue.min.js)'></script>
<script src='[https://cdnjs.cloudflare.com/ajax/libs/vue-router/0.7.13/vue-router.min.js](https://cdnjs.cloudflare.com/ajax/libs/vue-router/0.7.13/vue-router.min.js)'></script><script src="[http://wow.techbrood.com/libs/prefixfree.min.js](http://wow.techbrood.com/libs/prefixfree.min.js)"></script><script src="[http://wow.techbrood.com/libs/modernizr.js](http://wow.techbrood.com/libs/modernizr.js)"></script><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: ''
};
}
});
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.$get('product');
products[findProductKey(product.id)] = {
id: product.id,
name: product.name,
description: product.description,
price: product.price
};
router.go('/');
}
}
});
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.go('/');
}
}
});
var AddProduct = Vue.extend({
template: '#add-product',
data: function() {
return {
product: {
name: '',
description: '',
price: ''
}
}
},
methods: {
createProduct: function() {
var product = this.$get('product');
products.push({
id: Math.random().toString().split('.')[1],
name: product.name,
description: product.description,
price: product.price
});
router.go('/');
}
}
});
var router = new VueRouter();
router.map({
'/': {
component: List
},
'/product/:product_id': {
component: Product,
name: 'product'
},
'/add-product': {
component: AddProduct
},
'/product/:product_id/edit': {
component: ProductEdit,
name: 'product-edit'
},
'/product/:product_id/delete': {
component: ProductDelete,
name: 'product-delete'
}
})
.start(Vue.extend({}), '#app');</script>
不要用表单原生的提交,onClick之后拦截一下原生表单提交事件,不然会刷新页面,数据就丢了