Vue.js 教程

Vue.js 动态组件与 keep-alive

在上章 “Vue.js 动态组件” 中,我们在一个多标签的界面中使用 is 属性来切换不同的组件,如下:

<!-- 动态组件,根据 currentTab 中的值(组件)动态加载组件 -->
<component v-bind:is="currentTab"></component>

当在这些组件之间切换的时候,你有时会想保持这些组件的状态,以避免反复重新渲染导致的性能问题。例如一个多标签界面:

你会注意到,如果在 Home 标签中勾选了复选框,切换到 Posts 或 Archive 标签,然后再切换回 Home 标签,你会发现 Home 标签中的复选框没有被勾选。这是因为你每次切换新标签的时候,Vue 都创建了一个新的 currentTab 实例。

重新创建动态组件的行为通常是非常有用的,但是在这个示例中,我们更希望那些标签的组件实例能够被在它们第一次被创建的时候缓存下来。为了解决这个问题,我们可以用一个 <keep-alive> 元素将其动态组件包裹起来。例如:

<!-- 失活的组件将会被缓存!-->
<keep-alive>
   <!-- 动态组件,根据 currentTab 中的值(组件)动态加载组件 -->
   <component v-bind:is="currentTab"></component>
</keep-alive>

修改后的效果如下图:

现在这个 Home 标签保持了它的状态 (被选中的复选框) 甚至当它未被渲染时也是如此。

注意:这个 <keep-alive> 要求被切换到的组件都有自己的名字,不论是通过组件的 name 选项还是局部/全局注册。

完整示例

<html>
<head>
   <meta charset="UTF-8">
   <meta http-equiv="X-UA-Compatible" content="IE=edge">
   <meta name="viewport" content="width=device-width, initial-scale=1.0">
   <title>Vue</title>
   <!-- 使用 CDN 引入 Vue 库 -->
   <!-- <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script> -->
   <script src="https://cdn.bootcdn.net/ajax/libs/vue/2.7.9/vue.js"></script>
</head>
<body>

   <div id="app">
       <div>
           <button type="button" v-on:click="currentTab='tab-home'">Home</button>
           <button type="button" v-on:click="currentTab='tab-posts'">Posts</button>
           <button type="button" v-on:click="currentTab='tab-archive'">Archive</button>
       </div>
       <div style="border:solid 1px #000;padding:20px;">
           <!-- 失活的组件将会被缓存!-->
           <keep-alive>
               <!-- 动态组件,根据 currentTab 中的值(组件)动态加载组件 -->
               <component v-bind:is="currentTab"></component>
           </keep-alive>
       </div>
   </div>

   <script type="text/javascript">
       Vue.component("tab-home", {
           template: `
               <div>
                   <input type="checkbox" />
                   Home component
               </div>
           `
       });

       Vue.component("tab-posts", {
           template: `
               <div>
                   <input type="checkbox" />
                   Posts component
               </div>
           `
       });

       Vue.component("tab-archive", {
           template: `
               <div>
                   <input type="checkbox" />
                   Archive component
               </div>
           `
       });

       var app = new Vue({
           el: "#app",
           data: {
               currentTab: "tab-home"
           }
       });
   </script>

</body>
</html>
说说我的看法
全部评论(
没有评论
关于
本网站专注于 Java、数据库(MySQL、Oracle)、Linux、软件架构及大数据等多领域技术知识分享。涵盖丰富的原创与精选技术文章,助力技术传播与交流。无论是技术新手渴望入门,还是资深开发者寻求进阶,这里都能为您提供深度见解与实用经验,让复杂编码变得轻松易懂,携手共赴技术提升新高度。如有侵权,请来信告知:hxstrive@outlook.com
公众号