作为 attribute 和 property 的 value 及 Vue.js 的相关处理

attribute 和 property 是 Web 开发中,比较容易混淆的概念,而对于 value,因其特殊性,更易困惑,本文尝试做一下梳理和例证


attribute 和 property 的概念

简单的说,attribute 是元素标签的属性,property 是元素对象的属性,例如:

<input id="input" value="test value">
<script>
let input = document.getElementById('input');
console.log(input.getAttribute('value')); // test value
console.log(input.value); // test value
</script>
  • input 的 value attribute 是通过标签里的 value=“test value” 定义的,可以通过input.getAttribute(‘value’) 获取,可以通过 input.setAttribute(‘value’, ‘New Value’) 更新
  • input 的 value property 可通过 input.value 获取和更新,初始值是与 attribute 中的赋值一致的

attribute 和 property 的绑定

如果在最开始的时候,更新 attribute value 的值,property 的值也会随之改变

但是更新 property value 的值(在文本框输入或给 input.value 赋新值 ),attribute 的值不会随之改变,而且此时再更新 attribute 的值,property 的值也不再随之改变,如此动画所示,也可访问此页面尝试进行操作

这其实是脏值标记(dirty value flag)在起作用,dirty value flag 的初始值为 false,即 attribute value 的更新默认会改变对应的 property value,但是一旦用户交互修改了 property value,dirty value flag 的值就变为 true,即attribute value 的更新就不会改变对应的 property value 了

所以在实际项目中,我们一般都是在处理作为 property 的 value


Vue.js 对 value 的处理

一般情况使用 :value

Vue.js 的 v-bind,一般情况下是在处理 attribute,如果要作为 property 处理的话,需要加上 .prop

不过 v-bind:value 却大都默认为处理 property 值,因为被强制转化了,例如:

<input id="input" :value="'test value'" >
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
let input = new Vue({el: '#input',mounted () {console.log(this.$el.getAttribute('value')); // nullconsole.log(this.$el.value); // test valueconsole.log(this._vnode.data) // {attrs: {id: "input"}, domProps: {value: "test value"}}}
});
</script>

可见,Vue.js 将 value 作为 VNode 的 data 中的 domProps 的属性,而不是 attrs 的属性,所以挂载后会成为作为 property 的 value

在 Vue.js 源码中,强制转化 property 的处理如下:

// src/compiler/parser/index.js
function processAttrs (el) {...if ((modifiers && modifiers.prop) || (!el.component && platformMustUseProp(el.tag, el.attrsMap.type, name))) {addProp(el, name, value, list[i], isDynamic)} else {addAttr(el, name, value, list[i], isDynamic)}

其中 platformMustUseProp 在 web 平台的定义如下:

// src/platforms/web/util/attrs.js
const acceptValue = makeMap('input,textarea,option,select,progress')
export const mustUseProp = (tag: string, type: ?string, attr: string): boolean => {return ((attr === 'value' && acceptValue(tag)) && type !== 'button' ||(attr === 'selected' && tag === 'option') ||(attr === 'checked' && tag === 'input') ||(attr === 'muted' && tag === 'video'))
}

由上可知,类型不为 button 的 input, textarea, option, select, progress 的 value 会强制作为 property,而不需要设置为 :value.prop

例如 textarea 标签,其本身其实并不支持 value attribute,所以以下代码中的 value 的值并不会显示在多行文本框中

<textarea value="test value"></textarea>

复制代码但是在 Vue.js 中, 以下代码能成功绑定到 value property 并显示在多行文本框中

<textarea :value="'test value'"></textarea>

特殊情况使用 :value.prop

以上 Vue.js 源码需要注意的还有,强制作为 property, 还要满足 !el.component,即不为动态组件,因为动态组件的 el.component 的值为其 is attribute 的值

即动态组件的的 v-bind 默认都是作为 attribute的,如果要作为 property,就要使用 .prop,例如:

<div id="app"><component :is="element" :value.prop="'test value'"></component><button @click="change">Change</button>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
let app = new Vue({el: '#app',data: {element: 'input'},methods: {change () {this.element = 'input' === this.element ? 'textarea' : 'input';}}
});
</script>

如果以上 component 中,删除 :value.prop 的 .prop,切换到 textarea 时,其值就不会显示在多行文本框中,可以在此页面点击切换标签查看


总结

  • 作为 attribute 和 property 的 value 的绑定关系会在用户交互更新值后失效
  • Vue.js 一般使用 :value 即可让 value 作为 property
  • Vue.js 动态模版需要使用 :value.prop 才可让 value 作为 property

vue中的attribute 和 property 是什么意思相关推荐

  1. VUE中出现 Cannot read property ‘length‘ of undefined 的错误

    问题描述: Cannot read property 'length' of undefined @Override 在做项目时遇到了length的报错.不影响其他东西,只是看着很难受 原因分析: 因 ...

  2. java中类图概念,程序员眼中的UML(4)--类图释疑之一,Attribute和Property之区别

    程序员眼中的UML(4) --类图释疑之一,Attribute和Property之区别 上一篇中提出了很多问题,其中最令人费解的可能就是Attribute和Property之区别了吧.我在网络上寻找良 ...

  3. 关于vue中Cannot read property 'length' of undefined 导致:数据不显示问题【自己经验参考】

    关于vue中Cannot read property 'length' of undefined 导致:数据不显示问题 导致:数据不能及时,或者不渲染的问题? 项目备忘: 经过排查,发现是自己代码中忽 ...

  4. vue中的props对象

    vue中的props对象 1.props对象的定义 props其实是properties的缩写,props对象是用来定义属性的.props对象可以接受数组形式的参数又或者是对象形式的参数. 数组形式 ...

  5. vue中prop的用法

    prop的大小写 HTML 中的 attribute 名是大小写不敏感的,所以浏览器会把所有大写字符解释为小写字符.这意味着当你使用 DOM 中的模板时,camelCase(驼峰命名法)的 prop ...

  6. vue中 props的基本介绍

    一.Prop 的大小写 (camelCase vs kebab-case) HTML 中的 attribute 名是大小写不敏感的,所以浏览器会把所有大写字符解释为小写字符.这意味着当你使用 DOM ...

  7. vue中的render函数、h()函数、函数式组件

    一.什么是render 官网:用于编程式地创建组件虚拟 DOM 树的函数. 在我们使用webpack脚手架创建项目时,都能在main.js中看到一个render函数 import Vue from ' ...

  8. 在Vue 中使用 JSX 语法

    Vue 中构建虚拟DOM可以直接使用渲染函数构建虚拟Dom,正常情况下用render函数的参数createElement方法构建虚拟Dom的语法比较繁琐,更方便的是用更接近于模板的JSX语法. Vue ...

  9. vue和react相同点_我在React和Vue中创建了相同的应用程序。 这是区别。

    vue和react相同点 by Sunil Sandhu 由Sunil Sandhu 我在React和Vue中创建了相同的应用程序. 这是区别. (I created the same app in ...

  10. 深刻理解Vue中的组件

    今天看了下Vue官网上关于组件的教程,感觉内容还挺多,现在把组件中基本的知识梳理一下. 组件的基本使用 注册组件 注册组件就是利用Vue.component()方法,先传入一个自定义组件的名字,然后传 ...

最新文章

  1. Java程序员必须了解的JVM性能调优知识,全都在这里了
  2. 【BZOJ 2298】 2298: [HAOI2011]problem a (DP)
  3. 日本Blogger专用电脑
  4. DevOps vs. Agile:它们有什么共同点?
  5. linux入门_linux入门-常用命令的使用
  6. 计算机编程ebcdic码,EBCDIC 与 ASCII 编码相互转换
  7. Spring Cloud核心组件原理分析
  8. jinja Macros
  9. 9-15 redis-trib构建集群
  10. matlab sparse()
  11. CVPR 2022 | 即插即用!南洋理工商汤开源SAM-DETR: 利用语义对齐匹配实现快速收敛的DETR...
  12. php vld 安装,PHP性能之语言性能优化:vld
  13. Github上开源的数据可视化工具及作品分享(一)
  14. Vue-跟着李南江学编程
  15. springboot源码解析,kafkaredis面试题
  16. 关于汉字转拼音的Pinyin4j工具使用
  17. android 黑屏定位,如何将黑屏Android修复为正常
  18. Xftp的下载和安装教程
  19. 支付项目:9、购物车模块
  20. Linux——shell脚本

热门文章

  1. SpringBoot入门,快速搭建简单Web应用环境
  2. 小程序使用腾讯视频插件及插件未授权使用
  3. 小招喵喜欢吃喵粮(贪心、二分查找)
  4. mysql rename数据库_为什么现在MySQL无法重命名数据库?
  5. php框架 f,ShuipFCMS: ShuipFCMS是一款基于ThinkPHP框架开发的内容管理系统!
  6. 哎呀你不要把他叫出来_墓友-第一章——釉彩瓶-爱阅小说网
  7. 【Grpc】grpc中repeated的数据如何set值?
  8. v-lazy懒加载的作用与使用
  9. 今天手把手教你做一个Python版的迷宫小游戏
  10. ERROR: Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon runn