
正文
【js】 vue 2.5.1 源码学习(一) 大体结构 (自写版本,非源码)
提示:扫一扫查出行【扫一扫了解最新限行尾号】
复制提示
一、整体思路
1. 首先我们需要解析data,并且data里面的属性添加为vue的属性,并且拿到属性值 。 通过 原型方法 _peoxy实现 Obsever(代理函数) ==》 walk convert defineReactive
2. 对象属性的默认值 defineProperty
3. vue.init ==> $mount ==> compile
// 大概思路 1. 将data的值设置为Vue的属性。 _peoxy Obsever(代理函数) ==》 walk convert defineReactive
// 2. 对象属性的默认值 defineProperty
// 3. vue.init ==> $mount ==> compile (function(root, factory){
root.Vue = factory()
})(this,function(){
var noop = function(){ }
function compile(){ }
function defineProperty(obj , key ,val , def ){
// 判断是都又值,没有则选择默认值
if(val !== undefined){
obj[key] = val
}else{
obj[key] = def
}
}
function obsever(data){
// 数据变化的监听代理
if(!data || typeof data !=='object') return
return new Obsever(data)
}
function Obsever(data){
this.data = data
this.walk()
}
Obsever.prototype = {
walk:function(){
var obj = this.data
this.convert(obj)
},
convert: function(obj){
var _this = this
Object.keys(obj).forEach(function(key){
_this.defineReactive(obj,key,obj[key])
})
},
defineReactive: function(obj,key,val){
Object.defineProperty(obj,key,{
get: function(){
return val
},
set:function(newVal){
console.log('我能够监听到message他的变化')
val = newVal
}
})
}
}
function Vue(options){
this.$options = options || {}
var data = this._data = options.data
var _this = this
defineProperty(this , '$rander' , this.render , noop )
Object.keys(data).forEach(function(value){
// console.log('eee')
_this._proxy(value,data[value])
})
obsever(data)
this.init(options);
}
// 将data的属性设置到vue上
Vue.prototype._proxy= function(key,val){
var _this = this
Object.defineProperty(this,key,{
set: function(newVal){
console.log('newVal===' +newVal)
this._data[key] = newVal
},
get: function(){
return this._data[key]
}
})
}
// 初始化Vue
Vue.prototype.init = function(options){
var _this = this
var el = options.el
if(el!==undefined){
this.$mount(el) // 拿到template
}
}
Vue.prototype.$mount= function(el){
var template = this.template
this.$el = typeof el === 'string' ? document.querySelector(el) : document.body
if(this.$el == null){
error('Elenemt' + this.$options.el + 'none found')
}
defineProperty(this,'$template',template,this.$el.outerHTML)
if(this.$render === noop){
this.$render = Vue.compile(this.$template)
} }
Vue.compile = function(){
// 解析html。
}
return Vue
})
<body>
<div id="app">
{{ message }}
</div>
<!-- <script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.js"></script> -->
<script src="./vue.js"></script>
<script type="text/javascript">
var vm = new Vue({
el:"#app",
data: {
message: "hello Vue",
key: "wodow"
},
computed: {
add:function(){
// this.xxx
}
},
methods: { },
mounted: function(){ } })
vm.message = "hello yue" // vue 实例会代替data里面的值。
console.log( vm.message)
</script>
</body>
以上代码只是简单的叙述了一个大概开始,后续还有更多。






