この記事は、誰もが原則を理解できるようにするためのもので、書かれたコードはVueソースコードではありません。
<div id="app">
<h1> {
{
name }} </h1>
<p> {
{
mes }} </p>
</div>
console.log(app) // 打印出来看一下
new Vue({
el:'#app',
data:{
name:'刘亦菲',
mes:'我爱你'
}
})
console.log(app) // 在这里打印出来看一下
- どちらもアプリですが、2つの異なるdivに表示されるコンテンツは異なり、後者はページにレンダリングされます。マウスをその上に置くと、ページにハイライト応答が表示されます
- では、Vueはインスタンス内のデータの名前とメッセージをページにどのようにレンダリングするのでしょうか。
4つのステップ
- ラベルを探す
- データを取得する
- 二重ブレースを見つけて置き換える
- レンダリング
ラベルを探す
新しいページを再作成し、インポートされたVueファイルを削除します
let tempNode = document.querySelector('#app')
データを取得する
let data = {
name:'刘亦菲',
mes:'我爱你'
}
二重ブレースを検索し、データをテンプレートと組み合わせる
- まず、テンプレートのすべての子要素を見つけます
- 再帰が一般的に使用されます
- 実際のVueソースコードは 判定–>文字列テンプレート–>VNode–>実際のDOM
function compiler(template,data) {
let chileNodes = template.childeNode // 拿到所有子节点
}
- DOMノードは異なる値に対応し、異なるノードを表すことがわかっています
- すべての子ノードをトラバースしましょう。このノードが要素ノードである場合、ネストされたラベルである可能性があるため、再帰する必要があります
- サブエレメントがあるかどうか、補間する必要があるかどうかを検討してください。
function compiler(template,data) {
let chileNodes = template.childNodes
for(let i = 0; i < childNodes.length; i++) {
let type = childNodes[i].nodeType
if(type === 3){
// 文本节点
} else if(type === 1) {
// 元素节点
compiler(childNodes[i],data)
}
}
}
- このノードがテキストノードである場合、必要な二重ブレースがある可能性があることを意味します
// 使用正则来选择
let reg = /\{\{(.+?)\}\}/g;
if(type === 3){
let txt = childNodes[i].nodeValue // 该属性只有文本节点才有意义
txt = txt.replace(reg,function(_,g) {
let key = g.trim(); // 剔除掉不必要的东西
let value = data[key] // 把保存在data里的对应的数据赋值给选出来的值
return value // 返回被data赋值后的新的值
})
childNodes[i].nodeValue = txt
}
- 置換の使い方に慣れていない可能性があります。見てみましょう
- 一致するものは、関数の最初のパラメーターです
- 関数の戻り値は、一致したものを置き換えるために使用されます
- 関数の最初のパラメーターと後続のパラメーターは、正規表現内の対応するグループです
データをページにレンダリングする
-
現時点では、新しいテンプレートは生成されません。DOMは参照タイプであるため、ここに表示されているのは、ページ上で直接更新されたデータです。
-
テンプレートはなくなります
-
テンプレートを直接変更しないため、クローンを作成します
let generateNode = tempNode.cloneNode(true)
console.log(tempNode)
// compiler(tempNode,data)
compiler(generateNode,data)
console.log(tempNode)
app.parentNode.replaceChild(generateNode,app)
- ページへの印刷の効果を確認する
完全なコードを見てください
<body>
<div id="app">
<h1> {
{
name }} </h1>
<p> {
{
mes }} </p>
</div>
// js部分
<script>
let tempNode = document.querySelector('#app')
let data = {
name:'刘亦菲',
mes:'我爱你'
}
let reg = /\{\{(.+?)\}\}/g;
function compiler(template,data) {
let childNodes = template.childNodes
for(let i = 0; i < childNodes.length; i++) {
let type = childNodes[i].nodeType
if(type === 3) {
let txt = childNodes[i].nodeValue
txt = txt.replace(reg,function(_,g) {
let key = g.trim();
let value = data[key]
return value
})
childNodes[i].nodeValue = txt
} else if(type === 1) {
compiler(childNodes[i],data)
}
}
}
let generateNode = tempNode.cloneNode(true)
console.log(tempNode)
// compiler(tempNode,data)
compiler(generateNode,data)
console.log(tempNode)
app.parentNode.replaceChild(generateNode,app)
</script>
</body>