如何把vue resolve => requirvue 封装公共ajax处理成一个公共函数

中国领先的IT技术网站
51CTO旗下网站
如何使用vue开发波纹点击特效组件
最近在使用 vue2 做一个新的 material ui 库,波纹点击效果在 material design 中被多次使用到,于是决定把它封装成一个公共的组件,使用时直接调用就好啦。
作者:绫宇来源:| 21:37
最近在使用 vue2 做一个新的 material ui 库,波纹点击效果在 material design
中被多次使用到,于是决定把它封装成一个公共的组件,使用时直接调用就好啦。
开发之前的思考
常见的波纹点击效果的实现方式是监听元素的 mousedown 事件,在元素内部创建一个 波纹元素 ,并调整元素的 transform: scale(0);
到 transform: scale(1);, 通过计算点击的位置来设置 波纹元素 的大小和位置,以达到波纹扩散的效果。
我将组件分为两个部分, circleRipple.vue 和 TouchRipple.vue 各自实现不同的功能
circleRipple.vue 波纹扩散组件,完成波纹扩散的效果
TouchRipple.vue 监听 mouse 和 touch 相关事件,控制 circleRipple 的显示,位置。
circleRipple.vue
circleRipple 需要完成波纹扩展的效果,而且可以从外部控制它的大小和位置, 所以利用 vue 的 transition 动画完成效果,
提供mergeStyle 、 color 、opacity 参数来从外部控制它的样式。实现代码如下。
&template&&&&&transition&name=&mu-ripple&&&&&&&&div&class=&mu-circle-ripple&&:style=&styles&&&/div&&&&&/transition&&&/template&&&&script&&import&{merge}&from&'../utils'&export&default&{&&&props:&{&&&&&mergeStyle:&{&&&&&&&type:&Object,&&&&&&&default&()&{&&&&&&&&&return&{}&&&&&&&}&&&&&},&&&&&color:&{&&&&&&&type:&String,&&&&&&&default:&''&&&&&},&&&&&opacity:&{&&&&&&&type:&Number&&&&&}&&&},&&&computed:&{&&&&&styles&()&{&&&&&&&return&merge({},&{color:&this.color,&opacity:&this.opacity},&this.mergeStyle)&&&&&}&&&}&}&&/script&&&&style&lang=&less&&&@import&&../styles/import.less&;&.mu-circle-ripple{&&&position:&absolute;&&&width:&100%;&&&height:&100%;&&&left:&0;&&&top:&0;&&&pointer-events:&&&&user-select:&&&&border-radius:&50%;&&&background-color:&currentC&&&background-clip:&padding-&&&opacity:&0.1;&}&&.mu-ripple-enter-active,&.mu-ripple-leave-active{&&&transition:&transform&1s&@easeOutFunction,&opacity&2s&@easeOutF&}&&.mu-ripple-enter&{&&&transform:&scale(0);&}&&.mu-ripple-leave-active{&&&opacity:&0&!&}&&/style&&
vue2 对于动画方面做了比较大的修改,除了把指令换成组件外,它还可以完成更复杂的动画效果,具体可以看这里 vue2 transition
TouchRipple.vue
TouchRipple 需要控制 circleRipple 的显示。完成以下内容:
监听 mouse 和 touch 相关事件, 控制 circleRipple 的显示。
通过点击事件 event 对象, 计算出 circleRipple 的大小和位置
如果频繁点击可能出现多个 circleRipple
首先,基本模板 + 数据模型
&&&&&&&@mousedown=&handleMouseDown&&@mouseup=&end()&&@mouseleave=&end()&&@touchstart=&handleTouchStart&&&@touchend=&end()&&@touchcancel=&end()&&&&&&&&&&&&:style=&style&&ref=&holder&&&&&&&&&&&&&&&&:key=&ripple.key&&:color=&ripple.color&&:opacity=&ripple.opacity&&:merge-style=&ripple.style&&v-for=&ripple&in&ripples&&&&&&&&&&&&&&&&&&&&&&&import&circleRipple&from&'./circleRipple'&export&default&{&&&props:&{&&&&&//&是否从中间扩散,设为false会从点击处扩散&&&&&centerRipple:&{&&&&&&&type:&Boolean,&&&&&&&default:&true&&&&&},&&&&&//&外层包裹的样式&&&&&style:&{&&&&&&&type:&Object,&&&&&&&default&()&{&&&&&&&&&return&{&&&&&&&&&&&height:&'100%',&&&&&&&&&&&width:&'100%',&&&&&&&&&&&position:&'absolute',&&&&&&&&&&&top:&'0',&&&&&&&&&&&left:&'0',&&&&&&&&&&&overflow:&'hidden'&&&&&&&&&}&&&&&&&}&&&&&},&&&&&//&波纹颜色&&&&&color:&{&&&&&&&type:&String,&&&&&&&default:&''&&&&&},&&&&&//&波纹透明度&&&&&opacity:&{&&&&&&&type:&Number&&&&&}&&&},&&&data&()&{&&&&&return&{&&&&&&&nextKey:&0,&//&记录下一个波纹元素的key值,&相当于uuid,不设置的话会使动画失效&&&&&&&ripples:&[]&//&波纹元素参数数组&&&&&}&&&},&&&mounted&()&{&&&&&this.ignoreNextMouseDown&=&false&//&防止既有&touch&又有&mouse点击的情况&&&},&&&methods:&{&&&&&start&(event,&isRippleTouchGenerated)&{&&&&&&&//&开始波纹效果&&&&&},&&&&&end&()&{&&&&&&&//&结束波纹效果&&&&&},&&&&&handleMouseDown&(event)&{&&&&&&&//&监听&鼠标单击&&&&&},&&&&&handleTouchStart&(event)&{&&&&&&&//&监听&touchstart&方法&&&&&}&&&},&&&components:&{&&&&&'circle-ripple':&circleRipple&&&}&}&&
开始和结束波纹效果
增加一个波纹元素只需要在 ripple 增加一个 object 即可,不同的是当需要从点击处扩展时,需要计算一下波纹元素的大小和位置。
{&&&//&isRippleTouchGenerated&是否是touch&事件开始的&&&start&(event,&isRippleTouchGenerated)&{&&&&&//&过滤&touchstart&和&mousedown&同时存在的情况&&&&&if&(this.ignoreNextMouseDown&&&&!isRippleTouchGenerated)&{&&&&&&&this.ignoreNextMouseDown&=&false&&&&&&&return&&&&&}&&&&&&&&&&//&添加一个&波纹元素组件&&&&&this.ripples.push({&&&&&&&key:&this.nextKey++,&&&&&&&&color:&this.color,&&&&&&&opacity:&this.opacity,&&&&&&&style:&this.centerRipple&?&{}&:&this.getRippleStyle(event)&//&不是从中心扩展的需要计算波纹元素的位置&&&&&})&&&&&this.ignoreNextMouseDown&=&isRippleTouchGenerated&&},&&end&()&{&&&&if&(this.ripples.length&===&0)&return&&&&this.ripples.splice(0,&1)&//&删除一个波纹元素&&&&this.stopListeningForScrollAbort()&//&结束&touch&滚动的处理&&&}&}&
因为 vue2 基于 Virtual DOM 的, 所以如果没有 key 在增加一个元素又同时删除一个元素的时候,dom
tree并没有发生变化,是不会产生动画效果的。
监听 mousedown 和 touchstart
mousedown 和 touchstart 处理上会有所不同,但都是用来启动波纹效果的, touch涉及到多点点击的问题,我们一般取第一个即可。
{&&&&&handleMouseDown&(event)&{&&&&&&&//&只监听鼠标左键的点击&&&&&&&if&(event.button&===&0)&{&&&&&&&&&this.start(event,&false)&&&&&&&}&&&&&},&&&&&handleTouchStart&(event)&{&&&&&&&event.stopPropagation()&//&防止多个波纹点击组件嵌套&&&&&&&if&(event.touches)&{&&&&&&&&&this.startListeningForScrollAbort(event)&//&启动&touchmove&触发滚动处理&&&&&&&&&this.startTime&=&Date.now()&&&&&&&}&&&&&&&this.start(event.touches[0],&true)&&&&&}&}&
touchmove控制
当发生touchMove事件是需要判断是否,移动的距离和时间,然后结束小波纹点击小姑
{&&&//&touchmove&结束波纹控制&&&stopListeningForScrollAbort&()&{&&&&&if&(!this.handleMove)&this.handleMove&=&this.handleTouchMove.bind(this)&&&&&document.body.removeEventListener('touchmove',&this.handleMove,&false)&&&},&&&startListeningForScrollAbort&(event)&{&&&&&this.firstTouchY&=&event.touches[0].clientY&&&&&this.firstTouchX&=&event.touches[0].clientX&&&&&document.body.addEventListener('touchmove',&this.handleMove,&false)&&&},&&&handleTouchMove&(event)&{&&&&&const&timeSinceStart&=&Math.abs(Date.now()&-&this.startTime)&&&&&if&(timeSinceStart&&&300)&{&&&&&&&this.stopListeningForScrollAbort()&&&&&&&return&&&&&}&&&&&const&deltaY&=&Math.abs(event.touches[0].clientY&-&this.firstTouchY)&&&&&const&deltaX&=&Math.abs(event.touches[0].clientX&-&this.firstTouchX)&&&&&//&滑动范围在&&&6px&结束波纹点击效果&&&&&if&(deltaY&&&6&||&deltaX&&&6)&this.end()&&&}&}&
计算波纹的位置和大小
需要从点击处扩散的波纹效果,需要计算波纹元素的大小和位置
{&&&getRippleStyle&(event)&{&&&&&let&holder&=&this.$refs.holder&&&&&//&&这个方法返回一个矩形对象,包含四个属性:left、top、right和bottom。分别表示元素各边与页面上边和左边的距离。&&&&&let&rect&=&holder.getBoundingClientRect()&&&&&&//&获取点击点的位置&&&&&let&x&=&event.offsetX&&&&&let&y&&&&&if&(x&!==&undefined)&{&&&&&&&y&=&event.offsetY&&&&&}&else&{&&&&&&&x&=&event.clientX&-&rect.left&&&&&&&y&=&event.clientY&-&rect.top&&&&&}&&&&&//&获取最大边长&&&&&let&max&&&&&if&(rect.width&===&rect.height)&{&&&&&&&max&=&rect.width&*&1.412&&&&&}&else&{&&&&&&&max&=&Math.sqrt(&&&&&&&&&(rect.width&*&rect.width)&+&(rect.height&*&rect.height)&&&&&&&)&&&&&}&&&&&const&dim&=&(max&*&2)&+&'px'&&&&&return&{&&&&&&&width:&dim,&&&&&&&height:&dim,&&&&&&&//&通过margin控制波纹中心点和点击点一致&&&&&&&'margin-left':&-max&+&x&+&'px',&&&&&&&'margin-top':&-max&+&y&+&'px'&&&&&}&&&}&}&
由于 touchRipple 内部都是 position:absolute 布局,使用时,需要在外部加上 position:relative
//&listItem.vue&&a&:href=&href&&@mouseenter=&hover&=&true&&@mouseleave=&hover&=&false&&@touchend=&hover&=&false&&&&&&@touchcancel=&hover&=&false&&class=&mu-item-wrapper&&:class=&{'hover':&hover}&&&&&&&&touch-ripple&class=&mu-item&&:class=&{'mu-item-link':&link}&&:center-ripple=&false&&&&&&&&&&div&class=&mu-item-media&&&&&&&&&&&&slot&name=&media&&&/slot&&&&&&&&&/div&&&&&&&&&div&class=&mu-item-content&&&&&&&&&&&//&...&&&&&&&&/div&&&&&&&/touch-ripple&&&/a&&&style&&&.mu-item-wrapper&{&&&&&display:&&&&&&color:&&&&&&position:&relative;&}&&/style&&
到这点击波纹组件就开发完了, 这些代码借鉴了 keen-ui 和 material-ui 的实现方式。【编辑推荐】【责任编辑: TEL:(010)】
大家都在看猜你喜欢
头条头条头条外电头条
24H热文一周话题本月最赞
讲师:1人学习过
讲师:24人学习过
讲师:0人学习过
精选博文论坛热帖下载排行
本书重点介绍了主流ARM应用系统的开发与实践。全书基于目前较为通用、流行的ARM处理器,介绍了其原理、硬件结构、硬件电路设计与开发和软件...
订阅51CTO邮刊最近项目上的事情不多,根据我自己的开发习惯,决定开发一些简单的开发架子,方便以后事情多的时候直接套用。本文讲的一个gulp+webpack+vue的单页应用架子,想要达到的目的:
可以通过命令打包开发chunk,并支持热替换
可以通过命令打包可发布的chunk
路由中的代码实现按需加载
用CommonJs的风格组织代码
代码结构尽量清晰易懂
尽我所能先做出一个满足以上特点的架子吧,最近看完ES6,准备再去看看flux和reduce,看过之后再来思考下前端数据如何管理比较科学规范。架子中有做的不规范可改进的地方,烦请大家指出,我好更新。
首先来看一下整个架子的结构:
2.1合并库文件
库文件不会随业务代码发生变化,所以所有库文件打包成一个文件就好了,这部分代码需要直接在页面中以 &script&&/script& 标签引入,不能和业务代码打包到一起。如果和业务代码打包到一起,一旦业务代码发生变化,整个打包的文件在浏览器中都需要被重新加载,这种做法不利于客户端做缓存,也会使webpack打包业务代码的过程变得非常慢,所以这里使用gulp合并一下库文件:
/** * 合并lib文件 */gulp.task('concat-lib',function(){
gulp.src(['vue/dist/vue.min.js','vue-router/dist/vue-router.min.js'],{
cwd:'../lib'
}).pipe(concat('vue.min.js')).pipe(gulp.dest('../release'));})
2.2组织业务代码
从上图可以看到,所有的业务开发代码都放在src目录下,展开来看:
components目录用来存放公用的vue组件,这块架子中没有,所以是空着的
css用来存放所有的样式文件,modules和components目录下分别存放各模块和各个组件所使用的样式,app.css是主入口页面样式,main.css是所有样式。把样式集中起来是为了方便样式的打包。
modules用来存放各个模块的代码,模块的模板和js代码放在同一目录下。
app.js是程序主入口js,在此文件中定义单页应用的路由,指向各个模块
index.html是应用主页面
核心代码是这块:
var Vue = require('vue')var VueRouter = require('vue-router');Vue.use(VueRouter);var compo1=require('./modules/module1');require('./css/main.css');// 路由器需要一个根组件。// 出于演示的目的,这里使用一个空的组件,直接使用 HTML 作为应用的模板var App = Vue.extend({})// 创建一个路由器实例// 创建实例时可以传入配置参数进行定制,为保持简单,这里使用默认配置var router = new VueRouter()// 定义路由规则// 每条路由规则应该映射到一个组件。这里的“组件”可以是一个使用 Vue.extend// 创建的组件构造函数,也可以是一个组件选项对象。// 稍后我们会讲解嵌套路由router.map({
component: compo1
'/path1': {
component: compo1
'/path2': {
component: function (resolve) {
//amd规范 实现效果:
//路由1中的模块和主页面模块打包在一起
//路由2中的模块按需加载
require(['./modules/module2'],resolve);
//commonJs规范实现方式:
//require.ensure([],function(require){
var comm2=require('./components/compo2');
resolve(comm2)
}});//默认路径//router.go('/path1');// 现在我们可以启动应用了!// 路由器会创建一个 App 实例,并且挂载到选择符 #app 匹配的元素上。router.start(App, '#app')
默认模块是moduel1,/path1路由指向module1,/path2路由指向module2,module2的模块并不是和module1一样在主页面中一开始就加载好的,而是在路由到此路径后才去加载,app.js中提供了vue组件文档中提供的两种方式:CommonJs和AMD两种规范的方式来加载,两种方式是等价的。
require('./css/main.css'); 把所有css加载到应用中,以便在开发模式下可以看到样式,在打包发布代码的时候会忽略此require,将样式打包成独立的文件。
2.3打包开发代码
打包开发代码的webpack配置是build目录下的webpack.config.dev.js
var webpack = require('webpack');var path=require('path');module.exports={
//这里写成数组是为了dev server插入服务配置
&app&:['../src/app.js'],
path:path.resolve(__dirname, &../release&),//__dirname+'/../release',
publicPath: &/release/&,//dev server 会从此路径去拿hot-update.json
filename:'[name].bundle.js'
externals: {
'vue': 'Vue',
'vue-router':'VueRouter'
loaders: [
{ test: //.css$/, loader: 'style-loader!css-loader' },
{test://.html$/,loader:'html-loader'}
plugins: [
devtool: &source-map&}
程序主入口是app.js,所有entry只需要配置一个app.js。
output配置中的publicPath是用来配置项目中静态文件路径的,这里开发过程中会使用webpack-dev-server,给配置到release目录下就行了。
externals下面配置的是通过标签引入,可以在全局环境下访问到的变量,可以通过require这里配置的key来获取那些变量。
devtool: &source-map& 可以为压缩之后的代码生成source-map文件,这里开发打包的代码并没有被压缩,所以这个其实没意义。
{test://.html$/,loader:'html-loader'} 是用来在组件中加载html模板的:
var template=require('./module1.html');// 定义组件var comm = Vue.extend({
template: template,
data:function () {
items:[{a:1,b:2,c:3},{a:4,b:5,c:5},{a:7,b:8,c:9}]
用上面的配置来打包,就会得到开发版本的打包代码了。
2.4使用webpack-dev-server和热替换插件HotModuleReplacementPlugin
为了方便开发调试,需要启动一个server来访问项目,并支持热替换,自动刷新浏览器,以方便修改代码之后能够实时看到效果。
在gulpfile.js做如下配置:
ar webpackConfigDev=require(&./webpack.config.dev.js&);var WebpackDevServer = require(&webpack-dev-server&);/** * 使用测试配置打包,启动hot dev server */gulp.task('webpack-dev',['concat-lib'],function(){
var config = Object.create(webpackConfigDev);
//这两项配置原本是在webpack.config.dev.js里边配置,可是通过gulp启动devserver,那种配置无效,只能在此处写入
//官网的解释是webpack-dev-server没有权限读取webpack的配置
config.entry.app.unshift(&webpack-dev-server/client?http://localhost:8080/&, &webpack/hot/dev-server&);
config.plugins.push(new webpack.HotModuleReplacementPlugin());
var compiler = webpack(config);
var server = new WebpackDevServer(compiler, {
contentBase: &../&,
publicPath: &/release/&,
hot: true,
compress: false,
stats: { colors: true }
server.listen(8080, &localhost&, function() {});
// server.close();});
这样会启动一个本地的8080端口监听,用来访问某个目录下的静态文件
contentBase: &../& 配置,指定了静态文件目录在项目根目录下,所以访问 http://localhost:8080 会看到根目录下的文件列表,点进去src目录,就会默认访问index.html,看到单页应用的效果了
publicPath: &/release/& 这个配置很重要,它指定了webpack-dev-server提供的打包静态文件路径,值得注意的是,使用WebpackDevServer的时候,并不会在release目录生成webpack打包文件,只会在内存中生成打包文件,通过localhost:8080/release/ 路径,可以访问到开发打包后的代码。
通过gulp启动此server之后,访问 http://localhost:8080/src 路径,可以看到用下面的效果:
可以看到,访问主页面的时候,加载了app.bundle.js打包文件,访问路由/path2的时候,才会去加载1.1.bundle.js文件,子组件是延迟2s后才加载的。
更新代码之后,会实时打包并刷新浏览器,看到实时效果。
2.5打包生产环境代码
和开发代码不同,生产环境代码具有以下特点:
代码需要压缩
打包生成的文件名中需要包含文件hash值,以方便控制客户端缓存
css不能像开发环境那样打包到js代码中,需要打包成独立的文件,在页面开头直接引入
基于以上特点,webpack配置文件如下:
var webpack = require('webpack');var ExtractTextPlugin = require(&extract-text-webpack-plugin&);var path=require('path');var cssExtract=new ExtractTextPlugin(&[name].[contenthash:8].css&);module.exports={
index:'../src/app.js'
path:path.resolve(__dirname, &../release&),
publicPath:&&,//TODO 填写生产环境静态文件路径
filename:'[name].[chunkhash:8].bundle.js'
externals: {
'vue': 'Vue',
'vue-router':'VueRouter'
loaders: [
{ test: //.css$/, loader: cssExtract.extract(&style-loader&, &css-loader&) },
{test://.html$/,loader:'html-loader'}
plugins: [
new webpack.optimize.UglifyJsPlugin({
compress: {
drop_console: true,
warnings: false
cssExtract
其中publicPath是填写静态文件路径的,如果图片或其他静态资源需要存放在CDN服务器上,可以把CDN地址配置到这里。
生成打包文件之后,可以通过gulp替换掉主入口文件 index.html里面的静态文件路径,这里通过webpack模板也可以完成此工作,但配置较为繁琐,个人感觉还是通过gulp来替换比较方便一点:
gulp.src('../src/index.html')
//.pipe(greplace(/xxxxx/g,&xxxxx&))
.pipe(gulp.dest('../release'));
打包后的代码:
后面的步骤就是上传静态文件到CDN或其他上线流程了,这里可以通过根据自己业务编写的gulp插件来完成,大家业务不同,处理方式不尽相同,我就不继续往下写了。
3.把命令都整合到npm中
我个人不太喜欢项目根目录下一堆跟打包相关的文件,所以在这个项目中,我把所有跟打包相关的文件都放到了build目录下,然后在package.json中:
&scripts&: {
&dev&: &gulp default --gulpfile build/gulpfile.js&,
&build&: &gulp build --gulpfile build/gulpfile.js&,
&release&: &gulp release --gulpfile build/gulpfile.js&
这样就可以使用npm命令来执行上面的操作了:
npm run dev 启动webpack-dev-server,使用开发webpack配置来打包代码,支持热替换
npm run build 打包开发代码
npm run release 打包生产环境代码
最新教程周点击榜
微信扫一扫Vue 项目中使用 webpack 将多个组件合并打包 - 推酷
Vue 项目中使用 webpack 将多个组件合并打包
使用 Vue 开发项目时,如果要使用其单文件组件特性,必然要使用 webpack 或者 browserify 进行打包,对于大型应用,为了提升加载速度,可以使用 webpack 的 code split 功能进行分割打包,生成较小的模块并按需加载,这在 Vue 文档及 vue-router 文档中均有介绍:
webpack 的 code split 可以使用 webpack 的 require.ensure 特殊语法或者使用 AMD 风格的 callback-require 语法,以 AMD 风格的 callback-require 语法为例——
全局注册 Async Component:
let myAsyncComponent = resolve =& {
require(['./my-async-component'], resolve)
ponent('async-webpack-example', myAsyncComponent)
局部注册 Async Component,单文件组件中 script 块内容:
let myAsyncComponent = resolve =& {
require(['./my-async-component'], resolve)
// Vue 扩展实例选项,其他选项略
export default {
components: {
'async-webpack-example': myAsyncComponent
在使用 vue-router 时,为实现不同路由下的组件异步加载,在路由映射中可以使用同样的方式来设置路由项的 component 属性。
这里的 myAsyncComponent 被定义为一个工厂函数,在需要时才会以 Vue 或者 vue-router 定义的用于解析组件选项的 resolve 回调函数(是的,在 Vue 和 vue-router 中有两个不同的解析组件选项的函数)为参数执行 callback-require 函数(resolve 回调函数的参数是组件选项),这样,在执行打包脚本时,my-async-component.vue 文件会被单独打包成一个文件,并且仅当该组件被使用时才会加载。
当要求异步加载的组件较多时,将会生成更多的单个文件,对于前端性能而言,虽然每个文件更小了,但可能意味着更多的网络连接建立和关闭的开销,因此在前端优化的实践中,通常需要在文件数量和单个文件大小之间取得平衡。
本文介绍如何将多个组件合并打包成一个单独的文件,一方面可以减少代码块的数量,另一方面,如果合并打包的这些组件在不同地方多次重复使用,由于 Vue 的缓存机制,可以加快后续组件的加载速度,并且如果这些通用组件长时间不会变化(如 UI 相关的组件),打包生成的文件也长期不会变化,可以充分利用浏览器的缓存功能,实现前端加载速度的优化。
先上效果图,在使用 vue-router 的 SPA 应用中,将除根路由之外的路由项对应的 ComponentA、ComponentB、ComponentC 等三个组件合并打包成一个文件。初次加载页面时,从开发者工具的 Network 面板上可以看到,此时未加载包含 ComponentA、ComponentB、ComponentC 这三个组件的 0.a5a1bae6addad442ac82.js 文件,当点击 Page A 链接时,加载了该文件,然后再点击 Page B、Page C 链接时,没有重新加载该文件。
我们首先通过 vue-cli 命令行工具使用 webpack 项目模板创建一个包含 vue-router 的项目,在其 src/components 目录下创建一个 CommonComponents 目录,在该目录中创建 ComponentA、ComponentB、ComponentC 这三个组件。
同时在 CommonComponents 目录下创建 index.js,其内容如下:
ponentA = require('./ComponentA')
ponentB = require('./ComponentB')
ponentC = require('./ComponentC')
这样,我们只需要使用 webpack 的 require.ensure 特殊语法或者使用 AMD 风格的 callback-require 语法异步加载 CommonComponents 目录下的 index.js,在使用 webpack 进行打包时,就可以实现将 ComponentA、ComponentB、ComponentC 这三个组件合并打包。以 AMD 风格的 callback-require 语法为例示范如下,这里的 callback 回调函数的形式没有任何特殊要求。
require(['component/CommonComponents'], function (CommonComponents) {
// do whatever you want with CommonComponents
component/CommonComponents 模块加载成功时,这里的回调函数中的 CommonComponents 参数将会是一个包含 ComponentA、ComponentB、ComponentC 这三个组件选项的对象。
在定义异步解析组件时,我们使用的是一个工厂函数 resolve =& {require(['./my-async-component'], resolve)} ,如果需要在路由配置文件中添加 component 属性为 ComponentA 组件的路由项,应该定义什么样的工厂函数呢?记住这里的 resolve 是 Vue 定义的一个用于解析组件选项的回调函数,其参数是所获取的组件选项,而上一段代码中的 CommonComponents 恰好是包含若干个组件选项的对象,因此我们可以将 CommonComponents 的子属性作为参数用于 resolve 调用,我们可以编写一个函数 getCommonComponent,用于根据组件名称返回获取相应的组件选项的工厂函数。
let getCommonComponent = componentName =& resolve =& require(['components/CommonComponents'], components =& resolve(components[componentName]))
在组件模板或者路由映射等使用其中某一个组件的地方,可以使用类似于 getCommonComponent('ComponentA') 这样的函数调用进行组件设置,在路由映射中的使用示例如下:
path: '/',
name: 'Hello',
component: Hello
path: '/a',
name: 'A',
component: getCommonComponent('ComponentA')
path: '/b',
name: 'B',
component: getCommonComponent('ComponentB')
path: '/c',
name: 'C',
component: getCommonComponent('ComponentC')
最终打包生成的文件列表如下图所示,其中的 0.a5a1bae6addad442ac82.js 包含了 ComponentA、ComponentB、ComponentC 这三个组件。
已发表评论数()
请填写推刊名
描述不能大于100个字符!
权限设置: 公开
仅自己可见
正文不准确
标题不准确
排版有问题
主题不准确
没有分页内容
图片无法显示
视频无法显示
与原文不一致

我要回帖

更多关于 vue require使用 的文章

 

随机推荐