提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
一、vue的响应式原理?
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div id='app'>
<input id='ipt' type="text">
<h1 id='user'></h1>
</div>
<script>
// Data getter/setter 劫持
var app = {}
var username = 'zhangsan'
Object.defineProperty(app, 'username', {
// 表示“读”,当我们访问app.username时,会触发get这个方法
get: function() {
return username
},
// 表示“写”,当我们修改app.username时,会触发set这个方法
set: function(newVal) {
username = newVal
// 通知watcher,让它去更新真实的DOM
Watcher(newVal)
}
})
// Watcher,它唯一的作用是更新DOM
function Watcher(newVal) {
document.getElementById('user').innerText = newVal
document.getElementById('ipt').value = newVal
}
// 页面初始化,使用watcher把响应式数据渲染到界面,并给相关的元素绑定js事件
Watcher(app.username)
// 页面中的表单事件
// .lazy 当表单失焦时,再更新app声明式变量
// document.getElementById('ipt').addEventListener('blur', function(e){
// app.username = e.target.value
// })
// 不加.lazy的效果,只有表单变化,就更新声明变量
document.getElementById('ipt').addEventListener('keyup', function(e){
app.username = e.target.value
})
</script>
</body>
</html>
Vue在实例化时,会把data选项中键值对进行遍历,使用Object.defineProperty()的方法为属性添加getter和setter给this实例,所以我们在当前实例上,对数据的读取进行劫持,可以通过this来访问这些声明式变量
二、生命周期
钩子函数(常用8个,共11个)
beforeCreate
created
beforeMount
mounted
beforeUpdete
updeted
beforeDestroy
destroy
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>生命周期</title>
</head>
<body>
<div id='app' class='app'>
<h1>测试生命周期</h1>
<h1 v-text='count'></h1>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
// 生命周期
var app = new Vue({
el: '#app', // 挂载
data: {
count: 1,
timer: null
},
// 第一阶段,实例化阶段,vue实例创建过程
// 响应式原理就在这里实现的
beforeCreate() {
console.log('beforeCreate')
},
created() {
console.log('created')
},
// 第二阶段,挂载阶段,把vue实例和真实的DOM关联起来
// vue创建虚拟DOM、用声明式变量替换虚拟DOM中各种指令,转换成真实DOM渲染到界面中
beforeMount(){
console.log('beforeMount')
},
mounted() {
console.log('mounted')
// 在这里调后端接口、开启定时器、开启websocket长连接
this.timer = setInterval(function(){
console.log('1')
}, 1000)
},
// 第三阶段,更新阶段,当声明式变量发生变化时触发
// 什么是虚拟DOM?虚拟DOM是在挂载阶段创建的一个json变量
// 虚拟DOM本质就是一个json对象,它是存储在当前硬件的内存中一个变量
// 虚拟DOM就是用来描述真实DOM
// 当声明式变量发生变化时,就自动生成一个新的虚拟DOM
// vue使用diff运算,对两个虚拟DOM进行差异化对比,找到最小的差异
// 最后通过watcher把这个最小的差异更新到真实的DOM中去,页面进而自动更新
// 虚拟DOM存在的意义,就是最小化地减少DOM操作,因为DOM操作最耗费性能的
beforeUpdate() {
console.log('beforeUpdate')
},
updated() {
console.log('updated')
},
// 第四阶段,销毁阶段
// 把watcher拆卸掉,把当前组件及其子组件中事件绑定都解绑
beforeDestroy() {
console.log('beforeDestroy')
// 清除定时器、清除长连接,清除一切耗费性能的业务
clearInterval(this.timer)
},
destroyed() {
console.log('destroyed')
}
})
</script>
</body>
</html>