在vue3.0中,為了更好的實現多平台應用,將渲染器的創建函數createRenderer方法單獨分離出來,這個API可以用來自定義渲染邏輯,將Virtual DOM渲染為web平台真實DOM
作用:實現脫離於源碼之外的各種跨平台操作
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <script src="https://unpkg.com/vue@next"></script> </head> <body> <div id="app"></div> <script> console.log(Vue) </script> </body> </html>
我們可以看到控制台輸出
Vue是一個對象,暴露了很多的api
<body> <div id="app"> {{count}} </div> <script> // console.log(Vue) let {createApp} =Vue; //創建app的實例 createApp({ data(){ return { count:2 } } }).mount("#app") //掛載到#app上 </script> </body>
此時我們打開瀏覽器就可以看到
我們也可以渲染組件
<body> <div id="app"> {{count}} <fun></fun> //調用組件並渲染 </div> <script> // console.log(Vue) let {createApp} =Vue; //創建app的實例 createApp({ data(){ return { count:2 } } }).component('fun',{ //創建一個組件 template:"<div>fun</div>" }).mount("#app") </script> </body>
手寫簡單的vue初始化操作
1>掛載根組件
//創建app的實例 接收的是根組件的配置 Vue.createApp({ data(){ return { count:2 } } }).mount("#app")
2>創建一個Vue
// 創建Vue let Vue={ // Vue這個對象提供一個createApp的方法,接收一個初始化的選項 createApp(options){ // 真正用來創建app的是renderer渲染器 return renderer.createApp(options) } }
3>創建renderer
//創建一個renderer的實例來自一個工廠函數createRenderer 參數是dom操作 let renderer=createRenderer({ createElement(tag){ return document.createElement(tag) }, insert(child,parent){ parent.appendChild(child) } })
4>創建createRenderer 工廠函數
let createRenderer=({createElement,insert})=>{ // 把vnode渲染為真是的dom let render=(vnode,container)=>{ //返回真正的渲染器 //解析vnode變成真是的dom let child=createElement(vnode.tag) if(typeof vnode.children==='string'){ child.textContent=vnode.children; } //省略了多個子元素的情況 //追加節點 insert(child,container) } // 返回真正的渲染器 return { render, createApp:createAppAPI(render) } }
5>創建真正的createApp方法的createAppAPI
let createAppAPI=(render)=>{ //返回一個真正的createApp函數 return function createApp(rootComponent){ //核心創建app實例 //app實例需要定義mount方法 use component方法等方法 let app={ //rootcontainer是一個宿主元素 mount(rootcontainer){ //調用傳進來的render函數 //手動創建一個虛擬dom let vnode ={ tag:'h3', props:null, children:rootComponent.data().count+'' } render(vnode,document.querySelector(rootcontainer)) } } return app } }
此時節點就以<h3>渲染