目录
- 一、自定义指令v-mycolor
- 二、使用钩子函数的自定义指令
- 三、Vue实现简单的学生信息管理系统
除了核心功能默认内置的指令,Vue.js允许注册自定义指令。添加一个自定义指令,有两种方式:
(1)通过Vue.directive()函数注册一个全局的指令
(2)通过组件directives属性,对该组件添加一个局部的指令
一、自定义指令v-mycolor
示例:
<div id="root">
<div v-mycolor="color" id="demo">
{{hello}}
</div>
</div>
<script>
Vue.config.productionTip = false;
Vue.directive('mycolor', function(el, binding, vnode) {
el.style = 'color:' + binding.value;
});
const vm = new Vue({
el: '#root',
data: {
hello:"你好",
color:'red'
},
methods: {
}
})
</script>
执行结果:
通过以上示例,可以看到网页上的"你好"是红色,说明自定义指令起到了作用。
在自定义指令中,可以传递是三个参数:
el:指令所绑定的元素,可以用来直接操作DOM。
binding:一个对象,包含指令的很多信息。
vnode:Vue.js编译生成的虚拟节点。
自定义指令生命周期:
(1)bind:只调用一次,指令第一次绑定到元素时调用,用这个钩子函数可以定义一个绑定时执行一次的初始化动作
(2)nserted:被绑定元素插入父节点时调用(父节点存在即可调用,不必存在与document中)。
(3)update:被绑定于元素所在的模板更新时调用,而无论绑定至是否变化。通过比较更新前后的绑定值,可以忽略不必要的模板更新。
(4)componentUpdated:被绑定元素所在模板完成一次更新周期时调用。
(5)unbind:只调用一次,指令与元素解绑时调用
二、使用钩子函数的自定义指令
钩子函数的参数如下所示:
el:与上面介绍的一样,el是指令所绑定的元素,可以用来直接操作DOM;
示例:
<div id="root">
<div v-mycolor="color" id="demo">
{{num}}
</div>
<div>
<button @click="add">Add</button>
</div>
</div>
<script>
Vue.config.productionTip = false;
Vue.directive('mycolor',{
bind:function(){
console.log('1-绑定时调用bind');
},
inserted:function(el,binding,vnode){
alert('绑定到节点时调用inserted');
console.log('2-绑定到节点时调用inserted');
el.style='color:'+binding.value;
},
update:function(el,binding,vnode){
alert('3-组件更新时调用update');
console.log('3-组件更新时调用update');
el.style='color:green';
},
componentUpdated:function(){
console.log('4-组件更新完成时调用componentUpdated');
}
})
const vm = new Vue({
el: '#root',
data: {
num:10,
color:'red'
},
methods: {
add:function(){
this.num++;
}
}
})
</script>
执行结果:
运行后,浏览器会弹出"绑定到节点时调用inserted",这时文字的颜色会变成红色,且浏览器的控制中输出:
当点击"Add"按钮时,浏览器会弹出"3-组件更新时调用update",这时文字会由"10"变成11,字体颜色会变成绿色:
三、Vue实现简单的学生信息管理系统
实现学生信息的增删改查和分页功能,及按照学生年龄进行降序排序,升序排序和原顺序
全部源代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="../../vue-2.7.14.js"></script>
<style>
* {
margin: 0px;
padding: 0px;
}
#root {
margin: 0px auto;
width: 900px;
height: auto;
background-color: orange;
}
div {
margin: 0px auto;
border: 2px solid black;
width: 98%;
text-align: center;
padding-top: 10px;
padding-bottom: 10px;
}
table {
width: 98%;
margin: 1px auto;
border: 2px solid black;
border-collapse: collapse;
}
th,
td {
border: 2px solid black;
padding: 5px;
}
label {
margin-left: 10px;
}
input {
height: 30px;
}
button {
width: 100px;
height: 30px;
}
span {
margin-left: 50px;
margin-right: 50px;
}
</style>
</head>
<body>
<div id="root">
<div>
<h2>学生信息管理系统</h2>
<div>
<h2>添加信息</h2><br>
<div>
<input type="text" placeholder="请输入学号" v-model="id">
<input type="text" placeholder="请输入姓名" v-model="name">
<input type="text" placeholder="请输入性别" v-model="sex">
<input type="text" placeholder="请输入年龄" v-model="age">
<button v-on:click="add">提交</button>
</div><br>
<div>
<h2>查询信息</h2><br>
<input type="text" placeholder="请输入要查询的姓名" v-model.lazy="keyword">
<button @click="search()">查询</button>
</div>
</div><br>
<div>
<table>
<tr>
<th>序号</th>
<th>学号</th>
<th>姓名</th>
<th>性别</th>
<th>年龄</th>
<th>创建时间</th>
<th>操作</th>
</tr>
<tr v-for="(student,index) in dataShow" :key="student.id">
<td>{{index+1}}</td>
<td>{{student.id}}</td>
<td>{{student.name}}</td>
<td>{{student.sex}}</td>
<td>{{student.age}}</td>
<td>{{student.ctime | newTime}}</td>
<td>
<button @click.prevent='toEdit(student.id)'>修改</button>
<button @click.prevent="del(index)">删除</button>
</td>
</tr>
<tr>
<td align="right" colspan="7">共计 {{count}} 人</td>
</tr>
</table>
</div><br>
<div>
<select v-model="pageSize" v-on:change="changePageSize">
<option value="5">5页</option>
<option value="10">10页</option>
<option value="15">15页</option>
<option value="20">20页</option>
</select>
<button v-on:click="firstPage" :disabled="currentPage === 1">首页</button>
<button v-on:click="previousPage" :disabled="currentPage === 1">上一页</button>
<button v-on:click="nextPage" :disabled="currentPage === totalPages">下一页</button>
<button v-on:click="lastPage" :disabled="currentPage === totalPages">尾页</button>
<span>当前是第{{ currentPage }}页 / 总共{{ totalPages }}页</span>
</div>
<br>
<div v-show="flag">
<h2>修改信息</h2>
<br><br>
<label>学号:<input type="text" placeholder="请输入学号" v-model="id2"></label>
<label>姓名:<input type="text" placeholder="请输入姓名" v-model="name2"></label>
<br><br>
<label>性别:<input type="text" placeholder="请输入性别" v-model="sex2"></label>
<label>年龄:<input type="text" placeholder="请输入年龄" v-model="age2"></label>
<br><br>
<button @click="add2(editIndex)">保存</button>
</div>
<div>
<span><button style="width: 150px;" v-on:click="sortType=2">按年龄升序</button></span>
<span><button style="width: 150px;" v-on:click="sortType=1">按年龄降序</button></span>
<span><button style="width: 150px;" v-on:click="sortType=0">原顺序</button></span>
</div>
</div>
</div>
<script>
Vue.config.productionTip = false;
Vue.filter("newTime", (value) => {
year = value.getFullYear();
month = value.getMonth() + 1;
day = value.getDate();
return `${year}年${month}月${day}日`;
// return year + "年" + month + "月" + day + "日"
})
const vm = new Vue({
el: '#root',
data: {
flag: false,//true表示修改窗口展开,false表示窗口关闭
id: "",
name: "",
sex: "",
age: "",
id2: "",
name2: "",
sex2: "",
age2: "",
keyword: "",
time: "",
sortType: 0,//0表示原顺序,1表示降序,2表示升序
editIndex: null, // 保存正在编辑的对象的索引,初始值不能为0及0以上的数
students: [
{ id: "00001", name: "张三", sex: "男", age: 20, ctime: new Date() },
{ id: "00002", name: "李四", sex: "女", age: 19, ctime: new Date() },
{ id: "00003", name: "王五", sex: "男", age: 18, ctime: new Date() },
{ id: "00004", name: "赵六", sex: "男", age: 19, ctime: new Date() },
{ id: "00005", name: "李力", sex: "男", age: 21, ctime: new Date() },
{ id: "00006", name: "二狗", sex: "男", age: 17, ctime: new Date() },
{ id: "00007", name: "狗蛋", sex: "女", age: 20, ctime: new Date() },
{ id: "00008", name: "三炮", sex: "男", age: 19, ctime: new Date() },
{ id: "00009", name: "刘仁", sex: "女", age: 19, ctime: new Date() },
{ id: "00010", name: "四儿", sex: "男", age: 22, ctime: new Date() }
],
newStudents: [],
currentPage: 1,//当前页数,默认为1
pageSize: 5,//每页显示数量
},
computed: {
//计算有几组学生信息
count() {
return this.fillPersons.length;
},
dataShow() {
let start = (this.currentPage - 1) * this.pageSize;
let end = Math.min((this.currentPage) * this.pageSize, this.count);
return this.fillPersons.slice(start, end);
},
//计算总页数
totalPages() {
return Math.ceil(this.count / this.pageSize) || 1;
},
//对学生信息进行排序
fillPersons() {
// 找到第一个满足条件的元素就终止过滤操作
const arr = this.students.filter((p) => {
return p.name.indexOf(this.keyword) !== -1;
});
//对学生信息进行升序降序和原顺序排序
if (this.sortType) {
arr.sort((p1, p2) => {
return this.sortType === 1 ? p2.age - p1.age : p1.age - p2.age;
});
}
return arr;
}
},
methods: {
//更改每页显示的记录数时更新当前页码,以确保在更改每页记录数后,
// 用户仍然可以看到正确的记录列表。
changePageSize() {
this.currentPage = 1;
},
//首页
firstPage() {
this.currentPage = 1;
},
//上一页
previousPage() {
this.currentPage -= 1;
},
//下一页
nextPage() {
this.currentPage += 1;
},
//尾页
lastPage() {
this.currentPage = this.totalPages;
},
//添加操作
add() {
//添加进对应的学生信息
this.students.push({
id: this.id,
name: this.name,
sex: this.sex,
age: this.age,
ctime: new Date()
});
//重新赋空值
this.id = "",
this.name = "",
this.sex = "",
this.age = ""
},
//删除操作
del(index) {
//根据下标删除对应的学生信息
this.students.splice(index, 1);
},
//查询操作
search() {
//判断是否输入查询内容
if (this.keyword) {
// this.students = this.newStudents;
//找到满足条件的元素并赋值
var list = this.students.filter(item => item.name.indexOf(this.keyword) > -1);
if (list.length != 0) {
alert("查询成功");
this.students = list;
} else {
alert("查询失败");
this.students = [];
}
this.keyword = ''
} else {
alert("请输入要查找的姓名");
}
},
// 修改操作
toEdit(id) {
//定位索引
this.editIndex = id;
// flag 调成 true,调出修改操作窗口
this.flag = true;
// filter 操作:找到第一个满足条件的元素就终止过滤操作
let student = this.students.filter(stu => {
// 注意:此时的返回值 student 是一个对象
return stu.id == id;
});
// 此时在文本框中显示的是:已经选中的学生信息
this.id2 = student[0].id;
this.name2 = student[0].name;
this.sex2 = student[0].sex;
this.age2 = student[0].age;
},
// 修改保存操作
add2(editIndex) {
// flag 调成 false,就表示是关闭修改操作窗口
this.flag = false;
//查找需要修改的的下标
var index = this.students.findIndex((item) => {
if (item.id == this.editIndex) {
return true;
}
})
//删除对应下标的学生信息
this.students.splice(index, 1);
// //把最最新的学生信息重新添加
this.students.push({
id: this.id2,
name: this.name2,
sex: this.sex2,
age: this.age2,
ctime: new Date()
});
// //重新赋空值
this.id2 = "",
this.name2 = "",
this.sex2 = "",
this.age2 = ""
},
}
})
</script>
</body>
</html>
执行结果:
上图只展示了主界面,其他功能请自行复制粘贴到vscode中执行修改!