第3章:vue生命周期及实例的属性
Vue的生命周期
vue的生命周期图示
生命周期示例day02/03.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 | <! DOCTYPE html> < html lang="en"> < head > < meta charset="UTF-8"> < title >Vue生命周期</ title > < script src="js/vue.js"></ script > < script > window.onload=function(){ let vm=new Vue({ el:'#itany', data:{ msg:'welcome to itany' }, methods:{ update(){ this.msg='欢迎来到南京网博!'; }, destroy(){ // this.$destroy(); vm.$destroy(); } }, beforeCreate(){ alert('组件实例刚刚创建,还未进行数据观测和事件配置'); }, created(){ //常用!!! alert('实例已经创建完成,并且已经进行数据观测和事件配置'); }, beforeMount(){ alert('模板编译之前,还没挂载'); }, mounted(){ //常用!!! alert('模板编译之后,已经挂载,此时才会渲染页面,才能看到页面上数据的展示'); }, beforeUpdate(){ alert('组件更新之前'); }, updated(){ alert('组件更新之后'); }, beforeDestroy(){ alert('组件销毁之前'); }, destroyed(){ alert('组件销毁之后'); } }); } </ script > </ head > < body > < div id="itany"> {{msg}} < br > < button @click="update">更新数据</ button > < button @click="destroy">销毁组件</ button > </ div > </ body > </ html > |
计算属性
1.基本用法
计算属性也是用来存储数据的,但具有以下几个特点
a.数据可以进行逻辑处理操作
b.对计算属性中的数据进行监视
计算属性取值不能向定义普通属性那样定义,需要定义函数,函数必须有返回值称为get值,调用的时候和普通属性是一样的{{}}
示例day02/04.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | <! DOCTYPE html> < html lang="en"> < head > < meta charset="UTF-8"> < title >计算属性</ title > < script src="js/vue.js"></ script > < script > window.onload=function(){ let vm=new Vue({ el:'#itany', data:{ // 普通属性 msg:'welcome to itany' }, computed:{ // 计算属性 msg2:function(){ return '欢迎来到南京网博'; } } }); } </ script > </ head > < body > < div id="itany"> <!-- 1,基本用法 --> < h2 >{{msg}}</ h2 > < h2 >{{msg2}}</ h2 > </ div > </ body > </ html > |
假如想要把msg以空格为分隔符然后反向输出,下面有两种方法
1,在数据展示时进行逻辑处理
2,使用计算属性定义函数在函数内处理
示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | <! DOCTYPE html> < html lang="en"> < head > < meta charset="UTF-8"> < title >计算属性</ title > < script src="js/vue.js"></ script > < script > window.onload=function(){ let vm=new Vue({ el:'#itany', data:{ // 普通属性 msg:'welcome to itany' }, computed:{ // 计算属性 msg2:function(){ return '欢迎来到南京网博'; }, reverseMsg:function(){ return this.msg.split(' ').reverse().join(' '); } } }); } </ script > </ head > < body > < div id="itany"> <!-- 1,基本用法 --> < h2 >{{msg}}</ h2 > < h2 >{{msg2}}</ h2 > <!-- 对数据进行处理 --> <!-- 缺点:在模板中放入了太多逻辑处理代码 --> < h2 >{{msg.split(' ').reverse().join(' ')}}</ h2 > <!-- 在计算属性内定义函数处理 --> < h2 >{{reverseMsg}}</ h2 > </ body > </ html > |
页面显示,两种处理方法效果是一样的
2.计算属性 vs 方法
将计算属性的get函数定义为一个方法也可以实现类似的功能
区别:
a.计算属性是基于它的依赖进行更新的,只有在相关依赖发送改变时才能更新变化
b.计算属性是缓存的,只要相关依赖没有改变,多次访问计算属性得到的值是之前缓存的计算结果,不会多次执行
示例day02/04html 计算属性
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 | <! DOCTYPE html> < html lang="en"> < head > < meta charset="UTF-8"> < title >计算属性</ title > < script src="js/vue.js"></ script > </ head > < body > < div id="itany"> <!-- 1,基本用法 --> < h2 >{{msg}}</ h2 > < h2 >{{msg2}}</ h2 > <!-- 对数据进行处理 --> <!-- 缺点:在模板中放入了太多逻辑处理代码 --> < h2 >{{msg.split(' ').reverse().join(' ')}}</ h2 > <!-- 在计算属性内定义函数处理 --> < h2 >{{reverseMsg}}</ h2 > < button @click="change">修改值</ button > <!-- 2.计算属性 vs 方法 --> <!-- <h2>{{num1}}</h2> <h2>{{num2}}</h2> <h2>{{getNum2()}}</h2> --> < button onclick="fn()">测试</ button > </ div > < script > let vm=new Vue({ el:'#itany', data:{ // 普通属性 msg:'welcome to itany', num1:7 }, computed:{ // 计算属性 msg2:function(){ return '欢迎来到南京网博'; }, reverseMsg:function(){ // 可以包含逻辑处理操作,同时reverseMsg依赖于msg return this.msg.split(' ').reverse().join(' '); }, num2:function(){ console.log(new Date()) return this.num1-1 } }, methods:{ change(){ // this.msg='i love you' this.num1=666; }, getNum2(){ console.log('num2'+new Date()) return this.num1-1; } } }); function fn(){ setInterval(function(){ // console.log(vm.getNum2()); console.log(vm.num2); },1000); } </ script > </ body > </ html > |
解析:函数fn是单独定义的不属于vue实例,点击测试时候调用,间隔1秒执行打印 vm.num2是打印计算属性
页面输出
修改代码
调用方法输出而不是计算属性
1 2 | console.log(vm.getNum2()); // console.log(vm.num2); |
页面输出
3,.get和set
计算属性由两部分组成:get和set,分别用来获取计算属性和设置计算属性
默认只有get,如果需要set,要自己添加
计算属性赋值不能给自己赋值而需要给该计算属性依赖的值赋值,示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 | <! DOCTYPE html> < html lang="en"> < head > < meta charset="UTF-8"> < title >计算属性</ title > < script src="js/vue.js"></ script > </ head > < body > < div id="itany"> <!-- 1,基本用法 --> < h2 >{{msg}}</ h2 > < h2 >{{msg2}}</ h2 > <!-- 对数据进行处理 --> <!-- 缺点:在模板中放入了太多逻辑处理代码 --> < h2 >{{msg.split(' ').reverse().join(' ')}}</ h2 > <!-- 在计算属性内定义函数处理 --> < h2 >{{reverseMsg}}</ h2 > < button @click="change">修改值</ button > <!-- 2.计算属性 vs 方法 --> <!-- <h2>{{num1}}</h2> <h2>{{num2}}</h2> <h2>{{getNum2()}}</h2> --> < button onclick="fn()">测试</ button > <!-- 3,get和set --> < h2 >{{num2}}</ h2 > < button @click="change2">修改计算属性</ button > </ div > < script > let vm=new Vue({ el:'#itany', data:{ // 普通属性 msg:'welcome to itany', num1:7 }, computed:{ // 计算属性 msg2:function(){ return '欢迎来到南京网博'; }, reverseMsg:function(){ // 可以包含逻辑处理操作,同时reverseMsg依赖于msg return this.msg.split(' ').reverse().join(' '); }, num2:{ get:function(){ console.log(new Date()) return this.num1-1 }, set:function(val){ // console.log('修改num2的值') // this.num2=val; this.num1=val; } } }, methods:{ change(){ // this.msg='i love you' this.num1=666; }, getNum2(){ console.log('num2'+new Date()) return this.num1-1; }, change2(){ this.num2=111; }, } }); function fn(){ setInterval(function(){ console.log(vm.getNum2()); // console.log(vm.num2); },1000); } </ script > </ body > </ html > |
解析:点击修改计算属性调用change2方法,在这个方法内给num2赋值给111,当出现赋值操作则调用该计算属性的set方法,传递的参数val就是change2中设置的的值111,但是不能在set方法内直接修改num2 的值,如果直接修改会因为重复调用溢出栈报错,需要修改的是是num1的值,因为num2依赖num1所以num2的值也修改了
页面显示
四,vue实例的属性和方法
1.属性
1 2 3 4 | vm.$el vm.$data vm.$options vm.$refs |
示例05.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 | <! DOCTYPE html> < html lang="en"> < head > < meta charset="UTF-8"> < title >vue实例的属性和方法</ title > < script src="js/vue.js"></ script > </ head > < body > < div id="itany"> {{msg}} < h2 ref="hello">你好</ h2 > < p ref='world'>世界</ p > < hr > <!-- <p ref='title'>标题:{{name}}</p> --> </ div > < script > vm=new Vue({ el:'#itany', data:{ msg:'welcome to itany', }, name:'liuym', age:24, show:function(){ console.log('show') }, }); // 属性 // vm.属性名,获取data中的属性 console.log(vm.msg); // vm.$el 获取vue实例关联的元素 console.log(vm.$el) vm.$el.style.color='red' // vm.$data 获取数据对象 console.log(vm.$data) // vm.$options 用来获取自定义属性 console.log(vm.$options.name) vm.$options.show(); // vm.$refs 获取所有添加ref属性的元素 console.log(vm.$refs.hello); // DOM对象 vm.$refs.hello.style.color='red'; // 方法 // 手动挂载vue实例 // vm.$mount('#itany') // var vm=new Vue({ // data:{ // msg:'欢迎来到南京网博', // name:'tom' // } // }).$mount('#itany'); // vm.$destory() 销毁实例 一般不手动调用 // vm.$destory(); // vm.$nextTick(callback)在DOM更新完成后再执行回调函数,一般在修改数据之后使用该方法,以便能获取更新后的DOM // 修改数据 // vm.name='汤姆'; // DOM还没有更新完 Vue实现响应式并不是数据发生改变之后DOM立即变化,需要按一定的策略进行DOM更新,需要时间 // console.log(vm.$refs.title.textContent); // vm.$nextTick(function(){ // // DOM更新完成再执行此代码 // console.log(vm.$refs.title.textContent); // }); </ script > </ body > </ html > |
页面显示
2.方法
1 2 3 4 5 6 7 | vm.$mount() vm.$destroy() vm.$nextTick() vm.$set() vm.$delete() vm.$watch() |
mount手动挂载实例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 | <! DOCTYPE html> < html lang="en"> < head > < meta charset="UTF-8"> < title >vue实例的属性和方法</ title > < script src="js/vue.js"></ script > </ head > < body > < div id="itany"> {{msg}} < h2 ref="hello">你好</ h2 > < p ref='world'>世界</ p > < hr > <!-- <p ref='title'>标题:{{name}}</p> --> </ div > < script > // vm=new Vue({ // el:'#itany', // data:{ // msg:'welcome to itany', // }, // name:'liuym', // age:24, // show:function(){ // console.log('show') // }, // }); // 属性 // vm.属性名,获取data中的属性 // console.log(vm.msg); // vm.$el 获取vue实例关联的元素 // console.log(vm.$el) // vm.$el.style.color='red' // vm.$data 获取数据对象 // console.log(vm.$data) // vm.$options 用来获取自定义属性 // console.log(vm.$options.name) // vm.$options.show(); // vm.$refs 获取所有添加ref属性的元素 // console.log(vm.$refs.hello); // DOM对象 // vm.$refs.hello.style.color='red'; // 方法 // 手动挂载vue实例 // vm.$mount('#itany') var vm=new Vue({ data:{ msg:'欢迎来到南京网博', name:'tom' } }).$mount('#itany'); // vm.$destory() 销毁实例 一般不手动调用 // vm.$destory(); // vm.$nextTick(callback)在DOM更新完成后再执行回调函数,一般在修改数据之后使用该方法,以便能获取更新后的DOM // 修改数据 // vm.name='汤姆'; // DOM还没有更新完 Vue实现响应式并不是数据发生改变之后DOM立即变化,需要按一定的策略进行DOM更新,需要时间 // console.log(vm.$refs.title.textContent); // vm.$nextTick(function(){ // // DOM更新完成再执行此代码 // console.log(vm.$refs.title.textContent); // }); </ script > </ body > </ html > |
手动挂载的效果和以下代码效果是一样的
1 2 3 4 5 6 7 8 9 10 11 | vm=new Vue({ el:'#itany', data:{ msg:'welcome to itany', }, name:'liuym', age:24, show:function(){ console.log('show') }, }); |
vm.$nextTick(callback)示例
vm.$nextTick(callback)在DOM更新完成后再执行回调函数,一般在修改数据之后使用该方法,以便能获取更新后的DOM
不使用nextTick在修改以后
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 | <! DOCTYPE html> < html lang="en"> < head > < meta charset="UTF-8"> < title >vue实例的属性和方法</ title > < script src="js/vue.js"></ script > </ head > < body > < div id="itany"> {{msg}} < h2 ref="hello">你好</ h2 > < p ref='world'>世界</ p > < hr > < p ref='title'>标题:{{name}}</ p > </ div > < script > // vm=new Vue({ // el:'#itany', // data:{ // msg:'welcome to itany', // }, // name:'liuym', // age:24, // show:function(){ // console.log('show') // }, // }); // 属性 // vm.属性名,获取data中的属性 // console.log(vm.msg); // vm.$el 获取vue实例关联的元素 // console.log(vm.$el) // vm.$el.style.color='red' // vm.$data 获取数据对象 // console.log(vm.$data) // vm.$options 用来获取自定义属性 // console.log(vm.$options.name) // vm.$options.show(); // vm.$refs 获取所有添加ref属性的元素 // console.log(vm.$refs.hello); // DOM对象 // vm.$refs.hello.style.color='red'; // 方法 // 手动挂载vue实例 // vm.$mount('#itany') var vm=new Vue({ data:{ msg:'欢迎来到南京网博', name:'tom' } }).$mount('#itany'); // vm.$destory() 销毁实例 一般不手动调用 // vm.$destory(); // vm.$nextTick(callback)在DOM更新完成后再执行回调函数,一般在修改数据之后使用该方法,以便能获取更新后的DOM // 修改数据 vm.name='汤姆'; // DOM还没有更新完 Vue实现响应式并不是数据发生改变之后DOM立即变化,需要按一定的策略进行DOM更新,需要时间 console.log(vm.$refs.title.textContent); // vm.$nextTick(function(){ // // DOM更新完成再执行此代码 // console.log(vm.$refs.title.textContent); // }); </ script > </ body > </ html > |
页面显示
修改代码使用nextTick绑定在函数内执行
1 2 3 4 5 | // console.log(vm.$refs.title.textContent); vm.$nextTick(function(){ // DOM更新完成再执行此代码 console.log(vm.$refs.title.textContent); }); |
页面显示
方法
1 2 3 | vm.$set(object,key,value) vm.$delete(object,key) vm.$watch(data,callback[,options]) |
set方法示例 day02/06.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | <! DOCTYPE html> < html lang="en"> < head > < meta charset="UTF-8"> < title >添加和删除属性</ title > < script src="js/vue.js"></ script > </ head > < body > < div id="itany"> < button @click="doUpdate">修改属性</ button > < button @click="doAdd">添加属性</ button > < hr > < h2 >{{user.name}}</ h2 > < h2 >{{user.age}}</ h2 > </ div > < script > var vm=new Vue({ el:'#itany', data:{ user:{ id:1001, name:'tom' } }, methods:{ doUpdate(){ this.user.name='汤姆'; }, doAdd(){ this.user.age=25; // 通过普通方式为对象添加属性时vue无法实时监控到 // this.$set(this.user,'age',18); // 通过vue实例的$set方法可以实时监视 // Vue.set(this.user,'age',19) // if(this.user.age){ // this.user.age++; // }else{ // Vue.set(this.user,'age',1); // } }, } }); </ script > </ body > </ html > |
user本身没有age属性,使用doAdd方法添加这个属性,页面显示
如果需要监控实时显示,修改代码使用set方法,修改方法doAdd()代码
1 | this.$set(this.user,'age',18); |
页面显示
以下代码是添加属性的全局方式,和上面代码实现的效果是一样的
1 | Vue.set(this.user,'age',19) |
一般情况下set方法不直接使用而是做一个判断再使用,例如需要从user中获取这个属性,如果有这个属性则给这个属性值+1,赋值设置这个属性值为1
1 2 3 4 5 | if(this.user.age){ this.user.age++; }else{ Vue.set(this.user,'age',1); } |
delete方法演示
06.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | <! DOCTYPE html> < html lang="en"> < head > < meta charset="UTF-8"> < title >添加和删除属性</ title > < script src="js/vue.js"></ script > </ head > < body > < div id="itany"> < button @click="doUpdate">修改属性</ button > < button @click="doAdd">添加属性</ button > < button @click="doDelete">删除属性</ button > < hr > < h2 >{{user.name}}</ h2 > < h2 >{{user.age}}</ h2 > </ div > < script > var vm=new Vue({ el:'#itany', data:{ user:{ id:1001, name:'tom' } }, methods:{ doUpdate(){ this.user.name='汤姆'; }, doAdd(){ // this.user.age=25; // 通过普通方式为对象添加属性时vue无法实时监控到 this.$set(this.user,'age',18); // 通过vue实例的$set方法可以实时监视 // Vue.set(this.user,'age',19) // if(this.user.age){ // this.user.age++; // }else{ // Vue.set(this.user,'age',1); // } }, doDelete(){ if(this.user.age){ // delete this.user.age; // 无效 Vue.delete(this.user,'age'); } }, } }); </ script > </ body > </ html > |
页面显示
watch方法示例
有两种方法监视数据day02/07.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | <! DOCTYPE html> < html lang="en"> < head > < meta charset="UTF-8"> < title >监视数据的变化</ title > < script src="js/vue.js"></ script > </ head > < body > < div id="itany"> < input type='text' v-model="name"> < h3 > {{name}}</ h3 > < hr > < input type='text' v-model="age"> < h3 > {{age}}</ h3 > </ div > < script > var vm=new Vue({ el:'#itany', data:{ name:'tom', age:23 }, watch:{ // 方式2,使用vue实例提供的watch选项 age:(newValue,oldValue)=>{ console.log('age被修改了,原值'+oldValue+',新值'+newValue); } } }); // 监视数据变化,没有全局方法 // 方式1:使用vue实例提供的$watch()方法 vm.$watch('name',function(newValue,oldValue){ console.log('name被修改了,原值'+oldValue+',新值'+newValue); }); </ script > </ body > </ html > |
监视数据传递两个参数一个是修改后的新值一个是旧值
页面显示
选项:deep 深度监视
为了发现对象内部值的变化,可以在选项参数中指定 deep: true
。注意监听数组的变更不需要这么做。
示例,监听一个数组的变更
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | <! DOCTYPE html> < html lang="en"> < head > < meta charset="UTF-8"> < title >监视数据的变化</ title > < script src="js/vue.js"></ script > </ head > < body > < div id="itany"> < input type='text' v-model="name"> < h3 > {{name}}</ h3 > < hr > < input type='text' v-model="age"> < h3 > {{age}}</ h3 > < hr > < input type='text' v-model="user.name"> < h3 > {{user.name}}</ h3 > </ div > < script > var vm=new Vue({ el:'#itany', data:{ name:'tom', age:23, user:{ name:'汤姆' } }, watch:{ // 方式2,使用vue实例提供的watch选项 age:(newValue,oldValue)=>{ console.log('age被修改了,原值'+oldValue+',新值'+newValue); }, user:(newValue,oldValue)=>{ console.log('user被修改了,原值'+oldValue+',新值'+newValue); }, } }); // 监视数据变化,没有全局方法 // 方式1:使用vue实例提供的$watch()方法 vm.$watch('name',function(newValue,oldValue){ console.log('name被修改了,原值'+oldValue+',新值'+newValue); }); </ script > </ body > </ html > |
解析:想要监控数组user的变更,但是页面显示,因为只是修改了数组user下面属性name的值,但是数组user对name属性的指向并没有变化,需要深度监视需要加deep选项
修改代码如下
1 2 3 4 5 6 7 | // 深度监视 user:{ handler:(newValue,oldValue) => { console.log('user被修改啦,原值:'+oldValue.name+',新值:'+newValue.name); }, deep:true //深度监视,当对象中的属性发生变化时也会监视 } |
页面显示
newValue和oldValue指向的是同一个地址空间,值是修改之后的值,所以是一样的。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!