略。
为了测试需要先搭建json-server伪造后台接口
先克隆https://github.com/typicode/json-server这个项目
npm install -g json-server
新建文件夹json-server
cd进去
npm init
npm install json-server --save
改一下package.json
{
"name": "jsonserver",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"json:server": "json-server --watch db.json",
"json:server:remote": "json-server http://jsonplaceholder.typicode.com/db"
},
"author": "",
"license": "ISC",
"dependencies": {
"json-server": "^0.15.1"
}
}
然后新建db.json
瞎写一些数据
{
"users": [
{
"name": "update-test",
"phone": "update-test",
"email": "update-test",
"education": "update-test",
"graduationschool": "update-test",
"profession": "update-test",
"profile": "update-test",
"id": 1
},
{
"name": "Bucky",
"phone": "333-444-555",
"email": "[email protected]",
"id": 2,
"age": 30,
"companyId": 2
},
{
"name": "mist",
"phone": "333-444-555",
"email": "[email protected]",
"id": 3,
"age": 33,
"companyId": 3
},
{
"name": "Elyse",
"phone": "333-444-555",
"email": "[email protected]",
"id": 4,
"age": 35,
"companyId": 3
},
{
"name": "123",
"phone": "123",
"email": "123",
"education": "123",
"graduationschool": "123",
"profession": "123",
"profile": "123",
"id": 5
},
{
"name": "123",
"phone": "123",
"email": "123",
"education": "214213",
"graduationschool": "213",
"profession": "213",
"profile": "test",
"id": 6
},
{
"name": "tset",
"phone": "test",
"email": "a123",
"education": "saf",
"graduationschool": "sadf",
"profession": "sadf",
"profile": "test",
"id": 7
},
{
"name": "tse",
"phone": "sdt",
"email": "asd",
"education": "adsfds",
"graduationschool": "adsf",
"profession": "sadf",
"profile": "tesdt",
"id": 8
}
],
"companies": [
{
"id": 1,
"name": "Apple",
"description": "Apple is Good!"
},
{
"id": 2,
"name": "Microsoft",
"description": "Microsoft is Good!"
},
{
"id": 3,
"name": "Huawei",
"description": "Huawei is Good!"
}
]
}
npm run json:server
启动json-server
接口:
GET 请求
//获取所有员工信息
http://localhost:3000/users
//获取id为1的用户信息
http://localhost:3000/users/1
//获取所有公司的信息
http://localhost:3000/companies/1
//获取某公司所有员工的信息
http://localhost:3000/companies/3/users
//根据公司名字获取信息
http://localhost:3000/companies?name=Microsoft
//根据多个名字获取公司信息
http://localhost:3000/companies?name=Microsoft&name=Apple
//获取一页中只有两条数据
http://localhost:3000/companies?_page=1&_limit=2
//对数据进行排序 (desc降序)
http://localhost:3000/companies?_sort=name&_order=asc
//获取年龄30及以上的
http://localhost:3000/users?age_gte=30
//获取年龄30~40之间的
http://localhost:3000/users?age_gte=30&age_lte=40
//搜索用户信息
http://localhost:3000/users?q=k
//【其他类型请求使用POSTMAN】
然后就搭建好了。
返回上级目录
npm install --global vue-cli
vue init webpack [取个项目名字(没有括号)]
cd [你取的项目名]
npm install
npm run dev
源码(目录结构见最上面的图片)
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<title>vcustomers</title>
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet">
<style>
body{
padding-top: 60px;
}
</style>
</head>
<body>
<div id="app"></div>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.min.js"></script>
</body>
</html>
main.js
// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue'
import VueRouter from 'vue-router'
import VueResource from 'vue-resource'
import App from './App'
import Customers from './components/Customers'
import About from './components/About'
import Add from './components/Add'
import CustomerDetails from './components/CustomerDetails'
import Edit from './components/Edit'
Vue.config.productionTip = false
Vue.use(VueRouter)
Vue.use(VueResource)
//设置路由
const router = new VueRouter({
mode:"history",
base:__dirname,
routes:[
{path:"/",component:Customers},
{path:"/about",component:About},
{path:"/add",component:Add},
{path:"/customer/:id",component:CustomerDetails},
{path:"/edit/:id",component:Edit}
]
})
/* eslint-disable no-new */
new Vue({
router,
template:`
<div id="app">
<nav class="navbar navbar-inverse navbar-fixed-top">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<router-link to="/" class="navbar-brand">用户管理系统</router-link>
</div>
<div id="navbar" class="collapse navbar-collapse">
<ul class="nav navbar-nav">
<li><router-link to="/">主页</router-link></li>
<li><router-link to="/about">关于我们</router-link></li>
</ul>
<ul class="nav navbar-nav navbar-right">
<li><router-link to="/add">添加用户</li>
</ul>
</div>
</div>
</nav>
<router-view></router-view>
</div>
`
}).$mount("#app")
Customers.vue
<template>
<div class="customers container">
<Alert v-if="alert" v-bind:message="alert"></Alert>
<h1 class="page-header">用户管理系统</h1>
<input type="text" class="form-control" placeholder="搜索" v-model="filterInput"/>
<table class="table table-striped">
<thead>
<tr>
<th>姓名</th>
<th>电话</th>
<th>邮箱</th>
<th></th>
</tr>
</thead>
<tbody>
<tr v-for="customer in filterBy(customers,filterInput)">
<td>{{customer.name}}</td>
<td>{{customer.phone}}</td>
<td>{{customer.email}}</td>
<td><router-link class="btn btn-default" v-bind:to="'/customer/'+customer.id">详情</router-link></td>
</tr>
</tbody>
</table>
</div>
</template>
<script>
import Alert from './Alert'
export default {
name: 'customers',
data (){
return {
customers:[],
alert:"",
filterInput:""
}
},
methods:{
fetchCustomers(){
this.$http.get("http://localhost:3000/users")
.then(function(response){
this.customers = response.body;
})
},
filterBy(customers,value){
return customers.filter(function(customer){
return customer.name.match(value);
})
}
},
created(){
if(this.$route.query.alert){
this.alert = this.$route.query.alert;
}
this.fetchCustomers();
},
updated(){
this.fetchCustomers();
},
components:{
Alert
}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
</style>
Alert.vue
<template>
<div class="alert alert-warning alert-dismissible" role="alert">
<button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">×</span></button>
{{message}}
</div>
</template>
<script>
export default {
name: 'about',
props:["message"],
data () {
return {
}
},
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
</style>
Add.vue
<template>
<div class="add container">
<Alert v-if="alert" v-bind:message="alert"></Alert>
<h1 class="page-header">添加用户</h1>
<form v-on:submit="addCustomer">
<div class="well">
<h4>用户信息</h4>
<div class="form-group">
<label>姓名</label>
<input type="text" class="form-control" placeholder="name" v-model="customer.name">
</div>
<div class="form-group">
<label>电话</label>
<input type="text" class="form-control" placeholder="phone" v-model="customer.phone">
</div>
<div class="form-group">
<label>邮箱</label>
<input type="text" class="form-control" placeholder="email" v-model="customer.email">
</div>
<div class="form-group">
<label>学历</label>
<input type="text" class="form-control" placeholder="education" v-model="customer.education">
</div>
<div class="form-group">
<label>毕业学校</label>
<input type="text" class="form-control" placeholder="graduationschool" v-model="customer.graduationschool">
</div>
<div class="form-group">
<label>职业</label>
<input type="text" class="form-control" placeholder="profession" v-model="customer.profession">
</div>
<div class="form-group">
<label>个人简介</label>
<textarea class="form-control" rows="10" placeholder="profile" v-model="customer.profile"></textarea>
</div>
<button type="submit" class="btn btn-primary">添加</button>
</div>
</form>
</div>
</template>
<script>
import Alert from './Alert'
export default {
name: 'add',
data () {
return {
customer:{},
alert:""
}
},
methods:{
addCustomer(e){
if(!this.customer.name || !this.customer.phone || !this.customer.email){
this.alert = "请填写对应信息";
}else{
let newCustomer = {
name:this.customer.name,
phone:this.customer.phone,
email:this.customer.email,
education:this.customer.education,
graduationschool:this.customer.graduationschool,
profession:this.customer.profession,
profile:this.customer.profile
}
this.$http.post("http://localhost:3000/users",newCustomer)
.then(function(response){
this.$router.push({path:'/',query:{alert:"用户信息添加成功!"}});
})
}
e.preventDefault();
}
},
components:{
Alert
}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
</style>
CustomerDetails.vue
<template>
<div class="details container">
<h1 class="page-header">
{{customer.name}}
<span class="pull-right">
<router-link class="btn btn-primary" v-bind:to="'/edit/'+customer.id">
编辑
</router-link>
<button class="btn btn-danger" v-on:click="deleteCustomer(customer.id)">
删除
</button>
<router-link to="/" class="btn btn-default">返回</router-link>
</span>
</h1>
<ul class="list-group">
<li class="list-group-item"><span class="glyphicon glyphicon-phone"> {{customer.phone}}</span></li>
<li class="list-group-item"><span class="glyphicon glyphicon-envelope"> {{customer.email}}</span></li>
</ul>
<ul class="list-group">
<li class="list-group-item"><span class="glyphicon glyphicon-education"> {{customer.education}}</span></li>
<li class="list-group-item"><span class="glyphicon glyphicon-blackboard"> {{customer.graduationschool}}</span></li>
</ul>
<ul class="list-group">
<li class="list-group-item"><span class="glyphicon glyphicon-briefcase"> {{customer.profession}}</span></li>
<li class="list-group-item"><span class="glyphicon glyphicon-user"> {{customer.profile}}</span></li>
</ul>
</div>
</template>
<script>
export default {
name: 'customerDetails',
data () {
return {
customer:""
}
},
methods:{
fetchCustomers(id){
this.$http.get("http://localhost:3000/users/"+id)
.then(function(response){
this.customer = response.body;
})
},
deleteCustomer(id){
this.$http.delete("http://localhost:3000/users/"+id)
.then(function(response){
this.$router.push({path:'/',query:{alert:"用户删除成功!"}});
})
}
},
created(){
this.fetchCustomers(this.$route.params.id)
}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
</style>
Edit.vue
<template>
<div class="edit container">
<h1 class="page-header">编辑用户</h1>
<form v-on:submit="updateCustomer">
<div class="well">
<h4>用户信息</h4>
<div class="form-group">
<label>姓名</label>
<input type="text" class="form-control" placeholder="name" v-model="customer.name">
</div>
<div class="form-group">
<label>电话</label>
<input type="text" class="form-control" placeholder="phone" v-model="customer.phone">
</div>
<div class="form-group">
<label>邮箱</label>
<input type="text" class="form-control" placeholder="email" v-model="customer.email">
</div>
<div class="form-group">
<label>学历</label>
<input type="text" class="form-control" placeholder="education" v-model="customer.education">
</div>
<div class="form-group">
<label>毕业学校</label>
<input type="text" class="form-control" placeholder="graduationschool" v-model="customer.graduationschool">
</div>
<div class="form-group">
<label>职业</label>
<input type="text" class="form-control" placeholder="profession" v-model="customer.profession">
</div>
<div class="form-group">
<label>个人简介</label>
<textarea class="form-control" rows="10" placeholder="profile" v-model="customer.profile"></textarea>
</div>
<button type="submit" class="btn btn-primary">更新</button>
<router-link v-bind:to="'/customer/'+this.$route.params.id" class="btn btn-default">返回</router-link>
</div>
</form>
</div>
</template>
<script>
export default {
name: 'add',
data () {
return {
customer:{}
}
},
methods:{
fetchCustomers(id){
this.$http.get("http://localhost:3000/users/"+id)
.then(function(response){
this.customer = response.body;
})
},
updateCustomer(e){
if(!this.customer.name || !this.customer.phone || !this.customer.email){
console.log("请添加对应的信息!");
}else{
let updateCustomer = {
name:this.customer.name,
phone:this.customer.phone,
email:this.customer.email,
education:this.customer.education,
graduationschool:this.customer.graduationschool,
profession:this.customer.profession,
profile:this.customer.profile
}
this.$http.put("http://localhost:3000/users/"+this.$route.params.id,updateCustomer)
.then(function(response){
this.$router.push({path:'/',query:{alert:"用户信息更新成功!"}});
})
}
e.preventDefault();
}
},
created(){
this.fetchCustomers(this.$route.params.id);
}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
</style>
app.vue
<template>
<div id="app">
</div>
</template>
<script>
import HelloWorld from './components/HelloWorld'
export default {
name: 'App',
components: {
HelloWorld
}
}
</script>
<style>
#app {
font-family: 'Avenir', Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style>
Reference
https://www.bilibili.com/video/av51530091?p=1