Vue 3.0的attribute强制行为理解学习

 更新时间:2022年08月11日 15:37:51   作者:cutekio  
这篇文章主要为大家介绍了Vue 3.0的attribute强制行为理解学习,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

理解property和attribute

这个要看具体的语境了。不过我们可以从词源的角度来区分一下这两者:

property

形容词

property的词源可追溯到proper,意为合适的,适当的。

短语示例:

  • a proper job 一份合适(自己的)工作

名词

proper加上ty后缀变为名词prproperty,意为特性

短语示例:

  • chemical property 化学性质,比如酒精易挥发的化学性质。

attribute

an abstraction belonging to or characteristic of an entity

对实体的抽象或者特征描述。

比如,我们谈论一条鱼这个实体,说这条鱼具有对称性,此时我们的意思是这条鱼具有这个属性,而不是说只有这条鱼具有对称性。

这样总结下来,property是attribute的子集,property代表专属于一个实体的属性。

但是在编码的过程中,程序员总有抽象不完善的情况,这也是为什么property和attribute会混淆的原因。

vue3中的property和attribute

在vue3中property也就是props所定义的一个组件的属性,这些属性会由组件接收,同时在接收的时候会对其进行校验数据类型和值的正确性。

如下一段代码很好地解释了vue3中什么是property:

class User {
  _name
  set name(name) {
      if(!name) {
        alert('名称不能为空')
      }
      this._name = name
  }
  get name() {
      return this._name
  }
}

而attribute则更像没人管的野孩子。下面一段介绍是vue3对非prop的attribute的描述:

一个非 prop 的 attribute 是指传向一个组件,但是该组件并没有相应 props 或 emits 定义的 attribute。常见的示例包括 classstyle 和 id attribute。可以通过 $attrs property 访问那些 attribute。

xml中的属性节点

html所构成的dom树,元素节点上的attribute的类型是属性节点,也是树的一个level。

dom api在处理这些属性时,如果是对象的property,则会交由对象的property处理器去处理,而如果对象没有相应的property,则会将由xml解析出来的attribute添加到attributes这个属性上去。

vue3.0的attribute强制行为

接触过强类型语言比如Java的都会知道【强制类型转换】这样一个术语。

int i = (int)(1.23);

vue框架在编译模板代码时也会进行类似的【强制类型转换

模板代码如下:

<template>
    <div id="draggable" draggable />
</template>

在vue2中,上述的模板会被渲染为:

<div id="draggable" draggable="true" />

在vue3中,上述的模板会被渲染为:

<div id="draggable" draggable=""></div>

也就是说vue3中没有强制行为,你在模板中看到的就是最终的渲染结果。

源代码分析

function setAttr(el: Element, key: string, value: any, isInPre?: any) {
  if (isInPre || el.tagName.indexOf('-') > -1) {
    baseSetAttr(el, key, value)
  } else if (isBooleanAttr(key)) {
    // set attribute for blank value
    // e.g. <option disabled>Select one</option>
    if (isFalsyAttrValue(value)) {
      el.removeAttribute(key)
    } else {
      // technically allowfullscreen is a boolean attribute for <iframe>,
      // but Flash expects a value of "true" when used on <embed> tag
      value = key === 'allowfullscreen' && el.tagName === 'EMBED' ? 'true' : key
      el.setAttribute(key, value)
    }
  } else if (isEnumeratedAttr(key)) {
    el.setAttribute(key, convertEnumeratedValue(key, value))
  } else if (isXlink(key)) {
    if (isFalsyAttrValue(value)) {
      el.removeAttributeNS(xlinkNS, getXlinkProp(key))
    } else {
      el.setAttributeNS(xlinkNS, key, value)
    }
  } else {
    baseSetAttr(el, key, value)
  }
}
function baseSetAttr(el, key, value) {
  if (isFalsyAttrValue(value)) {
    el.removeAttribute(key)
  } else {
    // #7138: IE10 & 11 fires input event when setting placeholder on
    // <textarea>... block the first input event and remove the blocker
    // immediately.
    /* istanbul ignore if */
    if (
      isIE &&
      !isIE9 &&
      el.tagName === 'TEXTAREA' &&
      key === 'placeholder' &&
      value !== '' &&
      !el.__ieph
    ) {
      const blocker = e => {
        e.stopImmediatePropagation()
        el.removeEventListener('input', blocker)
      }
      el.addEventListener('input', blocker)
      // $flow-disable-line
      el.__ieph = true /* IE placeholder patched */
    }
    el.setAttribute(key, value)
  }
}
export const convertEnumeratedValue = (key: string, value: any) => {
  return isFalsyAttrValue(value) || value === 'false'
    ? 'false'
    : // allow arbitrary string value for contenteditable
    key === 'contenteditable' && isValidContentEditableValue(value)
    ? value
    : 'true'
}
export const isBooleanAttr = makeMap(
  'allowfullscreen,async,autofocus,autoplay,checked,compact,controls,declare,' +
    'default,defaultchecked,defaultmuted,defaultselected,defer,disabled,' +
    'enabled,formnovalidate,hidden,indeterminate,inert,ismap,itemscope,loop,multiple,' +
    'muted,nohref,noresize,noshade,novalidate,nowrap,open,pauseonexit,readonly,' +
    'required,reversed,scoped,seamless,selected,sortable,' +
    'truespeed,typemustmatch,visible'
)
export const isEnumeratedAttr = makeMap('contenteditable,draggable,spellcheck')

vue2在解析模板之后,得到了关于dom结构的js对象描述。

通过调用dom api来创建节点并为节点添加属性【setAttribute】。

大致分为:

  • 布尔类型属性

The values "true" and "false" are not allowed on boolean attributes. To represent a false value, the attribute has to be omitted altogether.

也就是说布尔类型的值如果没有这个属性则是false,有了这个属性,则不论其属性值是false还是true,都会被浏览器解析为true.

  • 枚举属性

Some attributes, called enumerated attributes, take on a finite set of states. 这些属性值的可能情况是有限的

值得一提的是draggablecontenteditable都是枚举属性,虽然它们看起来像是布尔类型。

那么这两种类型的属性,vue2.0是怎么处理的呢?

  • 首先vue的自定义组件是不在这两种处理范畴之内的。
  • 对于布尔类型值,vue模板则不会一棍子打死,如果真的是falsy值,vue框架会自动帮你去除掉这个属性,调用removeAttribute方法。至于allowfullscreen这个虽然是一个boolean类型的值,但用在embed标签上,则要求是true
  • 其次,如果是枚举类型的值,则会对枚举类型的值进行转化。如果是falsy的值,则为'false'。可枚举类型的值实际上就3个contenteditable,draggable,spellcheck,如果是contenteditable则按照所见即所得的原则处理,其他都强制转换为true
  • 最后,不在上述情况的属性,则是如果是falsy的值,则移除,其他的值则是原样设置。

vue3.0的变化

  • 删除枚举 attribute 的内部概念,并将这些 attribute 视为普通的非布尔 attribute
  • 重大改变:如果值为布尔值,则不再删除 attribute false。相反,它被设置为 attr=“false”。移除 attribute,使用 null 或者 undefined

vue3不再强制变更属性值,这样有了所见即所得的效果,可以解除正常四维对于这些诡异行为的困惑。

至于为什么要这样做,仁者见仁,智者见智。

以上就是Vue 3.0的attribute强制行为理解学习的详细内容,更多关于Vue attribute强制行为的资料请关注脚本之家其它相关文章!

相关文章

  • Vue组件中的data必须是一个function的原因浅析

    Vue组件中的data必须是一个function的原因浅析

    这篇文章主要介绍了Vue组件中的data必须是一个function的原因浅析,本文通过实例代码给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下
    2018-09-09
  • vue 中url 链接左边的小图标更改问题

    vue 中url 链接左边的小图标更改问题

    这篇文章主要介绍了vue 中url 链接左边的小图标更改问题,本文给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下
    2019-12-12
  • vue router-link传参以及参数的使用实例

    vue router-link传参以及参数的使用实例

    下面小编就为大家带来一篇vue router-link传参以及参数的使用实例。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-11-11
  • vue 禁止重复点击发送多次请求的实现

    vue 禁止重复点击发送多次请求的实现

    本文主要介绍了vue 禁止重复点击发送多次请求的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-03-03
  • vue+element-ui中form输入框无法输入问题的解决方法

    vue+element-ui中form输入框无法输入问题的解决方法

    很多初次接触element-ui的同学,在用到element form组件时可能会遇到input框无法输入文字的问题,下面这篇文章主要给大家介绍了关于vue+element-ui中form输入框无法输入问题的解决方法,需要的朋友可以参考下
    2023-04-04
  • vue中 根据判断条件添加一个或多个style及class的写法小结

    vue中 根据判断条件添加一个或多个style及class的写法小结

    这篇文章主要介绍了vue中 根据判断条件添加一个或多个style及class的写法,文中给大家补充介绍了关于vue里:class的使用结合自己的实现给大家讲解,需要的朋友可以参考下
    2023-03-03
  • vue基于Element构建自定义树的示例代码

    vue基于Element构建自定义树的示例代码

    本篇文章主要介绍了vue基于Element构建自定义树的示例代码,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-09-09
  • 基于Vue实现简单的贪食蛇游戏

    基于Vue实现简单的贪食蛇游戏

    贪食蛇是一个非常经典的游戏, 在游戏中, 玩家操控一条细长的直线, 它会不停前进, 玩家只能操控蛇的头部朝向, 一路拾起触碰到之物。本文将用Vue实现这一游戏,感兴趣的可以尝试一下
    2022-04-04
  • iview table render集成switch开关的实例

    iview table render集成switch开关的实例

    下面小编就为大家分享一篇iview table render集成switch开关的实例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-03-03
  • vuex与组件联合使用的方法

    vuex与组件联合使用的方法

    Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。这篇文章主要介绍了vuex与组件联合使用的方法,需要的朋友可以参考下
    2018-05-05

最新评论