第3章:vue生命周期及实例的属性

 

  Vue的生命周期

  vue的生命周期图示

   生命周期示例day02/03.html

<!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 

<!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,使用计算属性定义函数在函数内处理

  示例

<!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 计算属性

<!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是打印计算属性

  页面输出

   修改代码

  调用方法输出而不是计算属性

console.log(vm.getNum2());
// console.log(vm.num2);

  页面输出

   3,.get和set

  计算属性由两部分组成:get和set,分别用来获取计算属性和设置计算属性

  默认只有get,如果需要set,要自己添加

  计算属性赋值不能给自己赋值而需要给该计算属性依赖的值赋值,示例

<!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.属性

vm.$el
vm.$data
vm.$options
vm.$refs

  示例05.html

<!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.方法

vm.$mount()
vm.$destroy()
vm.$nextTick()

vm.$set()
vm.$delete()
vm.$watch()

  mount手动挂载实例

<!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>

  手动挂载的效果和以下代码效果是一样的

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在修改以后

<!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绑定在函数内执行

// console.log(vm.$refs.title.textContent);
        vm.$nextTick(function(){
            // DOM更新完成再执行此代码
            console.log(vm.$refs.title.textContent);
        });

  页面显示

   方法

vm.$set(object,key,value)
vm.$delete(object,key)
vm.$watch(data,callback[,options])

  set方法示例 day02/06.html

<!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()代码

 this.$set(this.user,'age',18);

  页面显示

   以下代码是添加属性的全局方式,和上面代码实现的效果是一样的

Vue.set(this.user,'age',19)

  一般情况下set方法不直接使用而是做一个判断再使用,例如需要从user中获取这个属性,如果有这个属性则给这个属性值+1,赋值设置这个属性值为1

 if(this.user.age){
    this.user.age++;
}else{
    Vue.set(this.user,'age',1);
 }

  delete方法演示

  06.html

<!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

<!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。注意监听数组的变更不需要这么做。

  示例,监听一个数组的变更

<!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选项

   修改代码如下

  // 深度监视
user:{
	handler:(newValue,oldValue) => {
	console.log('user被修改啦,原值:'+oldValue.name+',新值:'+newValue.name);
	},
	deep:true //深度监视,当对象中的属性发生变化时也会监视
	}

  页面显示

   newValue和oldValue指向的是同一个地址空间,值是修改之后的值,所以是一样的。

原文地址:https://www.cnblogs.com/minseo/p/15683823.html