IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> vue模板编译 -> 正文阅读

[JavaScript知识库]vue模板编译

提示:本博客用于分享本人学习心得,如有错误之处欢迎大家指出。


前言

我们在用vue进行开发的时候,虽然模板是vue开发中最常用的部分,但是大多数人对他可能不是很了解,今天我们就一起来探讨以下,模板是什么?模板是如何编译的?

编译模板是什么?

  • 模板不是html,模板有表达式、插值、能实现判断、循环
  • html是标签语言,只有js代码才能实现判断、循环
  • 因此,模板一定是转换为某种js代码,即编译模板

编译模板的过程?

1. vue-template-compiler

vue中是通过vue-template-compiler将模板编译成render函数,然后执行render函数生成vnode,我们来看下面的内容,看一下vue-template-compiler是怎样将不同的模板编译的。

(1)插值

// index.js
const compiler = require('vue-template-compiler')

// 插值
const template = "<p>{{message}}</p>"

const res = compiler.compile(template)
console.log(res.render)

然后执行node index.js,输出结果如下:

with(this){return _c('p',[_v(_s(message))])}

在vue中,上面with里的this代表的是vue实列

在vue源码中
_c 代表的是 createElement
_v 代表的是 createTextVNode
_s 代表的是 toString

// vue源码
vm._c = (a, b, c, d) => createElement(vm, a, b, c, d, false)
export function installRenderHelpers (target: any) {
  target._o = markOnce
  target._n = toNumber
  target._s = toString
  target._l = renderList
  target._t = renderSlot
  target._q = looseEqual
  target._i = looseIndexOf
  target._m = renderStatic
  target._f = resolveFilter
  target._k = checkKeyCodes
  target._b = bindObjectProps
  target._v = createTextVNode
  target._e = createEmptyVNode
  target._u = resolveScopedSlots
  target._g = bindObjectListeners
}

因此,with(this){return _c(‘p’,[_v(_s(message))])} 就可以看成是下面这种形式

// message就是vue实列下的message->this.message(vm.message)
with(this){return createElement('p',[createTextVNode(toString(message))])}

(2)表达式

...
const template = "<p>{{flag ? message : 'message test'}}</p>"
...

然后执行node index.js,输出结果如下:

with(this){return _c('p',[_v(_s(flag ? message : 'message test'))])}

(3)动态属性

...
const template = "<div class='container'><img :src='imgSrc'></img></div>"
...

然后执行node index.js,输出结果如下:

// imgSrc: this.imgSrc
with(this){
  return _c('div',{staticClass:"container"},[_c('img',{attrs:{"src":imgSrc}})])
}

(4)条件

...
const template = 
	`<div>
		<div v-if="flag === A">A</div>
		<div v-else>B</div>
	</div>`
...

然后执行node index.js,输出结果如下:

with(this){return _c('div',[(flag === A)?_c('div',[_v("A")]):_c('div',[_v("B")])])}

flag===A创建A节点,否则创建B节点

(5)循环

...
const template = 
	`<ul><li v-for="item in list" :key="item.id">{{item.name}}</li></ul>`
...

然后执行node index.js,输出结果如下:

// list: this.list
with(this){
	return _c(
		'ul',_l(
			(list),function(item){
				return _c(
					'li',{key:item.id},[_v(_s(item.name))])}),0)}

_s 代表的是 renderList


(6)事件

...
const template = `<div @click="handleClick"></div>`
...

然后执行node index.js,输出结果如下:

// handleClick: this.handleClick
with(this){return _c('div',{on:{"click":handleClick}})}

(7)v-model

...
const template = `<input type="text" v-model="value" />`
...

然后执行node index.js,输出结果如下:

// value: this.value
with(this){
	return _c(
		'input',{
			directives:[
				{name:"model",rawName:"v-model",value:(value),expression:"value"}
			],
			attrs:{"type":"text"},
			domProps:{"value":(value)},
			on:{
				"input":function($event){
					if($event.target.composing)return;
					value=$event.target.value
				}
			}
		}
	)
}

在模板编译的时候,给input框监听了input事件, value=$event.target.value将当前的input值赋值给value变量,value指的是vm.value,然后 domProps:{“value”:(value)} 将value值显示出来


2. vue组件可用render代替template

通过上面的内容,我们知道了vue是将模板编译成render函数,因此,我们也可以用render代替template,如下代码:

// template
Vue.component('Test', {
	template: `<h1>xxx<h1>`
})

// render
Vue.component('Test', {
	render: function(createElment) {
		return createElment('h1',{}, 'xxx')
	}
})

编译模板的结果?

  1. 模板编译为render函数,执行render函数返回vnode
  2. 基于vnode再执行patch和diff
  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2021-08-11 12:13:37  更:2021-08-11 12:17:45 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/28 0:58:05-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码