• This is the second day of my participation in the November Gwen Challenge. Check out the details: the last Gwen Challenge 2021

Component _ Handles boundary cases

The next steps are all related to handling boundary cases, special cases that require minor adjustments to the Vue’s rules. It is important to note that these features have disadvantages or dangerous scenarios.

Access elements & components

In most cases, it’s best not to touch inside another component instance or manually manipulate DOM elements. But there are situations where it’s appropriate to do these things.

Accessing the root instance

Within each child component, the root instance can be accessed through $root.

 // Vue root instance
new Vue({
  data: {
    foo: 1
  },
  computed: {
    bar () {  / *... * /}},methods: {
    baz () {  / *... * /}}})Copy the code

All child components can access or use this instance as a global store.

 // Get the data for the root component
this.$root.foo

 // Write data to the root component
this.$root.foo = 2

 // Access the computed properties of the root component
this.$root.bar

 // Call the root component's method
this.$root.baz()
Copy the code

It’s handy to use in demos or in small applications with a few components. But using it in large applications can be complicated. So again, we’ll use Vuex (which we’ll learn later) to manage the state of our applications.

Access the parent component instance

In the child component, the parent component instance can be accessed through $parent. This is an alternative to passing data to child components as prop.

Such as:

<cmp-parent>
  <cmp-a></cmp-a>
</cmp-parent>
Copy the code

If cmp-parent needs to share a property, all of its children need to access the share property, in which case Cmp-a can access the share through this.$parent-share.

However, components built through this pattern are still prone to internal problems. For example, we nested a child component cMP-b in cMP-A, as in:

<cmp-parent>
  <cmp-a>
    <cmp-b></cmp-b>
  </cmp-a>
</cmp-parent>
Copy the code

If there is no share in cMP-b, check whether there is share in cMP-B. If there is no share in CMP-B, check whether there is share in cMP-B.

var share = this.$parent.share || this.$parent.$parent.share;
Copy the code

This quickly gets out of hand: touching the parent component makes the application harder to debug and understand, especially when changing the parent data, and after a while it’s hard to figure out where the change originated.

Dependency injection can be used to solve these situations.

Dependency injection

In the example above, the $parent attribute doesn’t scale well to deeper nested components. This is where dependency injection comes in, using two new instance options: provide and Inject.

The provide option allows us to specify the data/methods we want to provide to future generations of components, for example:

Vue.component('cmp-parent', {
  provide () {
    return {
      share: this.share,
    }
  },
  data () {
    return {
      share: 'share',}},template: `<div>cmp-parent</div>`
})
Copy the code

Then in any descendant component, we can use the Inject option to accept properties that specify what we want to add to the instance.

Vue.component('cmp-a', {
  inject: ['share'].template: `<div>cmp-a</div>`
})
Copy the code

In contrast to $parent, this usage allows us to access share in any descendant component without exposing the entire CMP-parent instance. This allows us to better continue developing the component without worrying that we might change/remove some of the dependencies of the child component. And the interfaces between these components are always clearly defined, just like props.

In fact, you can think of dependency injection as part of a “prop that works on a large scale,” except for:

  • The ancestor component does not need to know which descendant components use the properties it provides
  • Descendant components don’t need to know where the injected property came from

However, di has a downside. It couples the components in your application to their current organization, making refactoring more difficult. The supplied properties are also non-reactive. This is for design reasons, as it is not good enough to use them to create a centralized scale of data as it is to use $root to do so. If the attribute you want to share is specific to your application rather than generic, or if you want to update the data provided in the ancestor component, this means you may need to switch to a true state management scheme like Vuex.

Access child component instances or child elements

In spite of prop and events, there may be times when we need to access a child component directly in JS. In this case, we can use the ref feature to give the child an ID reference:

<my-cmp ref="cmp"></my-cmp>
Copy the code

This allows the

instance to be accessed via this.$refs.cmp. Ref can also access specified DOM elements, such as:

<input ref="input" />
Copy the code

So, we can query the DOM element by calling this.$refs.input.

When ref and V-for are used together, the resulting reference will be an array containing these subcomponents of the corresponding data source.

Note: Refs only take effect after the component is rendered, and they are not reactive. Refs should be avoided in templates or computed properties only after the component has rendered, and they are not reactive. Refs should be avoided in templates or computed properties only after the component has rendered, and they are not reactive. Refs should be avoided in templates or computed properties.

The last

If it is helpful to you, I hope to give you a 👍 comment/collection/three even!

Bloggers are honest and answer questions for free ❤