-
window上生成Vue
在用Rollup搭建开发环境时,用了format:"umd",的打包模式。
umd的打包模式会在window上添加Vue节点。
例如:在src/index.js中
export default function Vue() {
console.log('Vue节点');
}
rollup打完包后在html页面中引入生成的vue.js
然后打印Vue
<body>
<div id="Vue">首页</div>
<script src="dist/vue.js"></script>
<script>
// umd 打包模式会给window添加Vue
console.log(Vue);
</script>
</body>
页面结果为
image.png
-
操作
- 在页面配置Vue
new Vue({
el: '#app', // el 挂载元素的位置,也叫编译模版
data: {
}
})
- 在js里拿到用户的配置项
export default function Vue(options) {
console.log(options); // options为用户配置项
}
- 设置初始化方法
新建init.js
export function initMixin(Vue) {
Vue.prototype._init = function (options) {
console.log(options);
}
}
在index.js中注入调用
import { initMixin } from "./init";
function Vue(options) {
// 初始化
this._init (options) // _init 初始化方法 使用前先放到Vue原型链上
}
// 初始化,在init.js文件中给Vue原型链添加_init初始化方法
initMixin(Vue)
export default Vue
初始化状态
新建initState.js
import { initData } from "./initData";
export function initState(vm) {
let ops = vm.$options // 获取用户配置项
console.log(ops);
// 判断
if (ops.data) {
initData(vm) // data初始化
}
}
初始化data
新建initData.js
export function initData(vm) {
let data = vm.$options.data
data = typeof data === "function"?data.call(vm):data; // 注意 通过call指向vue的实例
// 对数据进行劫持
}
劫持data
import { observe } from "./observe/index";
export function initData(vm) {
let data = vm.$options.data
// 在vm上添加一个属性 _data
data = vm._data = typeof data === "function"?data.call(vm):data; // 注意 通过call指向vue的实例
// 对数据进行劫持
// data 有两种类型对象和数组 {a:{b:1}, list:[]}
observe(data)
}
判断data是对象还是数组,然后通过创建一个类来劫持对象data
- 劫持对象
- 劫持对象用Object.defineProerty,有个缺点,只能对对象中对一个属性进行劫持
- 遍历data进行劫持
- 嵌套对data 用递归 进行深度劫持
export function observe(data) {
console.log(data);
// 1.判断类型是否是对象
if (typeof data != 'object' || data == null) {
return data;
}
// 1. 对象,通过一个类来劫持对象data
return new Observer(data)
}
// 用来劫持对象的类
class Observer{
constructor (value){ // constructor 数据观测
this.walk(value) // 遍历
}
walk(data){
let keys = Object.keys(data) // 获取对象
for (let i = 0; i < keys.length; i++) {
// 在这个循环里对每个属性进行劫持
let key = keys[i]; // 属性
let value = data[key] // 值
defineReactive(data, key, value)
}
}
}
function defineReactive(data, key, value) { //{a:{b:1}}
observe(value) // 深度代理,深度劫持
// 对对象中对属性进行劫持
Object.defineProperty(data,key,{
get(){ // 使用获取
console.log('获取时触发');
return value
},
set(newValue){ // 修改的时候
console.log('设置时触发');
if(newValue == value) return ;
value = newValue
}
})
}
// {}
- 劫持数组
方法:函数劫持,重写数组方法,也就是劫持数组方法
// 重写数组
// 1. 获取原来的数组方法
let oldArrayProtoMethods = Array.prototype
// 2. 继承
export let ArrayMethods = Object.create(oldArrayProtoMethods) // 创建一个对象
// 劫持
let methods = [
"push",
"pop",
"unshift",
"shift",
"splice"
]
methods.forEach(item => {
ArrayMethods[item] = function (...args) {
console.log('劫持数组');
let result = oldArrayProtoMethods[item].apply(this, args) // this执行当前的数组 {list: []}
return result
}
})
网友评论