混合练习(一) 表格数据的增删
由上图页面的风格可以看出,使用bootstrap来搭建页面,这样也好,可以学着使用一下bootstrap。使用前,要先下载bootstrap:
我选择使用cnpm下载,也可以用npm,不过我怕网速不好,下载国外服务器的下载不下来,所以用国内的。因为bootstrap底层是jQuery开发的,所以要先下载jQuery框架依赖。
cnpm install --save bootstrap@3.3.7 下载指定版本的,不加班和版本号,默认下载最新版本
cnpm install --save jquery
也可以两个一起下载:cnpm install --save bootstrap@3.3.7 jquery
如果已经下载下来,但是版本不是我们想要的,可以去package.json里面修改bootstrap的版本号,然后重新 cnpm install
,把依赖重新下载下来。
分析小程序的业务逻辑:
1、先创建一些假数据,把表格遍历出来 v-for;
2、在表格的最下面,各有一行 暂无数据
(无数据) 与 删除全部
(有数据)
- 思路:判断存储表格中数据的数组arr的长度,若为0说明当前没有数据,则显示 暂无数据;否则显示 删除全部 这一行。
3、向表格中添加数据
- 思路:
(1)使用 v-model 让输入框绑定变量 (模型数据)
(2)给添加按钮绑定点击事件调用处理函数
(3)输入框中输入的数据,插入到arr中,靠双向绑定 v-model
(4)插入数据之后,输入框清空
4、判断添加按钮
是否禁用
- 思路:
(1)给按钮添加disabled属性,属性值使用 v-bind 指令绑定一个布尔值,控制disabled属性值的变化
(2)监听输入框的变化。使用vue的watch来进行监听(watch实时监控)
(3)在watch中监听两个变量的变化,除非是两个输入框里都有数据,才解除禁用
5、删除按钮的功能,单个删除
、全部删除
- 思路:
(1)设置一个变量,通过变量=不同数字来判断是单个删除,还是全部删除;(比如 @click=“number=index” 、@click=“number=-100” 表达式)
(2)给模态框的确认按钮绑定点击事件调用处理函数
(3)处理函数中,通过number的值判断是哪个操作(单个删除设置变量>= 0;全部删除设置变量<0;)
(4)如果是全部删除,则直接清空arr;如果是单个删除,则可以用arr.splice()方法删除某个index的值。
然后功能分析基本上就完成了。
<style>
#container {
padding: 10%;
}
.form-group {
margin: 10px 0;
}
table tr {
text-align: center;
}
.text_right {
text-align: right;
}
</style>
<!-- 使用练习bootstrap -->
<!-- 引入文件的script脚本数据放在下面吧,这样就不用等加载完在渲染 -->
<!-- 先引入jQuery -->
<!-- 然后引入bootstrap -->
<div class="container demoSky">
<div class="form-group">
<label for="exampleInputEmail1">Please input your name here.</label>
<input type="email" class="form-control" id="exampleInputEmail1" placeholder="Name" v-model="inputValue1">
</div>
<div class="form-group">
<label for="exampleInputEmail1">Please input your age here.</label>
<input type="email" class="form-control" id="exampleInputEmail1" placeholder="Age" v-model="inputValue2">
</div>
<button class="btn btn-default" type="submit" @click="add()" :disabled="bool">Add</button>
<button type="button" class="btn btn-primary" @click="reset()">Reset</button>
<h2>用户信息表</h2>
<table class="table table-bordered">
<tr>
<td>序号</td>
<td>名字</td>
<td>年龄</td>
<td>操作</td>
</tr>
<!-- vue 的v-for指令 遍历生成数据 -->
<tr v-for="(item,index) in arr">
<td>{{index+1}}</td>
<td>{{item.name}}</td>
<td>{{item.age}}</td>
<td><button type="button" class="btn btn-success" data-toggle="modal"
data-target="#myModal" @click="number=index">Delete</button></td>
</tr>
<!-- v-if 与 v-else 共同判断 -->
<tr v-if="arr.length<=0">
<td colspan="4">暂无数据......</td>
</tr>
<tr v-else="">
<td colspan="4" class="text_right">
<button type="button" class="btn btn-info" data-toggle="modal" data-target="#myModal" @click="number=-120">Delete
All</button>
</td>
</tr>
</table>
<!-- Modal 模态框 在需要出发的标签写上属性 data-toggle="modal" data-target="#myModal"-->
<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span
aria-hidden="true">×</span></button>
<h4 class="modal-title" id="myModalLabel">Modal title</h4>
</div>
<div class="modal-body">
确定删除吗?
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal" @click="del()">确定</button>
<button type="button" class="btn btn-primary" data-dismiss="modal">取消</button>
</div>
</div>
</div>
</div>
</div>
<script>
// vue代码
new Vue({
el: ".demoSky",//视图挂载时,确保命名唯一
data: {
arr: [
{ name: "yy1", age: 12 },
{ name: "yy2", age: 100 },
],
// arr:[],
inputValue1: "",
inputValue2: "",
bool: true,//默认按钮禁用
number: -1,//随便给个值,反正只要不被使用即可
},
methods: {
// 事件处理函数
add() {
// if(this.inputValue1 == ""||this.inputValue2 == "") return;//因为有对按钮的禁用功能,所以这儿可以不写
this.arr.push({ name: this.inputValue1, age: this.inputValue2 });
this.valueNull();
},
// sum:function(){}, //这种格式是正式全写的格式,上面那种是简写,是不是跟对象中的函数很像
reset() {
this.valueNull();
},
del() {
if(this.number<0){
console.log("全部删除");
this.arr.splice(0,this.arr.length);
// this.arr=[];
// this.arr.length=0
}else{
console.log("单个删除");
this.arr.splice(this.number,1);//删除当前arr的index的一个元素
}
},
// 处理其他业务逻辑的方法
valueNull() {
this.inputValue1 = "";
this.inputValue2 = "";
},
boolChange() {
if (this.inputValue1 && this.inputValue2) this.bool = false;//如果输入框没数据的话
else this.bool = true;
}
},
watch: {
inputValue1(newVal, oldVal) {
this.boolChange();
},
inputValue2(newVal, oldVal) {
this.boolChange();
},
}
})
</script>
<script src="./node_modules/jquery/dist/jquery.js"></script>
<script src="./node_modules/bootstrap/dist/js/bootstrap.js"></script>
通过这个例子,我发现了一个事实:vue的指令中可以直接使用模型数据的变量名。比如v-if=“arr.lenght<=0”。
watch 监听模型数据,模型数据改变时就会被触发;watch在初始化的时候不会运行,只有在数据发生改变的时候才会运行。
混合练习(二) todolist
所要实现的功能,实现数据的增删改查。
业务处理逻辑:
1、使用假数据初始化,模型数据arr:[{}];
2、v-model 双向绑定 ,input输入框与模型数据inputVal;
3、增加任务
- 思路:
(1)input设置change事件,回车触发
(2)添加按钮设置click事件,点击触发
(3)事件处理函数都为add(),都是实现向数组arr中添加一条新的对象数据
(4)添加成功后,input输入框重新置空
4、按钮禁用
- 思路:
(1)给 添加按钮 设置disabled属性,属性值用v-bind绑定数据模型bool,控制该添加按钮的禁用功能
(2)vue的watch属性,监听inputVal的变化,为空则bool=true,启用禁用功能
5、统计任务总数:arr.length;
6、统计剩余任务数
- 思路:
(1)给arr数组的每条数据设置一个status属性,用来存储复选框的状态
(2)遍历arr,统计status为false的数据的数量
(3)将这个数量值return出去
(4)将这个函数添加到view中的某个位置,语法是:{{last()}}
7、勾选复选框,任务样式改变
- 思路:
(1)将复选框双向绑定到arr数据的status属性,v-model="item.status"
(2)写一个样式.del{}
,加删除线,字体颜色也变暗
(3)v-bind指令,可以使用status的值,然后判断arr里每条数据的status属性值,为true则添加删除样式,否则添加 ’ ’ 空字符,:class="item.status?'del':''"
8、点击 完成 删除已选任务
- 思路:
(1)给完成按钮添加点击事件,事件处理如下:
(2)将arr复制给另外的newArr
(3)然后把arr清空
(4)然后再重新遍历newArr,找到 status为false的内容 ,插入到原始数据中,更新view。以下我找到两种写法:
第一种,我的写法:
第二种,老师的写法:delTask(){ let newArr=this.arr.concat(); this.arr.splice(0); newArr.forEach((item,index)=>{ if(item.status==false) this.arr.push(item); }) }
del(){ var newarr=this.arr; // 1.把原始数据赋值给一个新变量保存 this.arr=[]; // 2.把这个原始数据清空 for(var i=0;i<newarr.length;i++){ // 3.遍历新数据 并且找到 style为false的内容 插入到原始数据中 if(newarr[i].style==false){ this.arr.push(newarr[i]) } } }
9、点击修改任务名
- 思路:
(0)在文本标签span后面再跟一个input输入框,并设置v-if、v-else命令,控制二者永远只显示一个,并在arr数据里设置一个变量edit进行控制。
(1)点击标签触发事件,切换成input输入框
(2)输入框绑定blur事件,输入完成后失焦时触发,切换回span标签
(3)绑定同一个事件处理函数,实现非删除状态下(未选中复选框),控制切换的变量的正反状态更改
10、当修改单个文本时,禁用复选框;
11、点击文本进入编辑模式,但是我发现切换成输入框后,必须手动聚焦,才能触发失焦事件,那么怎么让文本输入框自动聚焦?
发现了一篇超棒的文章:Vue 中如何让 input 聚焦?(包含视频讲解)
下面是完整代码,不过点击进入文本编辑模式时文本自动聚焦的功能我没实现。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="./node_modules/vue/dist/vue.js"></script>
<style>
.del {
text-decoration: line-through;
color: #ccc;
}
</style>
</head>
<body>
<div id="demoSky">
<h1>任务列表</h1>
<p>
任务总数:{{arr.length}};剩余任务:{{last()}};点击 <button @click="delTask()">完成</button>,移除任务
</p>
<ul>
<li v-for="(item,index) in arr">
<input type="checkbox" v-model="item.status" :disabled="!item.edit">
<span :class="item.status?'del':''" @click="clickHandler(item)" v-if="item.edit">{{item.title}}</span>
<input type="text" v-model="item.title" @blur="clickHandler(item)" v-else id="autoget">
</li>
</ul>
<input type="email" placeholder="任务" v-model="inputVal" @change="add()" > <button :disabled="bool" @click="add()">添加</button>
</div>
<script>
new Vue({
el: "#demoSky",
data: {
arr: [
{ title: "设计1", status: false, edit: true },
{ title: "设计2", status: false, edit: true },
{ title: "设计3", status: false, edit: true },
{ title: "设计4", status: false, edit: true },
],
inputVal: "",
bool: true,
ifBool: true,
checBool: false,
},
methods: {
add() {
this.arr.push({ title: this.inputVal, status: false, edit: true });
this.inputVal = "";
},
last() {
let num = 0;
for (let i = 0; i < this.arr.length; i++) {
if (this.arr[i].status == false) num++;
}
return num;
},
delTask() {
let newArr = this.arr.concat();
this.arr.splice(0);
newArr.forEach((item, index) => {
if (item.status == false) this.arr.push(item);
})
},
clickHandler(item) {
console.log("before:", item.edit)
if (item.status) return;
item.edit = !item.edit;
console.log("after:", item.edit)
}
},
watch: {
// 监听输入框的改变,然后改变其后button的disabled值,来判断是否进行该按钮
inputVal(newVal, oldValue) {
if (this.inputVal) {
this.bool = false;
} else {
this.bool = true;
}
}
}
})
</script>
</body>
</html>
>> 补充几个事件简介:change&input&keydown&blur&focus
1、change
js的onchange事件:
- 会在域的内容改变时发生。
- 也可用于单选框与复选框改变后触发的事件。
- onchange 触发需要三个步骤:
- input 元素获得焦点
input 元素的值发生变化
input 元素失去焦点
- input 元素获得焦点
jQuery的change事件与change()方法:
- 当元素的值发生改变时,会发生 change 事件。
该事件仅适用于文本域(text field),以及 textarea 和 select 元素。 - change() 函数触发 change 事件,或规定当发生 change 事件时运行的函数。
注释:当用于 select 元素时,change 事件会在选择某个选项时发生。当用于 text field 或 text area 时,该事件会在元素失去焦点时发生。
我说:因为最常使用的是input的文本输入和复选框checkbox嘛,我就从这两个方向看一下change到底是怎么用的。
- 如果是文本输入input添加change事件,那么每次改变数据回车后,只会触发一次change事件;
- 如果是checkbox的话,只要点击就会触发;
- 我还试了一下密码的,也会触发change事件。
2、input
- 文本 input 是输入时触发,回车不能触发
- checkbox选中或者取消选中都可以触发
3、keydown
keydown 按下按键的时候触发,啥键都行,而且如果查看当前触发的事件, 而且打印的事件对象有个属性 keycode
可以查看当前按下的按键的键码值。
Event 对象代表事件的状态,比如事件在其中发生的元素、键盘按键的状态、鼠标的位置、鼠标按钮的状态。
4、blur
- onblur:当元素失去焦点的时候。
- 常用的地方有 从单选按钮上移开焦点。
5、focus
onfocus:当元素获取到焦点的时候触发