欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Vue 的provide 和 inject使用(组件是嵌套关系,但是并不是父子关系)

程序员文章站 2024-03-05 12:37:36
...

文章参考

  1. vue中provide和inject使用
  2. Vue官网-依赖注入
  3. Vue 依赖注入 - Provide/Inject

问题描述

  1. 在工作中,发现 一个组件中添加一个添加搜索按钮的属性,就会影响到另外一个搜索的组件,这两个组件同时被一个“布局”组件包裹,不管我怎么控制相关的属性,都没有办法让搜索内容显示出来,最后查看了源码,了解到了使用的技术点 —— inject 和 provider

官方案例

看了很多网上的博客,场景应用大部分都形容的不怎么贴切,我个人更喜欢官网的例子

<google-map>
  <google-map-region v-bind:shape="cityBoundaries">
    <google-map-markers v-bind:places="iceCreamShops"></google-map-markers>
  </google-map-region>
</google-map>

问题描述说明?

  1. 和 这两个组件都需要依赖 gooogleMap 实例对象
  2. 而gooogleMap 实例对象是在 组件中的
  3. 与 ( )这两个组件是嵌套关系,但是并不是父子关系
  4. 问题是如何把这个实例对象传递给嵌套在里面两个组件中去呢?

解决思路

  1. 把gooogleMap 实例对象 放到他们共用的父组件中,然后通过父组件传递给子组件
  2. 使用Vuex存储 googleMap对象
  3. 使用provide 和 inject; 也是我们今天要学习的内容

如何理解 provide 和 inject

  1. provide 选项允许我们指定我们想要提供给后代组件的数据/方法
  2. 使用 inject 选项来接收指定的我们想要添加在这个实例上的 property

个人理解:

就是说在组件中定以了一个provide属性,提供当前组件中的某些数据或者方法,组件的 children 节点组件使用inject方式就能获取到提供provide的数据或者方法,类似于React中的Provider 和 Consumer

使用场景

组件是嵌套关系,但是并不是父子关系

使用方式例子

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>provide + inject</title>
  <script src="https://cdn.bootcss.com/vue/2.6.11/vue.min.js"></script>
</head>
<body>
  <div id="app"></div>
</body>
</html>

<script>
  Vue.component('A', {
    template: `
      <div>
        <B></B>
      </div>
    `,
    provide: {
      msg: '1234124'
    }
  })
  Vue.component('B', {
    template: `
      <div>
        <label>B:</label>
        <span>{{ this.msg }}</span>
        <C></C>
      </div>
    `,
    provide: {
      msg: '42341234',
      name: 'asdasda'
    },
    inject: ['msg'],
  })

  Vue.component('C', {
    template: `
      <div>
        <label>C:</label>
        <span>{{ this.xingming }}</span>
        <span>{{ this.msg }}</span>
      </div>
    `,
    inject: {
      xingming: {
        from: 'name',
        default: ''
      },
      msg: {
        from: 'msg',
        default: ''
      }
    },
    data() {
      return {
      }
    },
  })
  var app=new Vue({
    el: '#app',
    template: `
      <div>
        <A />
      </div>
    `
  });
</script>

inject定以的数据使用 this.名 方式调用,例如 this.msg