Vue动态组件与异步组件实例详解

1 在动态组件上使用 keep-alive

我们之前曾经在一个多标签的界面中使用 is 特性来切换不同的组件:

<component v-bind:is="currentTabComponent"></component>

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

Vue动态组件与异步组件实例详解

你会注意到,如果你选择了一篇文章,切换到 Archive 标签,然后再切换回 Posts,是不会继续展示你之前选择的文章的。这是因为你每次切换新标签的时候,Vue 都创建了一个新的 currentTabComponent 实例。

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

<!-- 失活的组件将会被缓存!--> <keep-alive> <component v-bind:is="currentTabComponent"></component> </keep-alive>

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

html:

<div> <button v-for="tab in tabs" v-bind:key="tab" v-bind:class="['tab-button',{active:currentTab === tab}]" v-on:click="currentTab = tab" >{{ tab }} </button> <keep-alive> <component v-bind:is="currentTabComponent"></component> </keep-alive> </div>

js:

Vue.component('tab-posts', { data: function () { return { posts: [ { id: 1, title: '赶在618前夕,微信更新了两个支付与电商功能', content: '本周末,中国消费者即将迎来上半年最大的消费网购峰值,6月17日父亲节,6月18日端午节,也是京东、天猫等电商的618购物节。略微出人意料但又在情理之中的是,中国最大的社交平台微信,近日密集上线了两个与支付和电商相关的功能。' }, { id: 2, title: '腾讯要花32亿收购《绝地求生》开发商10%股份', content: '目前腾讯和蓝洞已经接近达成协议,如果交易成功,腾讯将成为蓝洞的第二大股东。' }, { id: 3, title: '这两个地球之眼是真的吗?形成原因至今仍是谜团', content: '一名俄罗斯男子乘坐直升机游览时,经过俄罗斯萨哈林岛(库页岛)时,看到一个巨大的坑洞。地球上坑坑洞洞很多,本该不用大惊小怪。但当飞机离得更近,换了个角度看这个坑时,他震惊了,这分明就是“地球的眼睛”。' } ], selectedPost: null } }, template: ` <div> <ul> <li v-for="post in posts" v-bind:key="post.id" v-bind:class="{selected:post === selectedPost}" v-on:click="selectedPost = post"> {{ post.title }} </li> </ul> <div> <div v-if="selectedPost"> <h3>{{ selectedPost.title }}</h3> <div v-html="selectedPost.content"></div> </div> <strong v-else> 请点击某个标签页 </strong> </div> </div> ` }); Vue.component('tab-archive', { template: '<div>archive 页面</div>' }); new Vue({ el: '#dynamic-component-demo', data: { currentTab: 'Posts', tabs: ['Posts', 'Archive'] }, computed: { currentTabComponent: function () { return 'tab-' + this.currentTab.toLowerCase(); } } });

css:

.tab-button { padding: 6px 10px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid #ccc; cursor: pointer; background: #f0f0f0; margin-bottom: -1px; margin-right: -1px; } .tab-button:hover { background: #e0e0e0; } .tab-button.active { background: #e0e0e0; } .tab { border: 1px solid #ccc; padding: 10px; } .posts-tab { display: flex; } .posts-sidebar { max-width: 40vw; margin: 0; padding: 0 10px 0 0; list-style-type: none; border-right: 1px solid #ccc; } .posts-sidebar li { white-space: nowrap; text-overflow: ellipsis; overflow: hidden; cursor: pointer; } .posts-sidebar li:hover { background: #eee; } .posts-sidebar li.selected { background: lightblue; } .selected-post-container { padding-left: 10px; } .selected-post > :first-child { margin-top: 0; padding-top: 0; }

效果:

Vue动态组件与异步组件实例详解

2 异步组件

在大型应用中,我们可能需要将应用分割成小一些的代码块,并且只在需要的时候才从服务器加载一个模块。为了简化,Vue 允许你以一个工厂函数的方式定义你的组件,这个工厂函数会异步解析你的组件定义。Vue 只有在这个组件需要被渲染的时候才会被触发,且会把结果缓存起来供未来重渲染。例如:

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/23d36192218bc07b509d3a32b8af711b.html