Recursive components and dynamic components
Recursive components
Recursive component refers to the essential component to call their own in the template, open recursive component, is set in a component name
options. Such as the following example:
<template>
<div>
<my-component></my-component>
</div>
</template>
<script>
export default {
name: 'my-component'
}
</script>
Import Webpack in a Vue.js components, typically by import myComponent from 'xxx'
this syntax, then the current component (page) is components: { myComponent }
registered in the component. This component is not set mandatory name
fields, the user name of the component are coming after import custom, but users recursive component is the component itself, it must know what this component is called, because there is no use components
registered, so the name
field It is a must. In addition to the components used recursively name
, we in the previous section is also introduced, with some special way, to find the component instance by traversing the name option of matching components.
But then, the above example is problematic, if the direct running, throws max stack size exceeded
an error, because the components will be an infinite recursion, infinite loop. To solve this problem, we should give a recursive component constraints, the general assembly will be used in the recursive v-if
setting somewhere false
to end. For example, we add to the above example attribute count, when more than 5 is no longer recursion:
<template>
<div>
<my-component :count="count + 1" v-if="count <= 5"></my-component>
</div>
</template>
<script>
export default {
name: 'my-component',
props: {
count: {
type: Number,
default: 1
}
}
}
</script>
Therefore, conclude the necessary conditions to implement a recursive components are:
- Give the assembly is provided name ;
- Have a clear end condition
Recursive components used to develop stand-alone component with an unknown level of relationship is rarely used in business development. Such as common cascade selector and tree controls:
Usually such components are data-driven, there is a parent Children field, then recursively. The next section of combat, will develop a tree control Tree.
Dynamic Components
Sometimes, we hope, according to some conditions, dynamically switch a component, or a component dynamically select the rendering. When subsections describe the functional components Functional Render previously been mentioned, it is a function of context, commonly used in the procedure of selecting a plurality of components. Functional Render Render or use can address the needs of dynamic switching assembly, but it is based on a JS objects (Render function), and provides another Vue.js built-in components <component>
and is
properties can be better dynamic component.
A first look <component>
and is
basic example, first define three general components:
<!-- a.vue -->
<template>
<div>
组件 A
</div>
</template>
<script>
export default {
}
</script>
<!-- b.vue -->
<template>
<div>
组件 B
</div>
</template>
<script>
export default {
}
</script>
<!-- c.vue -->
<template>
<div>
组件 C
</div>
</template>
<script>
export default {
}
</script>
Then introducing the three components in the parent component, and dynamically switching:
<template>
<div>
<button @click="handleChange('A')">显示 A 组件</button>
<button @click="handleChange('B')">显示 B 组件</button>
<button @click="handleChange('C')">显示 C 组件</button>
<component :is="component"></component>
</div>
</template>
<script>
import componentA from '../components/a.vue';
import componentB from '../components/b.vue';
import componentC from '../components/c.vue';
export default {
data () {
return {
component: componentA
}
},
methods: {
handleChange (component) {
if (component === 'A') {
this.component = componentA;
} else if (component === 'B') {
this.component = componentB;
} else if (component === 'C') {
this.component = componentC;
}
}
}
}
</script>
Here the is
dynamic binding is a component object (Object), which points directly to a a / b / c of the three components. In addition to a direct binding Object, also can be a String, such as tag name, component name. Following this component, the original raw button button the package, if passed in prop: to
, then it will be rendered as a <a>
tag, to open the link address, if not pass to
, use it as a normal button. Consider the following example:
<!-- button.vue -->
<template>
<component :is="tagName" v-bind="tagProps">
<slot></slot>
</component>
</template>
<script>
export default {
props: {
// 链接地址
to: {
type: String,
default: ''
},
// 链接打开方式,如 _blank
target: {
type: String,
default: '_self'
}
},
computed: {
// 动态渲染不同的标签
tagName () {
return this.to === '' ? 'button' : 'a';
},
// 如果是链接,把这些属性都绑定在 component 上
tagProps () {
let props = {};
if (this.to) {
props = {
target: this.target,
href: this.to
}
}
return props;
}
}
}
</script>
Use components:
<template>
<div>
<i-button>普通按钮</i-button>
<br>
<i-button to="https://juejin.im">链接按钮</i-button>
<br>
<i-button to="https://juejin.im" target="_blank">新窗口打开链接按钮</i-button>
</div>
</template>
<script>
import iButton from '../components/a.vue';
export default {
components: { iButton }
}
</script>
Eventually render a native <button>
link button and two native <a>
, and a second click on the link will open in a new window, as shown:
i-button assembly <component>
is
binding is a label name button / a, and by v-bind
the additional properties all bound to <component>
the.
Go back to the first example of a / b / c switch components, if such components, the frequent switching, will in fact be re-render the component, such as our Riga two components A life cycle:
<!-- a.vue -->
<template>
<div>
组件 A
</div>
</template>
<script>
export default {
mounted () {
console.log('组件创建了');
},
beforeDestroy () {
console.log('组件销毁了');
}
}
</script>
As long as the switch to the A component, mounted
it will trigger a switch to other components, beforeDestroy
it will trigger once, and then re-render the assembly instructions, which may lead to performance problems. To avoid repetition render component can be in <component>
the outer sleeve Vue.js a built-in <keep-alive>
assembly, so that the assembly will be cached:
<keep-alive>
<component :is="component"></component>
</keep-alive>
At this point, only mounted
triggered if you do not leave the current page, switch to other components, beforeDestroy
will not be triggered, indicating that components have been cached.
keep-alive some extra props can be configured:
include
: String or a regular expression. Only the component name matches will be cached.exclude
: String or a regular expression. Any component matching names will not be cached.max
:digital. The maximum number of component instances can be cached.
Epilogue
Another type is the asynchronous component, Vue.js document has been presented very clearly, it can be extended at the end of reading the text reading 1. Many, such as router configuration list of the components we use in fact asynchronous, asynchronous components are generally used in the form of:
{
path: '/form',
component: () => import('./views/form.vue')
}
So that each page will load corresponding to when the JS file routing, otherwise entry file will be very large.
Recursive component, dynamic components and asynchronous components are relatively popular Vue.js three kinds of component patterns, but when the individual components of a complex package, the former two will often use.