Close read Vue official documentation series 🎉
Access elements & components
$root
Access the root component instance
$parent
Gets a parent component instance that supports multiple calls to get instances of successive layers of parents.
ref & $refs
Gets an instance of the child component
<children ref="child" />
Copy the code
Gets an object reference to a DOM element.
<input type="text" ref="input" />
Copy the code
Finally, we can access the corresponding references to these Refs in the component’s $refs property.
mountd(){
this.$refs.child.input.foucs();
}
Copy the code
When ref and V-for are used together, the ref you get will be an array containing the subcomponents of the corresponding data source.
Dependency injection
Provide dependencies with provide and inject dependencies with Inject.
Provider
provide: function(){
return {
getMapData: this.getData
}
}
Copy the code
Consumer
inject:['getMapData']
Copy the code
This pair of component options must be used together. To allow an ancestor component to inject a dependency into all its descendants, no matter how deep the component hierarchy is.
The value of provide is an object or a function that returns an object. The key of the object is the dependency injected into the descendant component. The value of Inject is an array of strings, or an object option. These array elements or object keys correspond to provide injected dependencies.
In its most basic form:
Vue.extend({
name: "Parent".provide: {
foo: "bar",}}); Vue.extend({name: "Son".inject: ["foo"].created() {
console.log(this.foo); }});Copy the code
While provide is a function, inject is an object option:
Vue.extend({
name: "Parent".provide() {
return {
foo: "bar"}; }}); Vue.extend({name: "Son".inject: {
bar: {
from: "foo".default: "new bar",}}});Copy the code
If the value of inject is an object, then from specifies the source and default is used to set the default value of the dependency. But when your dependency default is not a primitive type, you must use a factory method to return that value.
{
inject: {
foo: {
from: 'bar'.default: () = > [1.2.3]}}}Copy the code
Finally, since provide/inject initialization takes precedence over props,data, we can initialize their defaults with dependency injection.
Vue.extend({
inject: ["foo"].props: {
bar: {
type: String.default: () = > this.foo,
},
},
data() {
return {
copy_bar: this.foo, }; }});Copy the code
What problem does dependency injection solve?
- To solve the
$parent
Does not scale well to deeper nested components. - Providing data or methods to arbitrary descendants eliminates the need for multiple layers of Prop passing.
- Any descendant does not need to care where the property was injected from.
Application scenarios of dependency injection:
- Write a fixed set of components, with a root component and multiple layers of child components, with a fixed structure.
- A local data centralization.
Negative effects of dependency injection:
- Injected data or methods are not responsive based on design considerations.
- Injected data is not processed as responsive data, but that does not prevent dependency injection of responsive data.
- Because of the nature of dependency injection, it tightly couples related components in the application (those that use dependency injection), making refactoring difficult.
Vuex, the silver bullet of dependency injection, provides a third party independent data center with responsive update capabilities.
Programmatic event listeners
The programmatic event listener is built on top of the Vue system, which is distinct from the browser’s EventTarget API. Normally we use V-ON to listen for events on components and $emit() to fire events within components, and the “programmatic Event Listener” provides a feature to listen for events on component instances.
$on('eventName', eventHandler)
Bind/listen for an event.$off('eventName, eventHandler')
Unbind/stop listening for an event.$once(eventName, eventHandler)
Bind/listen on one event at a time.
Making good use of $once can improve our ability to solve component event cleanup problems.
Bad
// Attach the date picker to an input box once
// It will be mounted to the DOM.
mounted: function () {
// Pikaday is a library of third-party date pickers
this.picker = new Pikaday({
field: this.$refs.input,
format: 'YYYY-MM-DD'})},// Before the component is destroyed,
// Also destroy the date picker.
beforeDestroy: function () {
this.picker.destroy()
}
Copy the code
Good
mounted: function () {
var picker = new Pikaday({
field: this.$refs.input,
format: 'YYYY-MM-DD'
})
this.$once('hook:beforeDestroy'.function () {
picker.destroy()
})
}
Copy the code
We can also encapsulate these operations into methods that make it easier to perform the same operation multiple times.
Recursive components
In the same way that “recursion” is calling itself, component recursion is a component calling itself over and over again.
Recursive component entry:
<x-menu :menus="menus"></x-menu>
Copy the code
Recursive component definition:
Vue.component('x-menu', {
props: {menus: {requried:true.type:Array}},template:` <ul> <li v-for="menu in menus" :key="menu.key"> <div>{{ menu.name }}</div> <! - heart - > < x - menus v - if = "menu. Children" > < / x - menus > < / li > < / ul > `
});
Copy the code
A circular reference
Unlike recursive components, recursion implements the desired functionality by constantly calling itself. A circular reference exists only between two components, A that uses B, and B that uses A.
This is not the case if you are registered as a global component through Vue.com Ponent.
Typically this problem occurs only when modular systems are used to introduce components that reference each other.
There are two solutions:
1. Manually register one of the components
beforeCreate: function(){
this.$options.components.ComponetB = import('./components/componentB').default;
}
Copy the code
2. Use asynchronous components
{
components: {'component-b': () = >import('./components/componentB')}}Copy the code
Alternatives to template definitions
We recommend defining templates using single-file component SFC or writing string templates in the template property rather than separating component templates from logic.
Inline template
When the special attribute inline-template appears on a child component, the component will use its content as the template, rather than as the content to be distributed (regardless of the nature of the slot). This makes writing templates more flexible.
Inline templates need to be defined within the DOM element that the Vue belongs to.
<my-component inline-template>
<div>
<p>These are compiled as the component's own template.</p>
<p>Not parent's transclusion content.</p>
</div>
</my-component>
Copy the code
The contents of the start and end tags of a custom component will be used as templates for that custom component and therefore will not be passed to the
element. This will separate the template from the logic of the component and is generally not recommended.
X-Template
The contrast with inline templates is to use
The X-template needs to be defined outside the DOM element that the Vue belongs to.
<script type="text/x-template" id="hello-world-template"></script>
Copy the code
The ID is the credential that connects the template content to the template logic.
Vue.component('hello-world', {
template: '#hello-world-template'
})
Copy the code
The X-template approach also causes the component Template to be separated from the logic, so it is not recommended.
Forced to update
A call to this.$forceUpdate() forces the component to update.
throughv-once
Create low overhead static components
When a component contains a lot of static content. We can add v-once attributes to the root element to ensure that the content is evaluated only once and then cached to provide the rendering speed of the component.
Vue.component('terms-of-service', {
template: `
<div v-once>
<h1>Terms of Service</h1>. a lot of static content ...</div>`})Copy the code