Skip to content

Latest commit

 

History

History
139 lines (124 loc) · 4 KB

20_ref获取元素组件(掌握)($refs $parent $root).md

File metadata and controls

139 lines (124 loc) · 4 KB

$ref的使用

image-20221206201528603

千万不要这样获取DOM元素
<template>
  <div class="wrong">
    <h2 class="title">Hello World</h2>
    <button @click="changeTitle">不要操作原生DOM修改元素内容</button>
  </div>
</template>

<script>
export default {
  methods: {
    changeTitle () {
      const title = document.querySelector('.title')
      title.textContent = "不要这样获取DOM元素,Vue是声明式的,应该在data里面定义数据修改"
    }
  }
}
</script>

<!-- scope样式只在当前组件上面有效 -->
<style scoped>
</style>

获取元素的方法

父组件 App.vue

<template>
  <div class="app">
    <wrong></wrong>
    <!-- 正确修改内容方式 只要在对应的元素或者组件上添加了 ref那么这些元素或者组件对象就会被
		放在 this.$refs 上面-->
    <!-- 1.先在元素上定义一个ref -->
    <h2 ref="title"
        :style="{color: titleColor}">{{message}}</h2>
    <button @click="changeColor">通过Mustache语法修改属性值</button>
    <button ref="btn"
            @click="changeAppTitle">正确修改title方式</button>
  </div>
  <!-- 二:Banner组件 -->
  <h4>在父组件中,通过在子组件上面添加ref="banner",然后就可以在父组件中获取到组件实例<br>
    然后在父组件中就可以通过this.$refs.banner.changeBanner()获取到子组件中的方法
  </h4>
  <div class="banner">
    <!-- 3. 刚才我们是将ref放在了元素身上,但是现在我们想放在banner组件上面
那么获取到的就是banner组件 -->
    <banner ref="banner"></banner>
  </div>
</template>
<!-- 0. 那么我们如果一定要获取元素的话该怎么办呢? -->
<script>
// 一:如果我们有一个组件是banner
import Banner from './Banner.vue'
import Wrong from './千万不要这样获取DOM元素.vue'
export default {
  components: {
    Wrong,
    Banner
  },
  // 正确方式通过data修改值
  data () {
    return {
      message: "Hello World",
      titleColor: 'red'
    }
  },
  methods: {
    changeAppTitle () {
      this.message = "通过Mustache语法修改数据"
      // 2. 这样我们就可以通过 this.$refs.title获取到元素
      console.log(this.$refs.title)
      // 3. 可以通过 this.$refs.btn 获取到按钮元素
      console.log(this.$refs.btn)
      // 四:获取到的就是banner组件--->获取到的组件实例,即在Banner.vue中的this
      console.log(this.$refs.banner)
      // 五:在父组件中可以主动的调用子组件的对象方法
      this.$refs.banner.changeBanner("父组件调用子组件中的对象方法")
      // 六:如果banner template是多个根,拿到的是第一个node节点,
      console.log(this.$refs.banner.$el) 
      // 七:怎么拿到第二个node节点,
      console.log(this.$refs.banner.$el.nextElementSibling)
    },
    changeColor () {
      this.titleColor = "skyblue"
    }
  }
}
</script>

<!-- scope样式只在当前组件上面有效 -->
<style scoped>
</style>

子组件 Banner.vue

<template>
  <!-- 第二行这里是有一个text节点的 -->
  <div class="banner">
    <h2>{{title}}</h2>
  </div>
  <!-- 但是在开发中最好不要让元素有多个根,最好只有一个根 -->
  <!-- <div class="banner">
    {{secondTitle}}
  </div> -->
</template>

<script>
export default {
  data () {
    return {
      title: "Banner",
      secondTitle: "我是第二个根节点"
    }
  },
  methods: {
    changeBanner (val) {
      this.title = val
    }
  }
}
</script>

<!-- scope样式只在当前组件上面有效 -->
<style scoped>
</style>

image-20221206202137982