Vue-获取组件($root-$parent-$children-$refs)

这里写目录标题


$root

表示当前组件树的根 Vue 实例,即new Vue({…根组件内容})。
如果当前实例没有父实例,此实例将会是其自己。
Vue子组件可以通过$root属性访问父组件实例的属性和方法
原理:再入口文件main.js中对Vue的原型设置一个属性并绑定vm对象,后面的子组件都能访问这个根节点

//main.js中
var vm=new Vue({
  render: h => h(App),
}).$mount('#app')
Vue.prototype.myroot=vm
//box1中
<template>
    <div>
        <button @click="fn">点我</button>
    </div>
</template>
<script>
    export default {
        methods: {
            fn() {
                console.log(this.$root)
                console.log(this.myroot)
                console.log(this.myroot === this.$root)
            },
        },
    }
</script>

点击打印:
在这里插入图片描述

$parent

和$root 类似,$parent property 可以用来从一个子组件访问父组件的实例。它提供了一种机会,可以在后期随时触达父级组件,以替代将数据以 prop 的方式传入子组件的方式。

$children

子组件:$children // 数组
$children表示当前实例的直接子组件。需要注意$children并不保证顺序,也不是响应式的。如果正在尝试使用$children来进行数据绑定,考虑使用一个数组配合v-for来生成子组件,并且使用Array作为真正的来源

$ref

尽管存在 prop 和事件,有的时候你仍可能需要在 JavaScript 里直接访问一个子组件。为了达到这个目的,你可以通过 ref 这个 attribute 为子组件赋予一个 ID 引用。例如:

<template>
<div v-cloak class="App">
  <button @click="fn">点我</button>
  <box1 ref="reference"></box1>
</div>
</template>
<script>
  import box1 from "./components/box1.vue"
  export default {
    methods: {
      fn(){
        console.log(this.$refs.reference)
      }
    },
    components: {
      box1,
    }
  }
</script>
<script>
    export default {
        data(){
            return{
               msg:"box1组件"
            }
        },
    }
</script>

在这里插入图片描述
也可以用来在vue中使用dom操作比如:实现放大镜效果

<template>
  <div>
    <div ref="div1" class="div1">
      <div ref="mask" class="mask">
      </div>
    </div>
    <div ref="rightdiv" class="rightdiv">
      <div ref="bigimg" class="bigimg">
      </div>
    </div>
  </div>
</template>
<script>
  export default {
    mounted() {
      var div1 = this.$refs.div1
      var mask = this.$refs.mask
      var rightdiv = this.$refs.rightdiv
      var bigimg = this.$refs.bigimg
      div1.onmouseenter = function () {
        mask.style.display = "block"
        rightdiv.style.display = "block"
        div1.onmouseleave = function () {
          mask.style.display = "none"
          rightdiv.style.display = "none"
        }
        div1.onmousemove = function (e) {
          var mx = e.clientX - 200;
          var my = e.clientY - 100;
          var x = mx - 25;
          var y = my - 25;
          if (mx > 251) {
            x = 226
          } else if (mx < 25) {
            x = 0
          }
          if (my > 295) {
            y = 270
          } else if (mx < 25) {
            y = 0
          }
          mask.style.left = x + "px";
          mask.style.top = y + "px";
          bigimg.style.left = -x * 6 + "px";
          bigimg.style.top = -y * 6 + "px";
        }
      }

    }
  }
</script>

<style scoped="scoped" lang="scss">
  .div1 {
    width: 276px;
    height: 320px;
    background-image: url(http://attach.bbs.miui.com/forum/201303/16/173710lvx470i4348z6i6z.jpg);
    background-size: 100% 100%;
    position: absolute;
    left: 200px;
    top: 100px;
    background-color: firebrick;
  }

  .mask {
    width: 50px;
    height: 50px;
    background-color: rgba(255, 255, 180, 0.4);
    position: absolute;
    display: none;
  }

  .rightdiv {
    width: 300px;
    height: 300px;
    position: absolute;
    left: 500px;
    top: 100px;
    overflow: hidden;
    display: none;
  }

  .bigimg {
    width: 1656px;
    height: 1920px;
    background-image: url(http://attach.bbs.miui.com/forum/201303/16/173710lvx470i4348z6i6z.jpg);
    background-size: 100% 100%;
    position: absolute;
  }
</style>

在这里插入图片描述