Vue实战之CURD

#hello world
找到Vue创建的模板项目根目录的index.html
--html

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>demo1</title>
<script src="https://cdn.bootcss.com/vue/2.4.1/vue.js"></script>
</head>
<body>
<div id="app">
{{message}}
</div>
<script>
new Vue({
el:'#app',
data:{
message:'hello world'
}
})
</script>
</body>
</html>

--启动本地服务

npm run dev

--在浏览器输入默认地址

http://localhost:8080/

--view

hello world

#ToDoList

--html

<div id="app">
<form>
<table style="300px;border-collapse:collapse" border="1">
<tr>
<th>title</th>
<th>desc</th>
</tr>
<tr v-for="todoItem in todolist">
<td>{{todoItem.title}}</td>
<td>{{todoItem.desc}}</td>
</tr>
</table>
<input type="text" v-model="title"><br>
<input type="text" v-model="desc"><br/>
<input type="button" value="add todoItem" v-on:click="addItem()"/>
</form>
</div>

--

v-model:实现双向数据绑定
v-on:事件绑定指令,click是参数,可以缩写为@click
--js

var todoItem=function(title,desc){
this.title=title;
this.desc=desc;
}
new Vue({
el:'#app',
data:{
todolist:[],
titel:'',
desc:''
},
methods:{
addItem:function(){
this.todolist.push(new todoItem(this.title,this.desc));
this.title='';
this.desc='';
}
}
})

--

data:数据绑定
methods:属性绑定,事件绑定的回调函数都代理在methods中

刷新运行,在表单中输入后,点击add按钮,向数组添加元素同时刷新了列表
要从数据驱动UI的方式来思考,接下来增加删除功能
--html

<td><input type="button" value="remove" @click="remove(index)"/></td>
--js
methods:{
remove:function(index){
this.todolist.splice(index,1);
}
}

引入bootstrap美化页面
--html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>demo1</title>
<script src="https://cdn.bootcss.com/vue/2.4.1/vue.js"></script>
<link href="https://cdn.bootcss.com/bootstrap/4.0.0-alpha.6/css/bootstrap.css" rel="stylesheet">
</head>
<body class="container">
<div id="app" class='row'>
<div class="col-md-6">
<table class="table table-bordered">
<tr>
<th>title</th>
<th>desc</th>
<th></th>
</tr>
<tr v-for="(todoItem,index) in todolist">
<td>{{todoItem.title}}</td>
<td>{{todoItem.desc}}</td>
<td><input type="button" value="remove" @click="remove(index)" class="btn btn-danger" /></td>
</tr>
</table>
</div>
<div class="col-md-6">

<div class="form-inline">
<label for="title" class="control-label col-md-4">title:</label>
<input type="text" v-model="title" class="form-control col-md-8">
</div>
<div class="form-inline">
<label for="desc" class="control-label col-md-4">desc</label>
<input type="text" v-model="desc" class="form-control col-md-8">
</div>
<div class="form-inline">
<input type="button" value="OK" v-on:click="addItem()" class="btn btn-primary offset-md-10" />
</div>
</div>
</div>
</body>

--js

<script>
var TodoItem = function (title, desc) {
this.title = title;
this.desc = desc;
}
new Vue({
el: '#app',
data: {
todolist: [],
title: '',
desc: ''
},
methods: {
addItem: function () {
this.todolist.push(new TodoItem(this.title, this.desc))

this.title = this.desc = '';

},
remove: function (index) {
this.todolist.splice(index, 1);
}

}
})
</script>

刷新运行看下效果,接下来增加编辑按钮,先增加自增ID

--html

<div class="col-md-6">
<table class="table table-bordered">
<tr>
<th></th>
<th>title</th>
<th>desc</th>
<th></th>
</tr>
<tr v-for="(todoItem,index) in todolist">
<th>{{todoItem.id}}</th>
<td>{{todoItem.title}}</td>
<td>{{todoItem.desc}}</td>
<td><input type="button" value="remove" @click="remove(index)" class="btn btn-danger" /></td>
</tr>
</table>
</div>
<div class="col-md-6">
<div class="form-inline">
<label for="title" class="control-label col-md-4">title:</label>
<input type="hidden" v-bind:value="todoItem.id" />
<input type="text" v-model="todoItem.title" class="form-control col-md-8">
</div>
<div class="form-inline">
<label for="desc" class="control-label col-md-4">desc</label>
<input type="text" v-model="todoItem.desc" class="form-control col-md-8">
</div>
<div class="form-inline">
<input type="button" value="OK" v-on:click="addItem()" class="btn btn-primary offset-md-10" />
</div>
</div>

--js

var todoItem=(function(){
var id=1;
return function(title,desc){
this.title=title;
this.desc=desc;
this.id=id++;
}
})();

data:{
todolist:[],
todoItem:{
id:'',
title:'',
desc:''
}
}

methods:{
addItem:function(){
this.todolist.push(
new todoItem(
this.todoItem.title,
this.todoItem.desc
)
);
this.dodoItem={};
}
}

刷新看效果,接下来添加编辑按钮

--html

<input type="button" value="edit" @click="edit(todoItem.id)" class="btn btn-info"/>

--js

methods:{
edit:function(id){
var obj=this.todolist.filter(v=>v.id===id)[0];
this.todoItem=obj;
}
}

刷新运行,编辑后在没有点击OK按钮,表单中的变化已经体现在列表中

原因是:this.todoItem=obj 这句代码是引用赋值,所以todoItem和obj指向的是同一个地址,对this.todoItem的修改会直接反应到obj上,修改代码
--js

var obj=this.todolist.filter(v=>v.id===id)[0];
this.todoItem={
id:obj.id,
title:obj.title,
desc:obj.desc
};

但是现在修改还是新增操作,需要修改OK按钮的事件绑定方式为save,通过id判断新增还是修改操作:

--html

<input type="button" value="OK" v-on:click="save()" class="btn btn-primary offset-md-10" />

--js

methods:{
save:function(){
if(this.todoItem.id){
//编辑
var obj=this.todolist.filter(v=>v.id===this.todoItem.id)[0];
obj.title=this.todoItem.title;
obj.desc=this.todoItem.desc;
}else{
//新增
this.todolist.push(
new totoItem(
this.todoItem.title,
this.todoItem.desc
)
);
}
//重置表单
this.todoItem={};
}
}

运行,已经完成了编辑功能

v-bind:一般用来传递属性参数,后面跟 :attr
我们试着添加disable属性,使OK按钮只有在title不为空的前提下可用
--html

<input type="button" value="OK" v-on:click="save()" class="btn btn-primary offset-md-10" :disabled='canSave'/>

--js

new Vue({
computed:{
canSave:function(){
return !this.todoItem.title||!this.todoItem.desc;
}
}
})

save: function () {
if (this.todoItem.id) {
//编辑
var obj = this.todolist.filter(v => v.id === this.todoItem.id)[0];
obj.title = this.todoItem.title;
obj.desc = this.todoItem.desc;
} else {
//新增
this.todolist.push(
new todoItem(
this.todoItem.title,
this.todoItem.desc
)
);
}
//重置表单
this.todoItem = {title:'',desc:''};
},

增加查询功能

--html

<div class="row toolbar">
<div class="col-md-8">
keyword:
<input type="text" v-model="keyword"/>
<input type="button" @click="query()" value="search" />
</div>
</div>

--js

//全局变量,用于缓存所有数据
var list=[];

data:{
todolist:[],
todoItem:{
id:'',
title:'',
desc:''
},
keyword:''
}

methods:{
remove: function (index) {
this.todolist.splice(index, 1);
list=this.todolist;
},
edit: function (id) {
var obj = this.todolist.filter(v => v.id === id)[0];
this.todoItem = {
id: obj.id,
title: obj.title,
desc: obj.desc
};
},
save: function () {
if (this.todoItem.id) {
//编辑
var obj = this.todolist.filter(v => v.id === this.todoItem.id)[0];
obj.title = this.todoItem.title;
obj.desc = this.todoItem.desc;
} else {
//新增
this.todolist.push(
new todoItem(
this.todoItem.title,
this.todoItem.desc
)
);
}
//重置表单
this.todoItem = {title:'',desc:''};
list=this.todolist;
},
query: function () {
//这里需要list全局变量过滤,而不能通过this.todolist,因为需要给this.todolist赋值,赋值后无法还原原来的列表
this.todolist = list.filter(v => v.title.indexOf(this.keyword) !== -1);
}
}

增删改查完成,完整代码

-html

<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>demo1</title>
<script src="https://cdn.bootcss.com/vue/2.4.1/vue.js"></script>
<link href="https://cdn.bootcss.com/bootstrap/4.0.0-alpha.6/css/bootstrap.css" rel="stylesheet">

</head>

<body class="container">
<div id="app">
<div class="row toolbar">
<div class="col-md-8">
keyword:
<input type="text" v-model="keyword" />
<input type="button" @click="query()" value="search" />
</div>
</div>
<div class='row'>

<div class="col-md-6">
<table class="table table-bordered">
<tr>
<th></th>
<th>title</th>
<th>desc</th>
<th></th>
</tr>
<tr v-for="(todoItem,index) in todolist">
<th>{{todoItem.id}}</th>
<td>{{todoItem.title}}</td>
<td>{{todoItem.desc}}</td>
<td>
<input type="button" value="remove" @click="remove(index)" class="btn btn-danger" />
<input type="button" value="edit" @click="edit(todoItem.id)" class="btn btn-info" />
</td>
</tr>
</table>
</div>
<div class="col-md-6">

<div class="form-inline">
<label for="title" class="control-label col-md-4">title:</label>
<input type="hidden" v-bind:value="todoItem.id" />
<input type="text" v-model="todoItem.title" class="form-control col-md-8">
</div>
<div class="form-inline">
<label for="desc" class="control-label col-md-4">desc</label>
<input type="text" v-model="todoItem.desc" class="form-control col-md-8">
</div>
<div class="form-inline">
<input type="button" value="OK" v-on:click="save()" class="btn btn-primary offset-md-10" :disabled='canSave' />
</div>
</div>


</div>
</div>
<script>
var list = [];
var TodoItem = (function () {
var id = 1;
return function (title, desc) {
this.title = title;
this.desc = desc;

this.id = id++;
}
})();
new Vue({
el: '#app',
data: {
todolist: [],
todoItem: {
id: '',
title: '',
desc: ''
},
keyword: ''
}, computed: {
canSave: function () {
return !this.todoItem.title || !this.todoItem.desc;
}
},
methods: {
query: function () {
//过滤title中不包含keyword的数据
//这里必须通过list全局变量过滤,而不能通过this.todolist,因为需要给this.todolist赋值,赋值后无法还原原来的列表。
this.todolist = list.filter(v => v.title.indexOf(this.keyword) !== -1);
},
edit: function (id) {
//找到id值等于所传参数的todoitem
var obj = this.todolist.filter(v => v.id === id)[0];
//对数据进行绑定,则数据会响应到表单上
this.todoItem = {
id: obj.id,
title: obj.title,
desc: obj.desc
};
},
save: function () {
if (this.todoItem.id) {
//编辑保存
var obj = this.todolist.filter(v => v.id === this.todoItem.id)[0];
obj.title = this.todoItem.title;
obj.desc = this.todoItem.desc;

} else {
//新增保存
this.todolist.push(
new TodoItem(
this.todoItem.title,
this.todoItem.desc
)
);
}
//重置表单
this.todoItem = { title: '', desc: '' };

list = this.todolist;
},

remove: function (index) {
this.todolist.splice(index, 1);
}

}
})
</script>
</body>

</html>

 由于是用txt记录的没有截图,但是代码都是经过验证的~

原文地址:https://www.cnblogs.com/justinxhan/p/14744939.html