vue中的attribute和property的具体使用及区别

编辑: admin 分类: javascript 发布时间: 2021-11-17 来源:互联网
目录
  • 作为 attribute 和 property 的 value 及 Vue.js 的相关处理
  • attribute 和 property 的概念
  • attribute 和 property 的绑定
  • Vue.js 对 value 的处理
    • 一般情况使用 :value
  • 特殊情况使用 :value.prop
    • 总结

      作为 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 的值(在文本框输入或给 i韩国高防服务器http://www.558idc.com/krgf.htmlnput.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')); // null
          console.log(this.$el.value); // test value
          console.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的具体使用及区别的文章就介绍到这了,更多相关vue attribute property内容请搜索hwidc以前的文章或继续浏览下面的相关文章希望大家以后多多支持hwidc!