Custom Renderer自定义渲染器
在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>渲染