本文章出自全栈Ace
VIP课程 b战搜索全栈Ace
仅用作学习记录
准备工作,新建一个文件,index.html
1.index.html 代码如下:
点击查看代码
<!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">
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
<title>Document</title>
</head>
<body>
<div id="app">
{{userName}}
</div>
<script>
var vm = new Vue({
el: "#app",
data: {
userName: "Ace"
}
})
vm.$data.userName = "Taro"
</script>
</body>
</html>
2.新建一个文件myVue.js
myVue.js
/**
* Vue类的创建
* @param {*} options vue实例中的众多对象 (data,method,el)
*/
function Vue(options) {
this._init(options)
}
/**
* 创建一个方法用于获取vue对象中的众多属性,并把这个方法赋值给Vue的原型对象_init
* @param {*} options vue实例中的众多对象 (data,method,el)
*/
Vue.prototype._init = function (options) {
//此时this指向Vue类
let vm = this
console.log(`this 为:${this}`)
//创建Vue的对象 $options,来接收传入的options对象
vm.$options = options
//初始化vue
initState(vm)
}
/**
* 初始化vue
* @param {*} vm vue对象
*/
function initState(vm) {
let opt = vm.$options
// 初始化data对象
if (opt.data) {
initData(vm)
}
// 初始化watch
// if (opt.watch) {
// initWatch()
// }
//
}
/**
* 初始化Data
* @param {*} vm vue对象
*/
function initData(vm) {
//获取data
let data = vm.$options.data
//vue 对象中创建$data 方法
//data || {} 表示如果data为null则直接返回{}空对象
vm.$data = data || {}
if (typeof data != 'object' || data == null) {
return
} else {
new Observe(data, vm)
}
}
/**
* 监听类 用于监听data的变化
* @param {*} data 数据对象
* @param {*} vm vue对象
*/
function Observe(data, vm) {
/**
* 重构data 并对其进行get/set 属性代理
* @param {*} data
* @param {*} vm
*/
function restructure(data, vm) {
let keys = Object.keys(data)
console.log(keys)
// 循环遍历每一个key 并进行代理化改造
// ★核心内容
for (let index = 0; index < keys.length; index++) {
let key = keys[index]
let value = data[key]
//先定义vm中的对象,就不会出现后面重复定义的错误
vm[key] = value
// 验证value是否依旧是对象(递归)
if (typeof value != 'object' || value == null) {
//啥都不做
// vm[key] = value
// console.log('到了')
// console.log(vm)
} else {
new Observe(value, vm)
}
// 给data中的变量配置get/set属性用于监听
//或者可以理解成把指定key挂载到data中
Object.defineProperty(data, key, {
get: function () {
return value
},
set: function (newValue) {
if (newValue != value) {
//验证newValue是否是对象
if (typeof newValue != 'object' || newValue == null) {
//啥都不做
} else {
new Observe(newValue, vm)
}
value = newValue
//这里只是做一个日志输出,如果是一个正常的vue,则应该是更新视图方法
console.log(`我现在是[${value}] 啦`)
}
},
})
//直接将data中的变量挂载到vm中
//注意: 如果之前vm中未曾定义过这些属性,若是有两个相同的key则会出现重复定义属性的错误
//解决方案:在之前每一次for循环后先通过vm[key] = value
//定义一次,那么在这里就不会再次定义了
//这和js中xxx.xxx的意思一样,如果xxx.xx的xx在xxx中不存在则会定义,存在则只是调用
Object.defineProperty(vm, key, {
get: function () {
return value
},
set: function (newValue) {
if (newValue != value) {
//验证newValue是否是对象
if (typeof newValue != 'object' || newValue == null) {
//啥都不做
} else {
new Observe(newValue, vm)
}
// value = newValue
console.log(`我现在是[${value}] 啦`)
}
},
})
}
}
restructure(data, vm)
}
上述代码分为如下步骤:
- 创建vue类
- 写vue全局扩展类(.NET 是这么叫)
- 初始化vue
- 初始化data
- 监听类 用于监听data的变化(重构data)
3. index.html更新
点击查看代码
<!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">
<!-- <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script> -->
<script src="./myVue.js"></script>
<title>Document</title>
</head>
<body>
<div id="app">
{{userName}}
</div>
<script>
var vm = new Vue({
data: {
userName: "Ace",
user: {
userName: "Taro",
age: 18
}
}
})
vm.user.userName = "GaoSi"
</script>
</body>
</html>
原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/tech/pnotes/280010.html