// 如何让实现响应式的呢?
let obj = {};
let name = 'zhangsan';
Object.defineProperties(obj, name, {get : function() {
console.log('name' , name)
}, set : function() {
console.log('name' , name)
}})
// 1. 关键是理解Object.defineProperty
// 2. 将data的属性代理到vm上面的
let mv = {};
let data = {
price: 100,
name: 'zhangsan'
};
for (let key in data) {
(function (key) {
Object.defineProperty(mv, key, {
get: function () {
console.log('get val');
return data[key];
},
set: function (val) {
console.log('set val');
data[key] = val;
}
})
})(key);
}
<div id="app">
<div>
<input v-model="title">
<button v-on:click="add">submitbutton>
div>
<ul>
<li v-for="item in list">{{item}}li>
ul>
div>
// 1(*****). 模板实际上就是一个字符串………………(vue中的模板的本质)
// 2. 模板有逻辑,如v-if, v-for
// 3. 与html格式很像,但是有很大的区别
// 4. 最终还是要转换为html来显示
// 5(*****). 模板最终必须转换成JS代码,因为:
// (1)有逻辑(v-if v-for):必须用JS才能实现(图灵完备)
// (2) 转换成HTML来渲染页面,必须用JS才能实现
// (3) 因此,模板最终要转换成为一个JS函数(render函数)
var obj = {
name: 'zhangsan',
age: 20,
getAddress(){
alert('shanghai');
}
}
// 不使用with
function fn() {
alert(obj.name);
alert(obj.age);
obj.getAddress();
}
// 使用with(代码不易维护!!!)
function fn1() {
with(obj){
alert(name);
alert(age);
getAddress();
}
}
fn();
fn1();
<div id='app'>
<p>{{price}}</p>
</div>
// 使用with限制这个作用域里面的this
with(this) {
return _c( // this._c
'div',
{
attrs: {"id" : "app"} // id=app
},
[
_c('p', [_v(_s(price))]) // this._c('p', [_v(_s(price))])
]
)
}
// 实现一个自己的render函数
var vm = new Vue({
el: '#app',
data: {
price: 100
}
});
function render() {
with (vm) {
return _c(
'div',
{
attrs: {'id': 'app'}
},
[
_c('p', [_v(_s(price))])
]
);
}
}
function render() {
return vm._c(
'div',
{
attrs: {'id': 'app'}
},
[
// vm._v 转换为一个文本节点
// vm._s 转换为一个字符串
// vm._c 转换为一个DOM节点
vm._c('p', [vm._v(vm._s(price))])
]
);
}
<div id="app">
<div>
<input type="text" v-model="title">
<button @click="add">submitbutton>
div>
<div>
<ul>
<li v-for="item in list">{{item}}li>
ul>
div>
div>
with (this) {
// this 就是vm
return _c(
'div',
{attrs: {"id": "app"}},
[
_c('div',
[
_c('input', {
directives: [{
name: "model",
rawName: "v-model",
value: (title),
expression: "title"
}],
attrs: {"type": "text"},
domProps: {"value": (title)},
on: {
"input": function ($event) {
if ($event.target.composing) return;
title = $event.target.value
}
}
}),
_v(" "),
_c('button',
{
on: {
"click": add
}
},
[_v("submit")]
)
]
),
_v(" "),
_c('div',
[
_c(
'ul',
// 这里返回的是一个数组(li标签组成的数组)
_l((list), function (item) {
return _c('li', [_v(_s(item))])
}), 0
)
]
)
]
)
}
// view ---> data ---> 使用input的事件绑定 ---> 更新页面数据到data
// data ---> view ---> defineProperty ---> 同步数据到页面
vm._update(vnode) {
const prevNode = vm._vnode;
vm._vnode = vnode;
if (!prevNode) {
// 首次渲染的时候
vm.$el = vm.__patch__(vm.$el, vnode);
}
else{
vm.$el = vm.__patch__(prevNode, vnode);
}
}
// 开始更新vue组件(修改data的属性的时候,Object.defineProperty)
function updateComponent() {
vm._update(vm._render());
}