Dynamic Components and v-once Directive
# Dynamic Components and v-once Directive
# Dynamic Components
<div id="root">
<component :is="type"></component> <!--equivalent to the two commented lines below-->
<!-- <child-one v-if="type === 'child-one'"></child-one>
<child-two v-if="type === 'child-two'"></child-two> -->
<button @click="handleClick">change</button>
</div>
<script type="text/javascript">
Vue.component('child-one', {
template: '<div>child-one</div>'
})
Vue.component('child-two', {
template: '<div>child-two</div>'
})
var vm = new Vue({
el: '#root',
data: {
type: 'child-one'
},
methods: {
handleClick() {
this.type = this.type === 'child-one' ? 'child-two' : 'child-one'
}
}
})
</script>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
In the code above, clicking the button switches between two components. You can use the <component> tag with :is bound to a dynamic component name.
# Dynamic Component Demo
See the Pen 动态组件 by xugaoyi (@xugaoyi) on CodePen.
# v-once Directive
Does not expect an expression
Details:
Renders the element and component once only. On subsequent re-renders, the element/component and all its children will be treated as static content and skipped. This can be used to optimize update performance.
<!-- single element --> <span v-once>This will never change: {{msg}}</span> <!-- element with children --> <div v-once> <h1>comment</h1> <p>{{msg}}</p> </div> <!-- component --> <my-component v-once :comment="msg"></my-component> <!-- `v-for` directive --> <ul> <li v-for="i in list" v-once>{{i}}</li> </ul>1
2
3
4
5
6
7
8
9
10
11
12
13See also:
# Creating Cheap Static Components with v-once
Rendering plain HTML elements is very fast in Vue, but sometimes you might have a component that contains a lot of static content. In these cases, you can add the v-once attribute to the root element to ensure the content is only computed once and then cached, like this:
Vue.component('terms-of-service', {
template: `
<div v-once>
<h1>Terms of Service</h1>
... a lot of static content ...
</div>
`
})
2
3
4
5
6
7
8
Danger
Once again, try not to overuse this pattern. While it can be convenient in those rare cases when you have to render a lot of static content, it's simply not necessary unless you actually notice slow rendering -- plus it could cause confusion later. For example, imagine another developer who's not familiar with v-once or simply misses it in the template. They might spend hours trying to figure out why the template isn't updating correctly.