前文指路:《Vue零基础教程》,从前端框架到GIS开发系列课程
Vue零基础教程|从前端框架到GIS开发系列课程(二)
Vue零基础教程|从前端框架到GIS开发系列课程(三)模板语法
Vue零基础教程|从前端框架到GIS开发系列课程(四)计算属性与侦听器
Vue零基础教程|从前端框架到GIS开发系列课程(五)组件式开发
Vue零基础教程|从前端框架到GIS开发系列课程(六)组合式API
Party1什么是响应式
当数据改变时, 引用数据的函数会自动重新执行
Party2手动完成响应过程
首先, 明确一个概念:响应式是一个过程, 这个过程存在两个参与者: 一方触发, 另一方响应
同样, 所谓数据响应式的两个参与者
●触发者: 数据
●响应者: 引用数据的函数
当数据改变时, 引用数据的函数响应数据的改变, 重新执行
我们先手动完成响应过程
示例
<!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>
</head>
<body>
<div id="app"></div>
<script>
// 定义一个全局对象: `触发者`
const obj = { name: 'hello' }
// effect函数引用了obj.name, 这个函数就是 `响应者`
function effect() {
// 这里可以通过app拿到DOM对象
app.innerHTML = obj.name
}
effect()
// 当obj.name改变时, 手动执行effect函数, 完成响应过程
setTimeout(() => {
obj.name = 'brojie'
effect()
}, 1000)
</script>
</body>
</html>
为了方便, 我们把引用了数据的函数 叫做副作用函数
Party3副作用函数
如果一个函数引用了外部的资源, 这个函数会受到外部资源改变的影响
我们就说这个函数存在副作用. 因此, 也把该函数叫做副作用函数
这里, 大家不要被这个陌生的名字吓唬住
所谓副作用函数就是引用了数据的函数或者说数据关联的函数
Party4自定义设置过程
如果我们能感知数据改变, 拦截到赋值操作. 自定义设置过程
在赋值的同时调用一下数据关联的副作用函数, 就可以实现自动重新执行
理论上可行, 开始动手实践
1) Proxy代理对象
这里我们需要先补充一下Proxy相关的知识. 如果已经知道的小伙伴可以略过
new Proxy: 传入一个源对象, 返回一个新对象(代理对象)
当访问代理对象的属性时, 可以自定义访问过程
当设置代理对象的属性时, 可以自定义设置过程
示例
<!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>
</head>
<body>
<script>
// 定义一个源对象(目标对象)
const obj = { name: 'xiaopang' }
// 创建一个代理对象
const proxy = new Proxy(obj, {
get(target, key) {
// 当访问proxy代理对象的属性时, 会执行get函数
// 将get函数的返回值作为表达式的值
console.log(target, key)
return target[key] // obj.name obj[name]
},
set(target, key, value) {
// 当设置proxy代理对象的属性时, 会执行set函数
console.log('自定义set操作', value)
target[key] = value
return true
},
})
// console.log(proxy.name)
// console.log(proxy.age)
proxy.name = 'xxp'
console.log(obj)
</script>
</body>
</html>
这样就确定了思路
1先创建代理对象
2再操作代理对象(给代理对象赋值)
2) 最基本的reactive函数
定义一个函数reactive, 传入一个普通对象, 返回代理对象
示例
<!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>
</head>
<body>
<script>
function isObject(value) {
return typeof value === 'object' && value !== null
}
/**
* 创建响应式数据
* @param [object]: 普通对象
* @return [Proxy]: 代理对象
*/
function reactive(data) {
if (!isObject(data)) return
return new Proxy(data, {
get(target, key) {
return target[key]
},
set(target, key, value) {
target[key] = value
return true
},
})
}
const state = { name: 'xiaopang' }
const p = reactive(state)
p.name = 'xxp'
console.log(p.name)
</script>
</body>
</html>
Party5最基本的响应式
既然可以自定义set操作, 只需要在自定义set操作时, 重新执行属性关联的副作用函数
示例
<!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>
</head>
<body>
<div id="app">hello</div>
<script>
/**
* 定义响应式
* @param [object] : 普通对象
* @return [Proxy] : 代理对象
*/
function reactive(data) {
// 如果传入的data不是一个普通对象, 不处理
if (typeof data !== 'object' || data == null) return
return new Proxy(data, {
get(target, key) {
console.log(`自定义访问${key}`)
return target[key]
},
set(target, key, value) {
console.log(`自定义设置${key}=${value}`)
target[key] = value // 先更新值
effect() // 再调用effect, 调用effect时会重新获取新的数据
return true
},
})
}
const pState = reactive({ name: 'hello' })
function effect() {
app.innerHTML = pState.name
}
setTimeout(() => {
pState.name = 'brojie'
}, 1000)
</script>
</body>
</html>
看到这里, 恭喜你, 已经掌握了最核心的原理🤝
💡小结
1响应式是一个过程, 存在触发者和响应者
2数据的改变, 触发关联的副作用函数响应(重新执行)
3通过Proxy代理源数据
4在Proxy的自定义set操作中, 重新执行副作用函数
需要vue教程资料,备注:《Vue零基础教程》