vue中-表示,深入理解vue

  vue中:表示,深入理解vue

  如果你写过vue,对v型装订这个指令一定不陌生。下面小编将从源码层面去带大家剖析一下v型装订背后的原理,需要的小伙伴可以参考下面章的具体内容

  

目录

   一、v-bind关键源码分析1、虚拟绑定化的属性统一存储在哪里:属性映射与属性列表2,解析HTML,解析出属性集合attrs,在开始回调中返回3、在开始回调中创建ASTElement,createASTElement(.属性,)4、创建后元素会生成属性列表和属性映射5、属性的数据类型定义6、绑定属性获取函数二、如何获取v型装订的值1、v-bind:键源码分析2、v-bind:标题源码分析3、v-bind:类源码分析4、五型装订:风格源码分析v绑定:text-content.prop源码分析6、虚拟绑定的修饰符骆驼. sync源码分析

  

一、v-bind关键源码分析

  

1、v-bind化的属性统一存储在哪里:attrsMap与attrsList

  p v-bind:title=vBindTitle/p

  假设为p标签v型装订化了标题属性,我们来分析标题属性在某视频剪辑软件中是如何被处理的。

  vue在拿到这个html标签之后,处理title属性,会做以下几步:

  解析HTML,解析出属性集合attrs,在开始回调中返回

  在开始回调中创建ASTElement,createASTElement(.属性,)

  创建后元素会生成属性列表和属性图

  至于创建之后是如何处理虚拟绑定:标题这种普通的属性值的,可以在下文的虚拟绑定:src源码分析中一探究竟。

  

2、解析HTML,解析出属性集合attrs,在start回调中返回

  函数handleStartTag(匹配){

  .

  const l=match.attrs.length

  常量属性=新数组(l)

  对于(设I=0;I l;i ) {

  const args=match.attrs[i]

  .

  attrs[i]={

  名称:args[1],

  value: decodeAttr(value,shouldDecodeNewlines)

  }

  }

  .

  if (options.start) {

  //在这里上传到开始函数

  options.start(标记名、属性、一元、匹配开始、匹配结束)

  }

  }

  

3、在start回调中创建ASTElement,createASTElement(... ,attrs, ...)

  //解析歌舞伎町

  parseHTML(模板,{

  .

  开始(标签、属性、一元、开始、结束){

  let element:as element=createasteelement(tag,attrs,currentParent) //注意此处的属性列表

  }

  })

  

4、创建后ASTElement会生成attrsList和attrsMap

  //创建大西洋时间元素

  导出函数createASTElement(

  标签:字符串,

  attrs: ArrayASTAttr,//属性对象数组

  parent:as element void//父元素也是元素

  ):作为元素{//返回的也是元素

  返回{

  类型:1,

  标签,

  属性列表:属性,

  attrsMap: makeAttrsMap(attrs),

  rawAttrsMap: {},

  父母,

  儿童:[]

  }

  }

  

5、attrs的数据类型定义

  //声明一个阿斯塔特属性抽象语法树对象数据类型

  声明类型ASTAttr={

  名称:字符串;//属性名

  值:任意;//属性值

  动态?布尔型;//是否是动态属性

  开始?数字;

  结束?数字

  };

  

6、绑定属性获取函数

  绑定属性获取函数getBindingAttr 和 属性操作函数 getAndRemoveAttr

  getBindingAttr及其子函数getAndRemoveAttr在处理特定场景下的v型装订十分有用,也就是"虚拟绑定如何处理不同的绑定属性"章节很有用。这里将其列举出来供下文虚拟绑定:键源码分析;虚拟绑定:src源码分析;v绑定:类源码分析;虚拟绑定:样式源码分析;虚拟绑定:数据集。支柱源码分析源码分析参照。

  导出函数getBindingAttr(

  艾尔:作为一个元素,

  名称:字符串,

  getStatic?布尔型

  ):字符串{

  常量动态值=

  getAndRemoveAttr(el,: name)

  getAndRemoveAttr(el, v-bind: name )

  if (dynamicValue!=null) {

  返回解析过滤器(动态值)

  } else if (getStatic!==假){

  const静态值=getAndRemoveAttr(El,name)

  if (staticValue!=null) {

  返回JSON.stringify(staticValue)

  }

  }

  }

  //注意:这只是从数组(属性列表)中删除了属性,所以它

  //不会被过程属性处理。

  //默认情况下,它不会将其从映射(属性图)中移除,因为映射是

  编译期间需要。

  导出函数getAndRemoveAttr(

  艾尔:作为一个元素,

  名称:字符串,

  removeFromMap?布尔型

  ):字符串{

  让瓦尔

  if ((val=el.attrsMap[name])!=null) {

  const list=el.attrsList

  对于(设i=0,l=list.lengthI li ) {

  如果(列表[我].name===name) {

  list.splice(i,1) //从属性列表删除一个属性,不会从属性图删除

  破裂

  }

  }

  }

  if (removeFromMap) {

  删除埃尔。属性地图[名称]

  }

  返回值

  }

  

二、如何获取v-bind的值

  以下面代码为例从源码分析某视频剪辑软件是如何获取v型装订的值。

  会从记下几个场景去分析:

  常见的键属性

  绑定一个普通超文本标记语言属性:标题

  绑定班级和风格

  绑定一个文档对象模型属性:文本内容

  vBind:{

  key: new Date(),

  标题:"这是一个超文本标记语言属性v-bind”,

  类:" { borderRadius: isBorderRadius } "

  样式:" { minHeight: 100 px ,maxHeight} "

  文本内容:"你好,vue v-bind "

  }

  差异

  v-bind:key=vBind.key

  v-bind:title=vBind.title

  v-bind:class=vBind.class

  v-bind:style=vBind.style

  绑定:文本内容。prop= vbind。文本内容

  /

  /div

  

1、v-bind:key源码分析

  函数processKey (el) {

  const exp=getBindingAttr(el, key )

  if(exp){

  .

  el.key=exp

  }

  }

  过程键函数中用到了getBindingAttr函数,由于我们用的是v-bind,没有用:所以const动态值=getAndRemoveAttr(El, v-bind: key );getAndRemoveAttr(el, v-bind:key )函数到属性图中判断是否存在v-bind:key ,取这个属性的值赋为英国压力单位并从从属性列表删除,但是不会从属性图删除,最后将 v-bind:key 的值,也就是英国压力单位作为动态值,之后再返回解析过滤后的结果,最后将结果设置为过程键中将元素的关键属性。然后存储在片段中,至于片段是什么,在上面的源码中可以看到。

  

2、v-bind:title源码分析

  标题是一种"非某视频剪辑软件特殊的"也就是普通的超文本标记语言属性。

  函数处理属性(el){

  const list=el.attrsList

  .

  if (bindRE.test(name)) { //v-bind

  name=name.replace(bindRE,)

  值=parseFilters(值)

  .

  addAttr(el,name,value,list[i],)

  }

  }

  出口常量宾德雷=/^:^\.^v-bind:/

  导出函数addAttr(El:as元素,name: string,value: any,range?范围,动态?布尔){

  常量属性=动态

  ?(El。动态属性 (El。动态属性=[]))

  :(el.attrs (el.attrs=[]))

  attrs。push(rangesettitem({ name,value,dynamic },range))

  el.plain=false

  }

  通过阅读源码我们看出:对于原生的属性,比如标题这样的属性,vue会首先解析出名字和值,然后再进行一系列的是否有修饰语的判断(修饰符的部分在下文中会详细讲解),最终向更新元素的attrs,从而属性列表和属性图也同步更新。

  

3、v-bind:class源码分析

  钢性铸铁的班级在前端开发的展现层面,是非常重要的一层。因此某视频剪辑软件在对于班级属性也做了很多特殊的处理。

  函数转换节点(El:as元素,options: CompilerOptions) {

  const warn=选项。警告 基本警告

  const static Class=getAndRemoveAttr(El, Class )

  if (staticClass) {

  埃尔。静态类=JSON。stringify(静态类)

  }

  const class binding=getBindingAttr(El, class ,false /* getStatic */)

  如果(类绑定){

  el.classBinding=classBinding

  }

  }

  在跨节函数中,会通过getAndRemoveAttr得到静态类,也就是foo在getBindingAttr得到绑定的类,也就是v-bind:class=vBind.class 即v-bind:class= { borderRadius:isBorderRadius } ,将元素的类绑定赋值为我们绑定的属性供后续使用。

  

4、、v-bind:style源码分析

  风格是直接操作样式的优先级仅次于重要的,比班级更加直观的操作样式的一个超文本标记语言属性。某视频剪辑软件对这个属性也做了特殊的处理。

  函数转换节点(El:as元素,options: CompilerOptions) {

  const warn=选项。警告 基本警告

  const static Style=getAndRemoveAttr(El, Style )

  if (staticStyle) {

  埃尔。静态风格=JSON。stringify(解析样式文本(静态样式))

  }

  const style binding=getBindingAttr(El, style ,false /* getStatic */)

  if (styleBinding) {

  el.styleBinding=styleBinding

  }

  }

  在transfromNode函数中,你会通过getAndRemoveAttr得到静态样式,即style= { fontsize: 12px } ;获取getBindingAttr中的绑定样式,即v-bind:style=vBind.style ,即v-bind: class={minheight: 100 px ,maxHeight} ,其中maxHeight是一个变量,它将ASTElement的styleBinding赋值为我们的绑定属性,以备后续使用。

  

5、v-bind:text-content.prop源码分析

  文本是DOM对象的固有属性,因此可以通过prop来识别。如果我们想直接通过vue设置一个DOM prop,可以在DOM节点上修改。

  下面我们来看源码。

  函数处理属性(el) {

  const list=el.attrsList

  .

  if (bindRE.test(name)) { //v-bind

  if(修饰符){

  if (modifiers.prop!isDynamic) {

  name=camelize(名称)

  if(name=== innerHtml )name= innerHtml

  }

  }

  if (modifiers modifiers.prop) {

  addProp(el,name,value,list[i],isDynamic)

  }

  }

  }

  导出函数add prop(El:as element,name: string,value: string,range?范围,动态?布尔){

  (el.props (el.props=[]))。push(rangesettitem({名称,值,动态},范围))

  el.plain=false

  }

  道具?ArrayASTAttr

  从上面的源代码我们可以看到,v-bind中的text-content:text-content . prop一开始是驼峰化成textContent的(这是因为DOM属性都是驼峰格式),vue也有兼容innerHtml错误写法的意图。然后通过prop identifier将textContent属性添加到ASTElement的props中,这里的props本质上也是一个ASTAttr。

  有一个很值得思考的问题:为什么要这么做?HTML属性和HTML属性的异同?

  没有HTML属性可以直接修改DOM的文本内容,需要单独标识。

  比通过js手动更新dom的文本节点更快,省去了查询DOM然后替换文本内容的步骤。

  你可以在标签上看到我们有v-bind的哪个属性,非常直观。

  其实v-bind:title可以理解为v-bind:title.attr,v-bind:text-content.prop,但是vue默认了HTML属性,没有修饰符。

  

6、v-bind的修饰符.camel .sync源码分析

  骆驼只是驼峰,很简单。酪同步没那么简单。它将被扩展到一个更新父组件绑定值的v-on监听器。

  其实一开始我也是被这个搞得不知所措。sync修饰符,但是在仔细阅读。同步的成分并结合实际工作,你会发现它的威力。

  父母

  v-bind:foo=parent.foo

  v-on:update foo= parent . foo=$ event

  /父母

  在vue中,父组件传递给子组件的props不能被子组件直接通过this.props.foo=newFoo修改。除非我们在这个组件中。$emit(updateFoo ,newFoo),然后使用v-on作为父组件中的事件来侦听updateFoo事件。为了提高可读性,可以将$emit的名称改为update:foo,然后改为v-on:update:foo。

  有没有更简洁的写法?那是我们的。我是同步操作员。它可以缩写为:

  Parent v-bind:foo . sync= Parent . foo /Parent

  那就通过这个。子组件中的$emit(update:foo ,new foo);要触发,注意这里的事件名必须是update:xxx的格式,因为在vue的源代码中,使用了的属性。sync修改器将自己生成一个v-on:update:xxx监视器。

  下面我们来看源码:

  if (modifiers.camel!isDynamic) {

  name=camelize(名称)

  }

  if (modifiers.sync) {

  syncGen=genAssignmentCode(值,` $event `)

  如果(!isDynamic) {

  addHandler(el, update:${camelize(name)} `,syncGen,null,false,warn,list[i])

  //Hyphenate是一个断字函数,其中camelize是一个驼峰函数。

  if(连字符(名称)!==camelize(name)) {

  addHandler(el, update:${hyphenate(name)} `,syncGen,null,false,warn,list[i])

  }

  }否则{

  //带有动态事件名称的处理程序

  addHandler(el,` update: (${name})`,syncGen,null,false,warn,list[i],true)

  }

  }

  通过阅读源代码我们可以看到,对于v-bind:foo.sync的属性,vue会判断该属性是否是动态的。如果不是动态属性,先给它加一个驼峰监视器,再给它加一个连字符监视器,比如v-bind:foo-bar.sync,first v-on:update:fooBar,然后v-on:update:foo-bar。通过addHandler添加V-on监控。如果是动态属性,就不会驼峰,也不会断字。通过addHandler老老实实的听那个动态属性的事件(el,update:${name},).

  一句话,同步:sync是语法上的糖。将v-bind和v-on简化为v-bind.sync和this。$emit(update:xxx )。我们为子组件提供了一种快速更新父组件数据的方法。

  关于带你了解vue中v-bind的这篇文章到此为止。有关vue中v-bind的更多信息,请搜索我们以前的文章或继续浏览下面的相关文章。希望你以后能支持我们!

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: