1、动态组件
Vue.js 提供了一个特殊的元素 <component> 用来动态地挂载不同的组件。如果我们打算在一个地方根据不同的状态引用不同的组件的话,比如tab页,就可以用到这一标签。
<template>
<div id="app">
<el-button-group>
<el-button type="primary" size="small" v-for="item in btnGroup" :key="item.id" @click="handleBtn(item.name)">{{item.name}}</el-button>
</el-button-group>
<div>
<keep-alive>
<component :is="curComponent"></component>
</keep-alive>
</div>
</div>
</template>
<script>
export default {
name: 'App',
data () {
return {
curComponent: 'comA',
btnGroup: [
{
id: 1,
name: '组件一'
},
{
id: 2,
name: '组件二'
}
]
}
},
components: {
comA: {
template: `<input placeholder="请输入名字" type="text"/>`
},
comB: {
template: `<p>2222222222</p>`
}
},
methods: {
handleBtn (name) {
if (name === '组件一') {
this.curComponent = 'comA'
}
if (name === '组件二') {
this.curComponent = 'comB'
}
}
}
}
</script>
当我们点击不同的按钮时,下面会切换不同的组件。实现动态组件的加载。is
的值可以是一个已经注册的组件的名字或者一个组件的选项对象。
如果我们需要频繁的切换页面,每次都是在组件的创建和销毁的状态间切换,这无疑增大了性能的开销。那么我们要怎么优化呢?
Vue
提供了动态组件的 缓存。keep-alive
会在切换组件的时候缓存当前组件的状态,等到再次进入这个组件,不需要重新创建组件,只需要从前面的缓存中读取并渲染。
2、异步组件
在大型应用中,我们可能需要将应用分割成小一些的代码块,并且只在需要的时候才从服务器加载一个模块。为了简化,Vue
允许你以一个工厂函数的方式定义你的组件,这个工厂函数会异步解析你的组件定义。Vue
只有在这个组件需要被渲染的时候才会触发该工厂函数,且会把结果缓存起来供未来重渲染。
异步组件存在的意义在于加载一个体量很大的页面时,如果我们不设置加载的优先级的话,那么可能页面在加载视频等信息的时候会非常占用时间,然后主要信息就会阻塞在后面在加载。这对用户来说无疑不是一个很差的体验。但是如果我们设置加载的顺序,那么我们可以优先那些最重要的信息优先显示,优化了整个项目。
异步组件大致有以下几种定义方式:
Vue.componenet('async-component', function (resolve) {
resolve({
template: `<p>{{msg}}</p>`,
data () {
return {
msg: '11111'
}
}
})
})
如你所见,这个工厂函数会收到一个 resolve 回调,这个回调函数会在你从服务器得到组件定义的时候被调用。你也可以调用 reject(reason) 来表示加载失败。
一个推荐的做法是将异步组件和 webpack 的 code-splitting 功能一起配合使用:
Vue.componenet('async-component', function (resolve) {
// 这个特殊的 `require` 语法将会告诉 webpack
// 自动将你的构建代码切割成多个包,这些包
// 会通过 Ajax 请求加载
require('[./my-async-component]', resolve)
})
你也可以在工厂函数中返回一个 Promise,所以把 webpack 2 和 ES2015 语法加在一起,我们可以写成这样:
// 这个 `import` 函数会返回一个 `Promise` 对象。
Vue.component('async-component', () => import('./async-component'))
注意:import函数
与import语句
作用是不一样的
当使用局部注册的时候,你也可以直接提供一个返回 Promise 的函数:
<script>
export default {
data () {
return {}
},
components: {
'async-component': () => import('./async-component')
//或者
'async-component': (resolve) => require.ensure([], () => resolve(require('./async-component')), 'component')
}
}
</script>
require.ensure方法由webpack提供,详细解释参考:
https://www.cnblogs.com/weiyuanquyu/p/8432044.html
2.1 异步组件配合webpack进行代码分割
为什么有时候要使用异步导入组件配合webpack进行代码分割呢?因为如果我们有一个组件非常庞大,把所有得组件都打包到app.vue入口文件中,当页面加载时将会非常慢,其中有一些组件在当前路由中并没有使用到,但也会被加载,这时导致页面加载非常慢的重要原因。如果这些组件只有在使用时才被加载,这样肯定会加快整个页面的加载速度,而webpack正好能够帮我们将异步组件单独打包成文件。
例子(vue-cli搭建项目):
组件A:
<template>
<div>
<p>11111111111</p>
<com-b></com-b>
</div>
</template>
<script>
// import comB from '../asyncComponentB/index'
export default {
name: 'comA',
components: {
'comB': () => import('../asyncComponentB/index')
// comB
},
data () {
return {
}
}
}
</script>
组件B:
<template>
<p>222222222</p>
</template>
<script>
export default {
name: 'comB',
components: {
'comC': (resolve) => require.ensure([], () => resolve(require('../asyncComponentC/index')), 'comC')
},
data () {
return {}
}
}
</script>
组件C:
<template>
<p>33333333333333333334444444444433</p>
</template>
<script>
export default {
name: 'comC',
data () {
return {}
}
}
</script>
app.vue:
<template>
<div id="app">
<com-a></com-a>
</div>
</template>
<script>
// import comA from './components/asyncComponentA'
export default {
name: 'App',
data () {
return {
}
},
components: {
comA: () => import('./components/asyncComponentA')
// comA
}
}
</script>
运行npm run build --report
可以看到A、B、C三个组件被打包成独立文件
参考:
https://cn.vuejs.org/v2/guide/components-dynamic-async.html
https://segmentfault.com/a/1190000018018502?utm_source=tag-newest
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。