(一) -访问组件&元素(不推荐)——访问根实例-vue根实例& 访问父组件-子访问父组件成员 & 访问子组件-父访问子组件成员& 依赖注入-父组件提供成员,子组件注入父组件中provide提供的成员

访问组件 & 元素(不推荐)——访问根实例-vue根实例 & 访问父组件-子组件访问父组件成员 & 访问子组件-父组件访问子组件成员 & 依赖注入-父组件提供成员,子组件注入父组件中provide提供的成员

在绝大多数情况下,我们最好不要触达另一个组件实例内部或手动操作 DOM 元素。

访问元素 & 组件

不过也确实在一些情况下做这些事情是合适的:

对于 demo 或非常小型的有少量组件的应用来说这是很方便的。不过这个模式扩展到中大型应用来说就不然了。因此在绝大多数情况下,我们强烈推荐使用 Vuex 来管理应用的状态。

访问根实例-vue根实例(不推荐)

  • 小型应用中可以在 vue 根实例里存储共享数据
  • 组件中可以通过 $root 访问根实例
    • $root

示例:

第一步:注册根实例

main.js中 注册根实例

import Vue from 'vue'
import App from './App.vue'
import Modal from './components/modal/index.js'

// 注册插件
Vue.use(Modal)

Vue.config.productionTip = false

// Vue根实例
new Vue({
  render: h => h(App),
  data: {
    name: 'zs',
    age: 18
  }
}).$mount('#app')

第二步:新建demo.vue文件

//div里使用组件

{{ $root.name }} - {{ $root.age }}

<template>
  <div>
    <h1>1. 演示访问根组件</h1>
      //$root  访问根实例
    {{ $root.name }} - {{ $root.age }}

    <input type="button" value="set" @click="$root.age = 100" >
    <h1>2. 演示访问父组件</h1>

    {{ $parent.name }} - {{ $parent.age }}
    <input type="button" value="set" @click="$parent.age = 100" >

    <h1>3. 演示访问子组件</h1>
    <!-- $refs 只会在组件渲染完成之后生效,并且它们不是响应式的 -->
    <input ref="txt" type="text">
    <!-- {{ $refs.d.msg }} -->

    <h1>4. 依赖注入</h1>
    {{ myMsg }}
    <input type="button" value="getMap" @click="getMap" >

  </div>
</template>

<script>
export default {
  // 依赖注入
  // 注入父组件中provide提供的成员
  inject: ['myMsg', 'getMap'],
  created () {
    console.log(this.$parent)
  },
  data () {
    return {
      msg: '我是子组件中的值'
    }
  },
  methods: {
    focus () {
      this.$refs.txt.focus()
    }
  }
}
</script>

<style>

</style>

第三步:在App.vue入口文件中引入demo.vue文件

//script里引入组件

import Demo from ‘./components/01-demo’

//注册组件

components: {
Demo,

}

<template>
  <div id="app">
    <demo ref="d"></demo>

    <h1>3. 访问子组件</h1>
    <input type="button" value="子组件" @click="handle">

    <!-- 5. 封装组件 -->
    <h1>5. 封装组件-传递属性</h1>
    <!-- my-input是自定义组件,input/focus 都是自定义事件 -->
    <my-input @input="handleInput" @focus="handleFocus" placeholder="请输入..." maxlength="5" class="my"></my-input>

    <!-- 6. 动态组件和异步组件 -->
    <h1>6. 动态组件和异步组件</h1>
    <input type="button" value="登录" @click="componentId='Login'">
    <input type="button" value="注册" @click="componentId='Register'">

    <keep-alive>
      <component :is="componentId"></component>
    </keep-alive>

    <h1>7. 模态框组件</h1>
    <input type="button" value="modal" @click="showModal=true">
    <!-- 
      $event 只能在视图中使用
      $event 是事件参数

      v-model 等价于
      v-bind:value="searchText"
      v-on:input="searchText = $event"
     -->
    <my-modal v-model="showModal" @test="test"></my-modal>

    <input type="button" value="js方法调用" @click="$modal">
  </div>
</template>

<script>
import Demo from './components/01-demo'
import MyInput from './components/02-input'
// import Login from './components/03-login'
// import Register from './components/04-register'
import MyModal from './components/modal/index.vue'
export default {
  name: 'app',
  components: {
    Demo,
    MyInput,
    // 异步组件
    Login: () => import('./components/03-login'),
    Register: () => import('./components/04-register'),
    MyModal
  },
  data () {
    return {
      name: 'xxx',
      age: 19,
      // 导入组件的名字,是字符串形式
      componentId: 'Login',
      showModal: false
    }
  },
  methods: {
    // test (value) {

    // },
    handle () {
      // this.$children -- 数组
      // console.log(this)
      // 组件对象
      // console.log(this.$refs.d)
      this.$refs.d.focus()
      console.log(this.$refs.d.msg)
    },
    handleInput () {
      console.log('handleInput')
    },
    handleFocus () {
      console.log('handleFocus')
    }
  },
  // 依赖注入
  // 父组件中提供成员
  provide () {
    return {
      myMsg: '演示依赖注入',
      getMap () {
        console.log('getMap')
      }
    }
  }
}
</script>

<style>
</style>

访问父组件-子组件访问父组件成员(不推荐)

访问父级组件实例

  • 可以使用这种方式替换 prop 方式父给子传值
  • 但是这种方式应该尽量避免使用,因为:如果值改变了,很难确认值是在哪里变化的
  • 使用方式
    • $parent

父组件-App.vue文件中增加属性

data () {

  return {

   name: 'xxx',

   age: 19,

}

子组件-01-demo.vue文件中进行演示访问父组件

//<h1> 2. 演示访问父组件</h1>

  {{ $parent.name }} - {{ $parent.age }}

<input type="button" value="set" @click="$parent.age = 100" >

访问子组件-父组件访问子组件成员(不推荐)

访问子组件实例或子元素

  • 获取子组件内的 DOM 元素
  • 调用子组件内部的方法,例如:vant 中访问表单的方法
  • 使用方式
    • $refs

子组件-01-demo.vue文件中进行添加文本框

 //<h1>3. 演示访问子组件</h1>
//  <!-- $refs 只会在组件渲染完成之后生效,并且它们不是响应式的 -->
  <input ref="txt" type="text">

data () {
	  return {
	 	  msg: '我是子组件中的值'
	 }
 },

methods: {
  focus () {
   this.$refs.txt.focus()
  }
 }

父组件-App.vue文件中获得焦点-访问子组件

 // <h1>3. 访问子组件</h1>
   <input type="button" value="子组件" @click="handle">
       
 methods: {
  		 // test (value) {
		  // },
	  handle () {
		   // this.$children -- 数组
	   // console.log(this)
		   // 组件对象
		   // console.log(this.$refs.d)
		   this.$refs.d.focus()
          //获取子组件方法
	   console.log(this.$refs.d.msg)
  },

注意

$refs 只会在组件渲染完成之后生效,并且它们不是响应式的。这仅作为一个用于直接操作子组件的“逃生舱”——你应该避免在模板或计算属性中访问 $refs

依赖注入(不推荐)——父组件-提供成员,子组件-注入父组件中provide提供的成员

依赖注入

依赖注入——父组件-提供成员,子组件-注入父组件中provide提供的成员

  • 如果组件嵌套比较深 (a=>b=>c=>d),并且所有后代组件都依赖于 a 组件的数据或者方法

  • 此时虽然通过 $parent 也可以实现,但是比较麻烦,此时可以使用依赖注入的方式

  • 使用方式

    • 父组件中-App.vue文件-提供成员

      // 组件的选项中添加   提供成员
      provide: function () {
        return {
          getMap: this.getMap
        }
      }
      
    • 所有子组件中-01-demo.vue文件

      <h1>4. 依赖注入</h1>
          {{ myMsg }}
      <input type="button" value="getMap" @click="getMap" >
      
      
      // 组件的选项中自定义位置添加    注入父组件中provide提供的成员
      inject: ['getMap']
      
  • 注意:

    • 可以把依赖注入看成大范围的 prop
    • 这种方式的数据是非响应式的
    • 负面影响:耦合变高,使重构变得更加困难
发布了199 篇原创文章 · 获赞 1 · 访问量 5468

猜你喜欢

转载自blog.csdn.net/weixin_44867717/article/details/104924414