一、使用Vue实现对数组的增删改查
在管理员的一些后台页面里,个人中心里的数据列表里,都会有对这些数据进行增删改查的操作。比如在管理员后台的用户列表里,我们可以录入新用户的信息,也可以对既有的用户信息进行修改。在vue中,我们更应该专注于对数据的操作和处理。
比如我们有这样的的一个页面
样式
<style>
table{
border-collapse: collapse;
}
th,td{
padding: 2px 15px;
border: 1px solid #ccc;
text-align: center;
}
#edit{
width: 300px;
height: 230px;
border: 1px solid #ccc;
padding: 20px;
position: fixed;
left: 0;
top: 0;
right: 0;
bottom: 0;
margin: auto;
}
#edit .close{
width: 30px;
height: 30px;
border: 1px solid #ccc;
background-color: lightcoral;
color: white;
text-align: center;
line-height: 30px;
font-size: 20px;
border-radius: 50%;
cursor: pointer;
position: absolute;
right: 10px;
top: 10px;
}
</style>
页面
<div id="app">
<button @click="showEdit=true">添加</button>
<hr>
<table>
<thead>
<tr>
<th>学号</th>
<th>姓名</th>
<th>年龄</th>
<th>性别</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<tr v-for="(item,index) in students" :key="index">
<td>{{item.no}}</td>
<td>{{item.name}}</td>
<td>{{item.age}}</td>
<td>{{item.sex}}</td>
<td>
<button @click="getOne(item.no)">修改</button>
<button @click="delStudent(index)">删除</button>
</td>
</tr>
</tbody>
</table>
<div id="edit" v-show="showEdit">
<!-- 在修改界面中,不能修改学号 -->
<p>学号:<input type="text" v-model="student.no" :readonly="!isAdd"></p>
<p>姓名:<input type="text" v-model="student.name"></p>
<p>年龄:<input type="text" v-model="student.age"></p>
<p>性别:<input type="text" v-model="student.sex"></p>
<p>
<button v-if="isAdd" @click="addStudent">添加</button>
<button v-else @click="updateStudent">修改</button>
<button @click="clear">取消</button>
</p>
<div class="close" @click="close">X</div>
</div>
</div>
// 引入vue.js文件
<script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.14/vue.js"></script>
定义一个学生数组
new Vue({
el:'#app',
data:{
//定义一个学生数组
students:[
{
no:'1001',
name:'刘德华',
age:20,
sex:'男'
},
{
no:'1002',
name:'周杰伦',
age:22,
sex:'男'
},
{
no:'1003',
name:'蔡依林',
age:24,
sex:'女'
}
],
是否显示编辑窗口(接上)
showEdit:false,
是否是添加状态
isAdd:true,
学生对象
student:{
no:'',
name:'',
age:0,
sex:''
}
},
methods: {
//添加方法
addStudent(){
//将表单数据展开后,返回一个新的对象
let stu = {...this.student}
//将学生对象添加到学生数组中
this.students.push(stu)
//调用清空表单数据的方法
this.clear()
},
//清空表单数据的方法
clear(){
this.student = {
no:'',
name:'',
age:0,
sex:''
}
},
//关闭编辑窗口
close(){
this.showEdit = false
this.isAdd = true
this.clear()
},
//根据学号查询学生对象
getOne(no){
//打开编辑窗口
this.showEdit = true
//编辑窗口是修改状态
this.isAdd = false
//根据学号查询学生对象
let stu = this.students.find(s=>s.no===no)
this.student = {...stu}
},
//修改学生信息
updateStudent(){
//根据学号,找到原始数组中指定的学生对象
let stu = this.students.find(s=>s.no===this.student.no)
//修改数组里面指定学生对象的属性
stu.name = this.student.name
stu.age = this.student.age
stu.sex = this.student.sex
},
//删除学生
delStudent(index){
if(confirm('确定删除吗?')){
this.students.splice(index,1)
}
}
},
})
点击添加后效果如图
总结:
里面的难点不太多,主要是form表单方面的操作,再一个就是练习下组件间的数据与事件传递。内容比较简单,欢迎各位批评指正。
二、vue的生命周期
1.简单写个页面
<div id="app">
<h2 id="name">{{name}}</h2>
<h2 id="age">{{age}}</h2>
<div>
<button @click="name='李四'">修改姓名</button>
<button @click="age=30">修改年龄</button>
<button @click="destroy">不过了</button>
</div>
</div>
// 引入vue文件
<script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.14/vue.js"></script>
<script>
Vue.config.productionTip = false
let vm = new Vue({
// 指定挂载的容器
// el:'#app',
// 指定模板(如果有模板,vue会渲染整个模板;如果没有模板,vue会将el里面的所有内容当成模板使用)
// template:'<div><h2>{{name}}</h2><h2>{{age}}</h2></div>',
//数据
data:{
name:'张三',
age:20,
},
methods: {
destroy(){
// 调用销毁当前Vue实例的方法
// 注意:销毁后,当前Vue实例对象还在,只是该对象不能在重新挂载页面了
this.$destroy()
}
},
//创建之前(数据初始化之前)
beforeCreate() {
console.log('-----------------beforeCreate------------------');
// 这个生命周期函数,基本上不用,除非要设置Vue实例的内容
this.__proto__.fn = function(){
alert('哈哈!')
}
//Vue实例,已经创建完成
console.log(this);
//Vue实例身上的数据还没有初始化完成
console.log(this.name+' '+this.age);
},
//创建完成(数据初始化完成)
created() {
console.log('-----------------created------------------');
// 这个生命周期函数,通常用于初始化Vue管理的数据,比如:发生ajax请求会放在这里。
console.log(this);
console.log(this.name+' '+this.age);
},
//挂载之前(模板已经成功渲染,但是还没有将内容挂载到页面中)
beforeMount() {
console.log('-----------------beforeMount------------------');
// 这个生命周期函数,基本上不用
console.log(this.$el);
// document.querySelector('#name').innerHTML = "哈哈"
},
//挂载完成(模板已经成功渲染,并且已经将模板内容挂载到了页面)
mounted() {
console.log('-----------------mounted------------------');
// 这个生命周期函数,通常用于对DOM的重新改动
console.log(this.$el);
// document.querySelector('#name').innerHTML = "呵呵"
},
//修改之前(数据已经改了,只是还没有重新挂载页面)
beforeUpdate() {
console.log('-----------------beforeUpdate------------------');
console.log(this.name+' '+this.age);
console.log(this.$el);
},
//修改完成(数据已经改了,页面也已经重新挂载)
updated() {
console.log('-----------------updated------------------');
console.log(this.name+' '+this.age);
console.log(this.$el);
},
//销毁之前
beforeDestroy() {
console.log('-----------------beforeDestroy------------------');
// 这个生命周期函数,会用的多一些
console.log(this);
// 对数据做任何的修改,都不会重新渲染到页面
this.name = '王五'
},
//销毁完成
destroyed() {
console.log('-----------------destroyed------------------');
// 这个生命周期函数,几乎不用
console.log(this);
this.name = '王五'
},
})
setTimeout(() => {
// 通过vue实例的$mount方法,手动挂载容器
// 公共el选项指定挂载容器,当模板渲染成功后,会离开挂载页面
// $mount方法的好处是,可以自行选择挂载的时机。
vm.$mount('#app')
}, 1000);
</script>
Vue实例有一个完整的生命周期,也就是说从开始创建、初始化数据、编译模板、挂在DOM、渲染-更新-渲染、卸载等一系列过程,我们成为Vue 实例的生命周期,钩子就是在某个阶段给你一个做某些处理的机会。
beforeCreate( 创建前 )
在实例初始化之后,数据观测和事件配置之前被调用,此时组件的选项对象还未创建,el 和 data 并未初始化,因此无法访问methods, data, computed等上的方法和数据。
created ( 创建后 )
实例已经创建完成之后被调用,在这一步,实例已完成以下配置:数据观测、属性和方法的运算,watch/event事件回调,完成了data 数据的初始化,el没有。 然而,挂在阶段还没有开始, $el属性目前不可见,这是一个常用的生命周期,因为你可以调用methods中的方法,改变data中的数据,并且修改可以通过vue的响应式绑定体现在页面上,,获取computed中的计算属性等等,通常我们可以在这里对实例进行预处理,也有一些童鞋喜欢在这里发ajax请求,值得注意的是,这个周期中是没有什么方法来对实例化过程进行拦截的,因此假如有某些数据必须获取才允许进入页面的话,并不适合在这个方法发请求,建议在组件路由钩子beforeRouteEnter中完成
beforeMount
挂在开始之前被调用,相关的render函数首次被调用(虚拟DOM),实例已完成以下的配置: 编译模板,把data里面的数据和模板生成html,完成了el和data 初始化,注意此时还没有挂在html到页面上。
mounted
挂在完成,也就是模板中的HTML渲染到HTML页面中,此时一般可以做一些ajax操作,mounted只会执行一次。
beforeUpdate
在数据更新之前被调用,发生在虚拟DOM重新渲染和打补丁之前,可以在该钩子中进一步地更改状态,不会触发附加地重渲染过程
updated(更新后)
在由于数据更改导致地虚拟DOM重新渲染和打补丁只会调用,调用时,组件DOM已经更新,所以可以执行依赖于DOM的操作,然后在大多是情况下,应该避免在此期间更改状态,因为这可能会导致更新无限循环,该钩子在服务器端渲染期间不被调用
beforeDestroy(销毁前)
在实例销毁之前调用,实例仍然完全可用,
这一步还可以用this来获取实例,
一般在这一步做一些重置的操作,比如清除掉组件中的定时器 和 监听的dom事件
destroyed(销毁后)
在实例销毁之后调用,调用后,所以的事件监听器会被移出,所有的子实例也会被销毁,该钩子在服务器端渲染期间不被调用
三、轮播图例子
样式
<style>
#app {
position: relative;
width: 750px;
}
#app img {
width: 100%;
}
.jiantou {
width: 50px;
height: 50px;
background-color: rgba(0, 0, 0, 0.50);
position: absolute;
top: 0;
bottom: 0;
margin: auto 0;
font-size: 30px;
text-align: center;
line-height: 50px;
color: white;
cursor: pointer;
}
.left {
left: 10px;
}
.right {
right: 10px;
}
</style>
页面
<body>
<div id="app" @mouseenter="mouseenter" @mouseleave="mouseleave">
<img :src="imgs[showActive]">
<div class="left jiantou" @click="left">←</div>
<div class="right jiantou" @click="right">→</div>
<button @click="destroy">终止播放</button>
</div>
<script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.14/vue.js"></script>
<script>
Vue.config.productionTip = false
new Vue({
el: '#app',
data: {
//定义定时器
timer: null,
//显示的下标
showActive: 0,
//图片数组
imgs: ["http://p1.music.126.net/7zAkp74zoKd0LuEuEP6dOg==/109951166645160829.jpg?imageView&quality=89",
"http://p1.music.126.net/pkXsmqmFQOehNkJYmehkng==/109951166646695577.jpg?imageView&quality=89",
"http://p1.music.126.net/c1olbeIgiVsj9I39fCUXkQ==/109951166644891380.jpg?imageView&quality=89",
"http://p1.music.126.net/JMYet32O1mi6-YZ1GGSYcQ==/109951166646419732.jpg?imageView&quality=89",
"http://p1.music.126.net/WCX5Cq1z17Du2z0QBEcEaA==/109951166645933077.jpg?imageView&quality=89"]
},
methods: {
left() {
this.showActive--
//如果下标越界,重新从0开始
if (this.showActive < 0) this.showActive = 4
},
right() {
this.showActive++
//如果下标越界,重新从0开始
if (this.showActive >= 5) this.showActive = 0
},
mouseenter() {
clearInterval(this.timer)
},
mouseleave() {
//开启定时器
this.run()
},
run() {
this.timer = setInterval(() => {
console.log(11);
this.showActive++
//如果下标越界,重新从0开始
if (this.showActive >= 5) this.showActive = 0
}, 1000);
},
destroy(){
this.$destroy()
}
},
//生命周期函数(表示页面挂载完成)
mounted() {
//开启定时器
this.run()
},
// 在这个生命周期函数中,清除定时器
beforeDestroy() {
clearInterval(this.timer)
},
})
</script>
</body>