render函数#

1
2
<!--vue2-->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
1
2
3
4
5
6
7
8
9
10
11
12
<body>
<div id="app"></div>
<script>
new Vue({
// 第一个参数是标签名,第二个参数是标签的属性,第三个参数是标签体
render: h =>
h("div", { class: "container" }, [
h("h1", { class: "title" }, "hello world"),
]),
}).$mount("#app");
</script>
</body>
1
2
3
4
5
6
7
8
<body>
<div id="app"></div>
<script>
new Vue({
template: `<div class='container'><h1 class='title'>hello world</h1></div>`,
}).$mount("#app");
</script>
</body>
1
2
3
4
5
6
7
8
9
10
<body>
<div id="app">
<div class='container'><h1 class='title'>hello world</h1></div>
</div>
<script>
new Vue({
template: "#app",
}).$mount("#app");
</script>
</body>

以上三种结果相同

h()hyperscript 的简称——意思是“能生成 HTML (超文本标记语言) 的 JavaScript”。这个名字来源于许多虚拟 DOM 实现默认形成的约定。

render()若存在render函数,vue会将render 中的VNode渲染到页面,若不存在则会将挂载的标签中的html编译为Vnode再由render进行渲染,同时存在render优先级更高。

虚拟节点VNode

image-20230212002420932

生成的DOM,注意: <div id="app">不存在了已经

1
2
3
<div class="container">
<h1 class="title">hello world</h1>
</div>

在某些情况写render比模板中更方便

Proxy#

more: https://zh.javascript.info/proxy

模拟计数#

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<body>
<div id="app"><div id="count"></div><button onclick="add()">加一</button></div>
<script>
let count = ref(0);
let countDiv = document.querySelector('#count');
countDiv.innerText = count.value;
function ref(target){
// 监听get和set事件
return new Proxy({value:target}, {
get(target, key) {
console.log('get', key)
return target[key]
},
set(target, key, value) {
console.log('set', key, value)
countDiv.innerHTML = value;
target[key] = value
}
})
}
function add(){
count.value++;
}
</script>
</body>

proxy

more: https://cn.vuejs.org/guide/extras/rendering-mechanism.html

模拟双向绑定#

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
<body>
<div id="app">
<div id="mes"></div>
<input type="text" oninput="change(value)" />
</div>
<script>
let mes = ref('hello world');
let mesDiv = document.querySelector("#mes");
mesDiv.innerText = mes.value;
document.getElementsByTagName("input")[0].value = mes.value;

function ref(target) {
return new Proxy(
{ value: target },
{
get(target, key) {
console.log("get", key);
return target[key];
},
set(target, key, value) {
console.log("set", key, value);
mesDiv.innerText = value;
target[key] = value;
},
}
);
}
function change(val) {
console.log(val);
mes.value = val;
}
</script>
</body>