[译]Vue 动态组件

翻译自 Dynamic Components in Vue.js

这篇文章将会教你如何使用Vue中的 动态组件 。当创建小型的单页应用时,这些小型应用可能并不需要vue-router来控制路由,我们只想简单地切换不同的组件来达到不同的展示效果。

Vue中的动态组件要求你指定一个挂载点,在这个挂载点下你可以动态地切换组件。在这篇教程中,我们将通过几个例子来展示如何使用动态组件。我们会创建一个动态组件,学习使用keep-alive指令参数,最后我们还会在组件的切换之间添加一些过渡效果。下面开始吧:

创建动态组件

假设我们正在为一个Blog做个简单的导航栏,我们想添加两个页面:

  • 一个用于管理已经存在的博客文章
  • 一个用于创建新的博客文章

稍后,我们会组件化这两个页面。现在,让我们从头一步步来吧,我们把这个简单的应用挂载到body下:

newVue({
 el: 'body'
})

添加导航栏,在头部引入 BootStrop 3.3.6

<divclass="header clearfix">
<nav>
<ulclass="nav nav-pills pull-right">
<lirole="presentation">
<ahref="javascript:void(0)">Manage Posts</a>
</li>
<lirole="presentation">
<ahref="javascript:void(0)">Create Post</a>
</li>
</ul>
</nav>
<h3class="text-muted">Admin Panel</h3>
</div>

<divclass="container">
<!-- render the currently active component/page here -->
</div>

运行程序,我们会得到如下图所示的效果:

现在,我们这个小小的应用已经有了一个大概的结构,下面我们开始创建两个组件:一个用于管理已经存在的博客文章,一个用于创建新的博客文章。如果你还不了解如何在Vue中创建组件,建议你看看 这个教程 ,或者看官方的教程,那里已经说得够明白了。

下面创建一个 manage-posts 组件,并模拟一些文章标题数据:

Vue.component('manage-posts', {
 template: '#manage-template',
 data: function(){
return{
 posts: [
'Vue.js: The Basics',
'Vue.js Components',
'Server Side Rendering with Vue',
'Vue + Firebase'
 ]
 }
 }
})

接着为组件 manage-posts 创建一个模板:

<templateid="manage-template">
<div>
<h1>Manage Posts</h1>
<divclass="list-group">
<av-for="post in posts"href="#"class="list-group-item clearfix">
 {{ post }}
<spanclass="pull-right">
<buttonclass="btn btn-xs btn-info">
<spanclass="glyphicon glyphicon-edit"></span>
</button>
<buttonclass="btn btn-xs btn-warning">
<spanclass="glyphicon glyphicon-trash"></span>
</button>
</span>
</a>
</div>
</div>
</template>

效果

目前为止,我们已经有了导航栏和 mange-posts 组件,下面我们添加 create-post 组件,并把它们结合起来:

Vue.component('create-post', {
 template: '#create-template'
})

模板:

<templateid="create-template">
<div>
<h1>Create Post</h1>
<formclass="form-horizontal">
<divclass="form-group">
<labelclass="col-sm-2 control-label">Post title</label>
<divclass="col-sm-10">
<inputtype="text"class="form-control"placeholder="Post title">
</div>
</div>
<divclass="form-group">
<labelclass="col-sm-2 control-label">Post body</label>
<divclass="col-sm-10">
<textareaclass="form-control"rows="5"></textarea>
</div>
</div>
<divclass="form-group">
<divclass="col-sm-offset-2 col-sm-10">
<buttontype="submit"class="btn btn-primary">Create</button>
</div>
</div>
</form>
</div>
</template>

好了,组件都已准备完毕,下面我们进入本文重点:把这些组件制作成动态组件。

当一个用户点击 Manage Posts 按钮,我们想让Vue渲染manage-posts组件。同样的,当点击 Create Post 按钮,渲染create-post组件,

实现动态组件我们需要 <component> 元素,我们把它当做动态组件的挂载点,然后在该元素上通过 is 属性指定我们需要渲染的组件。如此,我们可以通过下面的方式渲染manage-post组件:

<divclass="container">
<!-- render the currently active component/page here -->
<componentis="manage-posts"></component>
</div>

效果图如下:

然而,这种硬编码的方式似乎不是所谓地 动态 ,我们目前仍然无法通过点击不同的按钮来展示不同的组件。

聪明的你也许已经想到了Vue的数据绑定。我们只需在data中定义一个名为currentView的属性,然后再对is属性进行数据绑定就行了,很简单:

newVue({
 el: 'body',
 data: {
 currentView: 'manage-posts'
 }
})
<divclass="container">
<!-- render the currently active component/page here -->
<component:is="currentView"></component>
</div>

最后,我们再给导航栏的两个按钮添加点击事件,这样用户每次点击即不同的按钮都会改变currentView的值,从而显示不同的组件:

...

<lirole="presentation">
<ahref="#"@click="currentView='manage-posts'">Manage Posts</a>
</li>

<lirole="presentation">
<ahref="#"@click="currentView='create-post'">Create Post</a>
</li>

...

下面是完整的代码:

keep-alive

目前我们已经知道了如何创建动态组件,下面我们说说更加重要的keep-alive。

现在当我们每次点击按钮切换组件时,旧的组件就会被销毁而新的组件会被渲染出来。

这样一来就存在一个问题,旧的组件因为被销毁从而丢失了所有的状态,当重新渲染这个组件时不得不重新调用它所需要的API来获取已经发表的文章(这里我们假设是从服务器获取文章)。为了避免这个问题,我们可以使用keep-alive指令参数来把切出去的组件保留在内存中,以保留它的状态或避免重新渲染:

<divclass="container">
<!-- render the currently active component/page here -->
<component:is="currentView"keep-alive></component>
</div>

在下面,我们可以验证被切出去的组件是否被保存在了内存中。我们可以在create-post组件中输入一些内容,接着切换组件,然后再切换回来。你会发现,我们输入的内容还在。

如果你的组件需要调用很多API或者渲染时需要大量的数据,那么这个指令参数会很有用。

组件间的过渡

下面,我们在组件切换间添加一些过度效果。

在组件的挂载点上,增加 transition 属性,我们使用简单的淡入淡出的过渡效果。

<divclass="container">
<component:is="currentView"transition="fade"transition-mode="out-in"></component>
</div>

添加CSS过渡控制:

.fade-transition{
transition: opacity0.2sease;
}

.fade-enter,.fade-leave{
opacity:0;
}

OK了:

你可能已经注意到了 transition-mode="out-in" 。这个属性告诉Vue,我们希望旧的组件先淡出,然后新的组件再淡入。否则的话,就会同时出现两个组件,一个淡出一个淡入,看上去相当别扭。

结束语

希望这篇教程能使你学会如何使用动态组件。这篇教程并不是为了说明动态组件可以替代 vue-router ,vue-router具有更多更有用的特性。对于一些简单的组件切换,我想动态组件可能会更合适。为了构建更好的SPA我觉得你应该学习一下vue-router。

我来评几句
登录后评论

已发表评论数()