zoukankan      html  css  js  c++  java
  • 关于Vue中的ref和$refs的二三事

      Vue中的ref可以用来给元素或子组件注册引用信息,而$refs可以用来获取ref注册过的元素或组件,关于这一点概念,其实很容易理解,使用一下就可以上手了,详细的概念参见 [vue-ref]   [vue-$refs]

      但是在实际项目中,会发现,有时候通过 this.$refs.ref名称 来获取对应的DOM或组件时,并不能成功,而要在后面加一个 [0] 才能成功获取到。多留心一下,会发现好像是涉及到循环时,就会出现这种情况,那不如来多做几组测试来验证一下,顺便试试各种特殊情况下的特别之处。

      太长了,我要直接看结论

      

      part 1 常规用法

      当ref用在组件上时,通过$refs获取的是该组件的实例,可进而调用组件内定义的方法、属性等;

      如下图所示,当ref定义在组件Home上时,通过this.$refs.test获取的是Home组件对应的实例对象,通常我们可以通过这种方式来调用某个组件内的methods、data中定义的数据、或是进而获取其子组件等。

    <template>
      <div id="app">
        <Home ref="test" />
      </div>
    </template>
    
    <script>
    import Home from './views/Home'
    export default {
      components: { Home },
      mounted () {
        console.log(this.$refs.test)
      }
    }
    </script>

      当ref用在DOM节点上时,通过$refs获取的是该DOM元素节点。

      如下图所示,当ref定义在DOM元素上时,通过this.$refs.test获取的是该DOM元素,且包含子元素,进而可以进行下一步的DOM操作。

    <template>
      <div id="app">
        <p ref="test">
          <span>123</span>
        </p>
      </div>
    </template>
    
    <script>
    export default {
      mounted () {
        console.log(this.$refs.test)
      }
    }
    </script>

     


      Part 2 多处ref引用的值相同时(非v-for内使用时)

       当html中ref值相同的节点是兄弟节点时,通过$refs获取到的是文档中顺序靠下的节点(使用在DOM上和组件上原则一致,以DOM为例)

    <template>
      <div id="app">
        <p ref="test">
          <span>123</span>
        </p>
        <span ref="test">456</span>
      </div>
    </template>
    
    <script>
    export default {
      mounted () {
        console.log(this.$refs.test)
      }
    }
    </script>

     

       当html中ref值相同的节点是嵌套关系时,比如父子关系,则通过$refs获取到的是外层节点(使用在DOM上和组件上原则一致,以DOM为例)

    <template>
      <div id="app">
        <p ref="test">
          <span ref="test">123</span>
        </p>
      </div>
    </template>
    
    <script>
    export default {
      mounted () {
        console.log(this.$refs.test)
      }
    }
    </script>

     

       当html中ref值相同的节点不在同一层级,也不是嵌套关系时,仍然遵循文档中顺序靠下的节点被获取的原则(使用在DOM上和组件上原则一致,以DOM为例)

    <template>
      <div id="app">
        <p ref="test">456</p>
        <p>
          <span ref="test">123</span>
        </p>
      </div>
    </template>
    
    <script>
    export default {
      mounted () {
        console.log(this.$refs.test)
      }
    }
    </script>


     

       Part 3 当ref值是个变量时(非v-for内使用时)

       ref值使用变量时,通过this.$refs[变量名称]指向的依旧是该DOM节点或组件实例,不需要加[0],且当出现ref值重复时,仍然满足Part2实践中的原则

    <template>
      <div id="app">
        <p :ref="name">
          <span>123</span>
        </p>
      </div>
    </template>
    
    <script>
    export default {
      data () {
        return {
          name: 'test'
        }
      },
      mounted () {
        console.log(this.$refs[this.name])
      }
    }
    </script>

     


       Part 4 ref用在v-for上时

      当ref值相同时,this.$refs[ref名称]获取到的是该DOM节点或组件的数组,此处以组件为例

    <template>
      <div id="app">
        <Home v-for="num in loop" :key="num" ref="test"></Home>
      </div>
    </template>
    
    <script>
    import Home from './views/Home'
    export default {
      components: { Home },
      data () {
        return {
          loop: 3
        }
      },
      mounted () {
        console.log(this.$refs.test)
      }
    }
    </script>

     

       当ref值不同时,this.$refs[ref名称]无法获取对应的DOM节点或是组件,需要在其后追加[0]才可访问,此处以组件为例

    <template>
      <div id="app">
        <Home v-for="num in loop" :key="num" :ref="'test' + num"></Home>
      </div>
    </template>
    
    <script>
    import Home from './views/Home'
    export default {
      components: { Home },
      data () {
        return {
          loop: 3
        }
      },
      mounted () {
        console.log(this.$refs.test1)
      }
    }
    </script>

     


       总结:

         1. ref用在DOM上时,通过this.$refs[ref名称]访问的是该DOM元素节点;ref用在组件上时,通过this.$refs[ref名称]访问的是该组件的实例对象,可以进而调用组件的方法或者获取组件的属性等;

        2. 当同一组件内部,有多处ref引用值相同的情况时,this.$refs[ref名称]指向文档流中靠下的组件或DOM节点,若是父子关系,则指向父级组件或DOM节点;

        3. 若ref的值是个变量,只要不是用在v-for里,通过this.$refs[变量名称]指向的依旧是该DOM节点或组件实例,且当出现ref值重复时,仍然满足取靠下的节点或是父级节点的规则;

        4. 若ref用在v-for里,当循环内的ref值相同时,this.$refs[ref名称]获取到的是该DOM节点或组件的数组,当ref值不同时,需提供this.$refs[ref名称][0]来获取该DOM节点或组件实例。

      以上各项实践可能考虑的情况不一定全,若是有遇到其他情况出现不一样的用法和结果,再进行补充。

  • 相关阅读:
    [HNOI2016]序列
    [Cqoi2015] 编号 【逆向思维,暴力枚举】
    [NOI2015] 软件包管理器【树链剖分+线段树区间覆盖】
    [Hdu-6053] TrickGCD[容斥,前缀和]
    [Hdu-5155] Harry And Magic Box[思维题+容斥,计数Dp]
    牛客NOIP暑期七天营-提高组6
    [SHOI2007] 书柜的尺寸 思维题+Dp+空间优化
    [UVA12235] Help Bubu 思维题+状态定义+Dp
    牛客NOIP暑期七天营-TG3 赛后题解
    牛客NOIP暑期七天营-TG1 赛后题解
  • 原文地址:https://www.cnblogs.com/happymental/p/11991112.html
Copyright © 2011-2022 走看看