Vue 进阶之路(十三)

之前的文章我们介绍了一下 vue 中的作用域插槽,本章我们来看一下动态组件与 v-once 指令。

 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <title>vue</title>
 6     <script src="https://cdn.jsdelivr.net/npm/vue"></script>
 7 </head>
 8 <body>
 9 <div id="app">
10     <child-one v-if="type === 'child-one'"></child-one>
11     <child-two v-if="type === 'child-two'"></child-two>
12     <p @click="handleClick">clickMe</p>
13 </div>
14 <script>
15     Vue.component("child-one", {
16         template: `<p>我是第一个子组件</p>`
17     });
18     Vue.component("child-two", {
19         template: `<p>我是第二个子组件</p>`
20     });
21     var app = new Vue({
22         el: '#app',
23         data: {
24             type: "child-one"
25         },
26         methods: {
27             handleClick() {
28                 console.log("type 数据更改前", this.type);
29                 this.type = this.type === "child-one" ? "child-two" : "child-one";
30                 console.log("type 数据更改后", this.type)
31             }
32         }
33     })
34 </script>
35 </body>
36 </html>

上面的代码中,我们定义了两个子组件 child-one 和 child-two,并且我们在父组件中定义了一个 handleClick() 方法,当点击时我们通过父组件中 type 的值来使两个子组件进行显隐,结果如下:

当点击 clickMe 时显示结果符合我们的预期,其实上面的代码可以改成如下:

 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <title>vue</title>
 6     <script src="https://cdn.jsdelivr.net/npm/vue"></script>
 7 </head>
 8 <body>
 9 <div id="app">
10     <component :is="type"></component>
11     <p @click="handleClick">clickMe</p>
12 </div>
13 <script>
14     Vue.component("child-one", {
15         template: `<p>我是第一个子组件</p>`
16     });
17     Vue.component("child-two", {
18         template: `<p>我是第二个子组件</p>`
19     });
20     var app = new Vue({
21         el: '#app',
22         data: {
23             type: "child-one"
24         },
25         methods: {
26             handleClick() {
27                 console.log("type 数据更改前", this.type);
28                 this.type = this.type === "child-one" ? "child-two" : "child-one";
29                 console.log("type 数据更改后", this.type)
30             }
31         }
32     })
33 </script>
34 </body>
35 </html>

我们将 <child-one> <child-two> 标签删除掉,改为 <component> 标签内,并在标签内写上 :is="type",<component> 标签是一个动态标签的意思,我们也可以将它写成 <p> 或者 <h1> 都行,:is="type" ,根据父组件 type 数据的值和 handleClick() 方法对 type 数据改变来确定 :is="type" 内 type 的值是 child-one 还是 child-two,这样就能动态地改变时显示 child-one 组件还是 child-two 组件,结果如下:

运行结果和上面是一样的。

接下来我们来看一下 v-once 指令。

 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <title>vue</title>
 6     <script src="https://cdn.jsdelivr.net/npm/vue"></script>
 7 </head>
 8 <body>
 9 <div id="app">
10     <child-one v-if="type === 'child-one'"></child-one>
11     <child-two v-if="type === 'child-two'"></child-two>
12     <p @click="handleClick">clickMe</p>
13 </div>
14 <script>
15     Vue.component("child-one", {
16         template: `<p v-once>我是第一个子组件</p>`
17     });
18     Vue.component("child-two", {
19         template: `<p v-once>我是第二个子组件</p>`
20     });
21     var app = new Vue({
22         el: '#app',
23         data: {
24             type: "child-one"
25         },
26         methods: {
27             handleClick() {
28                 console.log("type 数据更改前", this.type);
29                 this.type = this.type === "child-one" ? "child-two" : "child-one";
30                 console.log("type 数据更改后", this.type)
31             }
32         }
33     })
34 </script>
35 </body>
36 </html>

上面的代码中我们在每一个子组件的 template 模板中的 <p> 表内都加了一个 v-once 属性,如果不加这个指令的话我们每次通过 handleClick() 方法来判断 type 时,子组件就会进行一个销毁,另一个重新挂载,就会消耗不必要的内存。加上 v-once 时,当第一次挂载时需要渲染一次,当销毁时并不是彻底删除掉,而是留在了内存中,当需要重新挂载时就不需要重新渲染,而是直接去内存中拿,这样就能减少不必要的内存消耗。

猜你喜欢

转载自www.cnblogs.com/weijiutao/p/10683961.html