Vue 3.0的attribute强制行为理解学习
作者:cutekio 发布时间:2024-05-05 09:22:25
理解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。常见的示例包括 class
、style
和 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. 这些属性值的可能情况是有限的
值得一提的是draggable
和contenteditable
都是枚举属性,虽然它们看起来像是布尔类型。
那么这两种类型的属性,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不再强制变更属性值,这样有了所见即所得的效果,可以解除正常四维对于这些诡异行为的困惑。
至于为什么要这样做,仁者见仁,智者见智。
来源:https://juejin.cn/post/7125659129682591774


猜你喜欢
- matplotlib窗口图标默认是matplotlib的标志,如果想修改怎么改呢?由于我选择的matplotlib后端是PyQT5,直接查看
- 其中 offset and fetch 最重要的新特性是 用来 分页,既然要分析 分页,就肯定要和之前的分页方式来比较了,特别是 Row_N
- 摘要:将英文单词首字母变成大写是一个古老的话题,很常用,也很简单。不过如何用更简单的方式批量完成这个工作,则有很多学问,不想来看看吗!将英文
- 主要是要注意权限的问题,一般做发布/订阅,建议你做如下准备工作: 1.发布服务器,订阅服务器都创建一个同名的windows用户,并设置相同的
- 前段时间冷空气突袭的时候,据说郊区密云的雪积得挺厚,但北京城内除了飘了一点小雪粒,毫无动静。应该是气温过高所致,我在慈云寺桥附近拍下的照片可
- 很多jsp程序员都遇到过这样的情况,jsp页面传递参数到servlet,只要参数有中文就是乱码,且大多数是??????乱码,尝试了网上比较普
- 前言Tkinter 是 Python 的标准 GUI 库。Python 使用 Tkinter 可以快速的创建 GUI 应用程序。由于 Tki
- 本文实例讲述了Python创建系统目录的方法。分享给大家供大家参考。具体如下:Python2 mkdir在没有上级目录时创建会失败.该方法可
- 一、基本使用最近研究了一下 el-upload组件 踩了一些小坑 写起来大家学习一下很经常的一件事情 经常会去直接拷贝 elem
- throttle我们这里说的throttle就是函数节流的意思。再说的通俗一点就是函数调用的频度控制器,是连续执行时间间隔控制。主要应用的场
- 最近项目中使用了vue-router的addRoutes这个api,遇到了一个小坑,记录总结一下。场景复现:做前端开发的同学,大多都遇到过这
- Pandas是Python中最流行的数据分析和处理工具之一,它提供了一个名为DataFrame的数据结构,可以被认为是一个二维表格或电子表格
- 一、创建TensorRT有以下几个步骤:1.用TensorRT中network模块定义网络模型2.调用TensorRT构建器从网络创建优化的
- 要下午传上的.结果事一多,忘记了.好不容易回来 . 这个和 dh20156 的那个,是差不多的。 找不到合适的图片,也
- 今天开始学习数据库,由于我对微软不怎么感冒,所以就不用他家的产品了本来想装ORACLE的,不过太大了,看着害怕对于我这种喜欢一切从简的人来说
- MySQL查询字段为空或者为null判断为nullselect * from table where column is nul
- 一、背景1.项目描述你拥有一个超市(Supermarket Mall)。通过会员卡,你用有一些关于你的客户的基本数据,如客户ID,年龄,性别
- Graphical User Interface,简称 GUI,又称图形化用户接口,所谓的GUI编程,指的是用户不需要输入代码指令,只通过图
- 1.单继承父类也叫基类子类也叫派生类如下所示,继承的关系:继承的书写格式:class 子类(父类):方法实例:class Animal: &
- 首先下载源tar包可利用linux自带下载工具wget下载,如下所示:wget http://www.python.org/ftp/pyth