Vue--provide/inject -- use / tutorial / instance

Original website: Vue--provide/inject -- use / tutorial / instance_ CSDN blog

brief introduction

explain

This article introduces the usage of provide and inject in Vue with examples.

Official website

Provide / Inject | Vue.js

API — Vue.js

Introduction to provide and inject

explain

Through provide and inject, the data and methods of the parent component can be passed to all its descendants.

This kind of transmission can cross levels. For example, a parent component can pass data to a child component.

The parent component provides variables through the provider, and then injects variables through the inject in the descendant component.

There is such a sentence in the official document

Tip: provide and inject bindings are not responsive. This is deliberate. However, if you pass in a listener object, its object properties are still responsive.

Usage scenario

provide and inject are mainly used when developing high-level plug-in / component libraries, and are not recommended in applications.

advantage

It solves the problem of troublesome data transmission when there are too many component levels

shortcoming

Difficult data tracking: uncertain data injection layer and data use layer.

usage

  • provide
    • An object, or a function that returns an object.
    • Object contains what you want to pass, that is, properties and property values
      • Note: the provision of the descendant layer will overwrite the attribute value of the same key in the parent provision
  • inject
    • An array of strings, or an object.
    • The attribute value can be an object, including from and default attributes
  • from
    • The key value in the injected content can be used, that is, the key in the provide d incoming object
  • default
    • Default value. It is an alternative when the value is unsuccessful.

Code execution sequence

  1. data
  2. provide
  3. created
    1. At this stage, $el has not been generated yet. First process the logic of private, and then the descendant components can get the inject value
  4. mounted

Example: response not supported

The binding of provide and inject is not dynamic. That is, after the parent component data changes, the data of the child component will not change.

code

Parent.vue (parent component (top-level component))

<template>
  <div class="outer">
    <h3>Parent component</h3>

    name:<input v-model="name">
    Age:<input v-model.number="age" type="number">

    <child></child>
  </div>
</template>

<script>

import Child from "./Child";
export default {
  name: 'Parent',
  components: {Child},
  data() {
    return {
      name: 'Tony',
      age: 20,
    }
  },
  provide() {
    return {
      name: this.name,
      age: this.age
    }
  }
}
</script>

<style scoped>
.outer {
  margin: 20px;
  border: 2px solid red;
  padding: 20px;
}
</style>

Child.vue (sub component (intermediate component))

<template>
  <div class="outer">
    <h3>Subcomponents</h3>
    <div>Get top-level components name: {{ name }}</div>
    <div>Get top-level components age: {{ age }}</div>
    <grand-child></grand-child>
  </div>
</template>

<script>

import GrandChild from "./GrandChild";
export default {
  components: {GrandChild},
  inject: ['name', 'age'],
  // Detailed writing
  // inject: {/ / specify the source and default value in detail
  //   param1:{
  //     from:'Parent', / / indicates the information passed from the component Parent
  //     default:'a default msg'
  //   },
  //   reload:{
  //     from:'Parent'
  //   }
  // }
}
</script>

<style scoped>
.outer {
  margin: 20px;
  border: 2px solid blue;
  padding: 20px;
}
</style>

GrandChild.vue (sub component (bottom component))

<template>
  <div class="outer">
    <h3>Sun component</h3>
    <div>Get top-level components name: {{ name }}</div>
    <div>Get top-level components age: {{ age }}</div>
  </div>
</template>
<script>
export default {
  name: "GrandChild",
  inject: ['name', 'age'],
  // Detailed writing
  // inject: {/ / specify the source and default value in detail
  //   param1:{
  //     from:'Parent', / / indicates the information passed from the component Parent
  //     default:'a default msg'
  //   },
  //   reload:{
  //     from:'Parent'
  //   }
  // },

}
</script>

<style scoped>
.outer {
  margin: 20px;
  border: 2px solid green;
  padding: 20px;
}
</style>

Routing (store/index.js)

import Vue from 'vue'
import Router from 'vue-router'
import Parent from "../components/Parent";
 
Vue.use(Router)
 
export default new Router({
  routes: [
    {
      path: '/parent',
      name: 'Parent',
      component: Parent,
    }
  ],
})

test

Test 1: access

visit: http://localhost:8080/#/parent

You can see that both child components and child components can obtain the value of the parent component.

Test 2: modify parent component data

Example: support response

The binding of provide and inject is not dynamic.

The solution to realize dynamic response is to assign a function to a value of provide, return the dynamic data of the parent component, and then call this function in the child component.

code

Parent.vue (parent component (top-level component))

<template>
  <div class="outer">
    <h3>Parent component</h3>

    name:<input v-model="name">
    Age:<input v-model.number="age" type="number">

    <child></child>
  </div>
</template>

<script>

import Child from "./Child";
export default {
  name: 'Parent',
  components: {Child},
  data() {
    return {
      name: 'Tony',
      age: 20,
    }
  },
  provide() {
    return {
      name: this.name,
      age: () => this.age //What is passed in here is a function
    }
  }
}
</script>

<style scoped>
.outer {
  margin: 20px;
  border: 2px solid red;
  padding: 20px;
}
</style>

Child.vue (sub component (intermediate component))

<template>
  <div class="outer">
    <h3>Subcomponents</h3>
    <div>Get top-level components name: {{ name }}</div>
    <!--Instead, use the function to get the value-->
    <div>Get top-level components age: {{ age() }}</div>
    <grand-child></grand-child>
  </div>
</template>

<script>

import GrandChild from "./GrandChild";
export default {
  components: {GrandChild},
  inject: ['name', 'age'],
  // Detailed writing
  // inject: {/ / specify the source and default value in detail
  //   param1:{
  //     from:'Parent', / / indicates the information passed from the component Parent
  //     default:'a default msg'
  //   },
  //   reload:{
  //     from:'Parent'
  //   }
  // },
}
</script>

<style scoped>
.outer {
  margin: 20px;
  border: 2px solid blue;
  padding: 20px;
}
</style>

GrandChild.vue (sub component (bottom component))

<template>
  <div class="outer">
    <h3>Sun component</h3>
    <div>Get top-level components name: {{ name }}</div>
    <!--Instead, use the function to get the value-->
    <div>Get top-level components age: {{ age() }}</div>
  </div>
</template>
<script>
export default {
  name: "GrandChild",
  inject: ['name', 'age'],
  // Detailed writing
  // inject: {/ / specify the source and default value in detail
  //   param1:{
  //     from:'Parent', / / indicates the information passed from the component Parent
  //     default:'a default msg'
  //   },
  //   reload:{
  //     from:'Parent'
  //   }
  // }
}
</script>

<style scoped>
.outer {
  margin: 20px;
  border: 2px solid green;
  padding: 20px;
}
</style>

Routing (store/index.js)

import Vue from 'vue'
import Router from 'vue-router'
import Parent from "../components/Parent";
 
Vue.use(Router)
 
export default new Router({
  routes: [
    {
      path: '/parent',
      name: 'Parent',
      component: Parent,
    }
  ],
})

test

Test 1: access

visit: http://localhost:8080/#/parent

Test 2: modify parent component data

You can see:

  1. The name is not dynamically updated. Because there's no function
  2. age is dynamically updated. Because of the function

Keywords: Javascript Front-end Vue Vue.js

Added by chetanmadaan on Sat, 08 Jan 2022 18:52:16 +0200