vue 怎么vue import引入外部js纯函数的模块

Vue与React两个框架的区别和优势对比-前端开发博客
推荐文章 13964Views 3673Views 339Views 2312Views 8001Views热门文章
6,216Views
3,867Views
3,715Views
2,782Views
1,676Views
1,518Views
对这篇文章不满意吗?百度搜索:");&img src=&/50/v2-7dfcb2eb7c_b.jpg& data-rawwidth=&740& data-rawheight=&411& class=&origin_image zh-lightbox-thumb& width=&740& data-original=&/50/v2-7dfcb2eb7c_r.jpg&&&h2&&b&一、写在前面&/b&&/h2&&blockquote&产品经理:那谁,那个创建订单流程能不能改一下,改成创建订单的同时直接调取淘宝、微信支付,前端可以处理吧......&br&&br&设计:喂喂喂,这个这个这个二级导航高度不要55px,全部改成48px吧.....&br&&br&测试:卧槽,死前端过来,那个预约按钮又显示不出来了,服务端返回的状态是4,快看一下.....&br&&br&服务端:(1)这个验证应该要在先放在前端验证吧,我还有一堆后台没做;(2)这个列表更新不频繁,前端先写死吧.....&br&&br&项目经理:靠,在锤子手机原生浏览器下,https的图片没办法显示啊,会有“私密连接”报警,前端快看一下......&br&&br&运维:你这个前端上线,要把服务端构建命令和前端构建命令合并成一个命令,并且把package.json 挪到顶级目录......&/blockquote&&p&&br&&/p&&p&对!据我所知,很多团队把前端归类成差不多万能的岗位,所有体现问题的都要走到前端人员处理。&/p&&p&当然,只要能出好产品,It doesn't matter,烦点就烦点呗!&/p&&p&毕竟,很多团队测试是不测接口的,那么发现bug都是从前端发现的。&/p&&p&&br&&/p&&img src=&/v2-b2efbdf3a3e7651dcf1bc73_b.jpg& data-caption=&& data-rawwidth=&350& data-rawheight=&188& data-thumbnail=&/v2-b2efbdf3a3e7651dcf1bc73_b.jpg& class=&content_image& width=&350&&&p&&br&&/p&&p&理论上,团队中所有的成员都是有很大机会给前端提需求的。工作如此复杂,那如果不能有个体验好的开发环境,处理起这些需求,很容易就把自己套死了。&/p&&blockquote&注:这并不是一篇webpack api文档,所以不涉及具体的配置。具体webpack api可以上webpack官网查看&/blockquote&&p&&br&&/p&&h2&&b&二、给自己提一份需求&/b&&/h2&&blockquote&Q:什么样的开发环境才是好的开发环境?&br&A:天行健,君子以自强不息......&/blockquote&&p&那那那,我们就先给自己提个需求吧!&/p&&ol&&li&代码逻辑太复杂,所以开发过程中需要断点调试!&/li&&li&不想手动刷新,所以需要热加载!&/li&&li&写更漂亮的代码,所以需要支持es6、sass!&/li&&li&不想每次都import jquery,所以需要引入到全局!&/li&&li&图片太大了,所以需要压缩图片!&/li&&li&需要部署多个环境,开发环境、测试环境、beta环境、正式环境!&/li&&li&服务端,需求并不确定,可能会频繁的需要改tmd构建目录!&/li&&li&有些页面,服务端没时间开发,需要前端写死!&/li&&li&他们说,图片需要发布CDN!&/li&&li&CND可能会有缓存,现在还不确定静态资源用文件hash的形式好,还是参数hash的形式好!&/li&&li&好多人合作,所以需要检查代码规范!&/li&&li&.........&/li&&/ol&&p&嗯!嗯!暂时可以想到的需求就这些。&/p&&p&&br&&/p&&h2&&b&三、Webpack是什么?&/b&&/h2&&blockquote&Q:怎样才能不被牵着鼻子走?&br&A:知其然知其所以然......&/blockquote&&p&那那那,我们就先简单了解下webpack吧!&/p&&blockquote&简单理解是:webpack是打包工具,它将许多松散的模块(css、js、图片、字体等)按照一定的依赖和规则打包成符合生产环境部署的前端资源。&br&&br&比如:通过一个的主文件(如:app.js),webpack将从这个主文件开始找到所有依赖文件(js、css、图片、字体等),使用一定的规则(如:babel-loader、sass-loader、file-loader等)、插件(如:ExtractTextPlugin、HtmlWebpackPlugin等)处理它们,最后构建为符合上线部署的文件(如:bundle.js)。&/blockquote&&p&这就涉及到四个个概念主文件、规则、插件、构建后的文件。我们以这三个来了解webpack吧!&/p&&p&&b&(1)主文件:&/b&Entry&/p&&p&webpack中主文件以entry属性{ key: value }来组件主文件;如下:&/p&&div class=&highlight&&&pre&&code class=&language-js&&&span&&/span&&span class=&nx&&entry&/span&&span class=&o&&:&/span& &span class=&p&&{&/span&
&span class=&nx&&app&/span&&span class=&o&&:&/span& &span class=&s1&&'../font/app.js'&/span&&span class=&p&&,&/span&
&span class=&nx&&common&/span&&span class=&o&&:&/span& &span class=&p&&[&/span&&span class=&s1&&'jquery'&/span&&span class=&p&&,&/span& &span class=&s1&&'../font/common_js/common.api.js'&/span&&span class=&p&&,&/span& &span class=&s1&&'../font/common_js/common.base.js'&/span&&span class=&p&&]&/span&
&span class=&p&&}&/span&
&/code&&/pre&&/div&&p&上面配置中包括两个主文件:&/p&&p&app:应用程序js&/p&&p&common:共用代码js,这些代码是每个功能都需要页面都需要用的,所以把它分离到common中。&/p&&p&&br&&/p&&p&&b&(2)规则module rules&/b&&/p&&p&webpack2.0后规则以module.rules属性{key: value}来组织规则;如下:&/p&&div class=&highlight&&&pre&&code class=&language-js&&&span&&/span&&span class=&nx&&module&/span&&span class=&o&&:&/span& &span class=&p&&{&/span&
&span class=&nx&&rules&/span&&span class=&o&&:&/span& &span class=&p&&[&/span&
&span class=&p&&{&/span&
&span class=&nx&&test&/span&&span class=&o&&:&/span& &span class=&sr&&/\.js$/&/span&&span class=&p&&,&/span&
&span class=&nx&&loader&/span&&span class=&o&&:&/span& &span class=&s1&&'babel-loader'&/span&&span class=&p&&,&/span&
&span class=&nx&&exclude&/span&&span class=&o&&:&/span& &span class=&sr&&/(node_modules)/&/span&&span class=&p&&,&/span&
&span class=&p&&},&/span&
&span class=&p&&{&/span&
&span class=&nx&&test&/span&&span class=&o&&:&/span& &span class=&sr&&/\.(png|jpg|gif|svg)$/&/span&&span class=&p&&,&/span&
&span class=&nx&&loader&/span&&span class=&o&&:&/span& &span class=&s1&&'url-loader'&/span&&span class=&p&&,&/span&
&span class=&nx&&query&/span&&span class=&o&&:&/span& &span class=&p&&{&/span&
&span class=&nx&&limit&/span&&span class=&o&&:&/span& &span class=&mi&&1&/span&&span class=&p&&,&/span&
&span class=&nx&&publicPath&/span&&span class=&o&&:&/span& &span class=&nx&&config&/span&&span class=&p&&.&/span&&span class=&nx&&imgPath&/span&&span class=&p&&,&/span&
&span class=&nx&&name&/span&&span class=&o&&:&/span& &span class=&s1&&'/v1/images/[hash:8].[name].[ext]'&/span&
&span class=&p&&}&/span&
&span class=&p&&},&/span&
&span class=&p&&]&/span&
&span class=&p&&}&/span&
&/code&&/pre&&/div&&p&在主文件中涉及的所有依赖资源(app.js中import的所有js、css、图片、字体),对依赖资源的文件路径按正则(rules数组中的test),匹配成功的以对应的loader处理资源源文件(如:xx.jsx、xx.vue、xx.js、xx.ts)等。&/p&&p&&br&&/p&&p&&b&(3)插件:plugins&/b&&/p&&p&webpack中插件已plugins属性{key: value}来组织第三方插件;如下:(配置实现:生成html文件、提取公用js代码、分离css、定义全局变量)&/p&&div class=&highlight&&&pre&&code class=&language-js&&&span&&/span&&span class=&nx&&plugins&/span&&span class=&o&&:&/span& &span class=&p&&[&/span&
&span class=&k&&new&/span& &span class=&nx&&HtmlWebpackPlugin&/span&&span class=&p&&({&/span&
&span class=&nx&&filename&/span&&span class=&o&&:&/span& &span class=&s1&&'public/mall/index.html'&/span&&span class=&p&&,&/span&
&span class=&nx&&template&/span&&span class=&o&&:&/span& &span class=&s1&&'../template.html'&/span&&span class=&p&&,&/span&
&span class=&nx&&chunks&/span&&span class=&o&&:&/span& &span class=&p&&[&/span& &span class=&s1&&'common'&/span&&span class=&p&&,&/span& &span class=&s1&&'vendor'&/span&&span class=&p&&,&/span& &span class=&s1&&'mall'&/span&&span class=&p&&],&/span&
&span class=&nx&&hash&/span&&span class=&o&&:&/span& &span class=&kc&&true&/span&&span class=&p&&,&/span& &span class=&c1&&// 为静态资源生成hash值&/span&
&span class=&nx&&inject&/span&&span class=&o&&:&/span& &span class=&s1&&'body'&/span&&span class=&p&&,&/span&
&span class=&nx&&xhtml&/span&&span class=&o&&:&/span& &span class=&kc&&true&/span&&span class=&p&&,&/span&
&span class=&nx&&minify&/span&&span class=&o&&:&/span& &span class=&p&&{&/span&
&span class=&nx&&removeComments&/span&&span class=&o&&:&/span& &span class=&kc&&true&/span&&span class=&p&&,&/span&
&span class=&p&&}&/span&
&span class=&p&&}),&/span&
&span class=&k&&new&/span& &span class=&nx&&webpack&/span&&span class=&p&&.&/span&&span class=&nx&&optimize&/span&&span class=&p&&.&/span&&span class=&nx&&CommonsChunkPlugin&/span&&span class=&p&&({&/span&
&span class=&nx&&names&/span&&span class=&o&&:&/span& &span class=&p&&[&/span&&span class=&s1&&'vendor'&/span&&span class=&p&&,&/span& &span class=&s1&&'common'&/span&&span class=&p&&]&/span&
&span class=&p&&}),&/span&
&span class=&k&&new&/span& &span class=&nx&&ExtractTextPlugin&/span&&span class=&p&&({&/span&
&span class=&nx&&filename&/span&&span class=&o&&:&/span& &span class=&s1&&'meitumall/v1/css/[name].css?[contenthash:8]'&/span&&span class=&p&&,&/span&
&span class=&nx&&allChunks&/span&&span class=&o&&:&/span& &span class=&kc&&true&/span&&span class=&p&&,&/span&
&span class=&p&&}),&/span&
&span class=&k&&new&/span& &span class=&nx&&webpack&/span&&span class=&p&&.&/span&&span class=&nx&&ProvidePlugin&/span&&span class=&p&&({&/span&
&span class=&nx&&$&/span&&span class=&o&&:&/span& &span class=&s1&&'jquery'&/span&&span class=&p&&,&/span&
&span class=&nx&&jQuery&/span&&span class=&o&&:&/span& &span class=&s1&&'jquery'&/span&&span class=&p&&,&/span&
&span class=&s1&&'window.jQuery'&/span&&span class=&o&&:&/span& &span class=&s1&&'jquery'&/span&&span class=&p&&,&/span&
&span class=&s1&&'window.$'&/span&&span class=&o&&:&/span& &span class=&s1&&'jquery'&/span&&span class=&p&&,&/span&
&span class=&p&&}),&/span&
&span class=&p&&]&/span&
&/code&&/pre&&/div&&p&plugins插件的目的在于解决loader无法实现的功能,扩展webpack的功能。&/p&&p&&br&&/p&&p&&b&(4)构建后的文件&/b&&/p&&p&webpack中构建后文件以output属性{key: value}来组织构建后的文件;如下:&/p&&div class=&highlight&&&pre&&code class=&language-js&&&span&&/span&&span class=&nx&&output&/span&&span class=&o&&:&/span& &span class=&p&&{&/span&
&span class=&nx&&path&/span&&span class=&o&&:&/span& &span class=&s1&&'../dist'&/span&&span class=&p&&,&/span&
&span class=&nx&&publicPath&/span&&span class=&o&&:&/span& &span class=&nx&&config&/span&&span class=&p&&.&/span&&span class=&nx&&staticPath&/span&&span class=&p&&,&/span&
&span class=&nx&&filename&/span&&span class=&o&&:&/span& &span class=&s1&&'/v1/js/[name].[chunkhash:8].js'&/span&&span class=&p&&,&/span&
&span class=&nx&&chunkFilename&/span&&span class=&o&&:&/span& &span class=&s1&&'[id].[chunkhash:8].js'&/span&
&span class=&p&&}&/span&
&/code&&/pre&&/div&&p&path:定义构建后文件的存放主目录&/p&&p&publicPath:定义静态资源的引用路径(比如:css中应用了图片)&/p&&p&filename:定义构建后的文件名,其中[name]: 未entry中的定义的key(app),chunkhash定义hash规范。&/p&&p&chunkFilename:定义未在entry中组织的js文件,如:按commonJs需加载的文件,如:下面这种形式引入的js。&/p&&div class=&highlight&&&pre&&code class=&language-js&&&span&&/span&&span class=&nx&&require&/span&&span class=&p&&.&/span&&span class=&nx&&ensure&/span&&span class=&p&&([&/span&&span class=&s2&&&modules/require0.js&&/span&&span class=&p&&],&/span& &span class=&kd&&function&/span&&span class=&p&&(&/span&&span class=&nx&&require&/span&&span class=&p&&)&/span& &span class=&p&&{&/span&
&span class=&kd&&var&/span& &span class=&nx&&a&/span& &span class=&o&&=&/span& &span class=&nx&&require&/span&&span class=&p&&(&/span&&span class=&s2&&&modules/require0.js&&/span&&span class=&p&&);&/span&
&span class=&p&&},&/span& &span class=&s1&&'require0'&/span&&span class=&p&&);&/span&
&/code&&/pre&&/div&&p&&br&&/p&&img src=&/v2-f78661bef717cf2cc2c2e_b.jpg& data-caption=&& data-rawwidth=&2598& data-rawheight=&1299& class=&origin_image zh-lightbox-thumb& width=&2598& data-original=&/v2-f78661bef717cf2cc2c2e_r.jpg&&&p&&br&&/p&&h2&四、处理我们的需求&/h2&&p&处理第二中我们提到的需求:&/p&&blockquote&代码逻辑太复杂,所以开发过程中需要断点调试!&/blockquote&&p&webpack中,通过设置devtool开启sourceMap 让我们可以调试代码,如下:&/p&&div class=&highlight&&&pre&&code class=&language-js&&&span&&/span&&span class=&nx&&devtool&/span&&span class=&o&&:&/span& &span class=&s1&&'source-map'&/span&
&/code&&/pre&&/div&&p&souceMap有多种模式,大家可以看下这篇文章的介绍:&/p&&p&&a href=&/?target=https%3A//juejin.im/post/bb9ff& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&[webpack] devtool里的7种SourceMap模式是什么鬼?&i class=&icon-external&&&/i&&/a&&/p&&p&怎么调试代码,可以看这篇文章:&/p&&p&&a href=&/question//answer/& class=&internal&&蒙娜丽莎:使用vue-cli构建的项目如何调试?如何与服务端结合?&/a&&/p&&p&&br&&/p&&blockquote&不想手动刷新,所以需要热加载!&/blockquote&&p&webpack中,通过设置devServer来配置开发服务,如下:&/p&&div class=&highlight&&&pre&&code class=&language-js&&&span&&/span&&span class=&nx&&devServer&/span&&span class=&o&&:&/span& &span class=&p&&{&/span&
&span class=&nx&&contentBase&/span&&span class=&o&&:&/span& &span class=&s1&&'./dist'&/span&&span class=&p&&,&/span&
&span class=&nx&&inline&/span&&span class=&o&&:&/span& &span class=&kc&&true&/span&&span class=&p&&,&/span&
&span class=&nx&&compress&/span&&span class=&o&&:&/span& &span class=&kc&&true&/span&&span class=&p&&,&/span&
&span class=&nx&&host&/span&&span class=&o&&:&/span& &span class=&s1&&'127.0.0.1'&/span&&span class=&p&&,&/span&
&span class=&nx&&port&/span&&span class=&o&&:&/span& &span class=&mi&&8088&/span&&span class=&p&&,&/span&
&span class=&nx&&disableHostCheck&/span&&span class=&o&&:&/span& &span class=&kc&&true&/span&&span class=&p&&,&/span&
&span class=&nx&&historyApiFallback&/span&&span class=&o&&:&/span& &span class=&kc&&true&/span&
&span class=&p&&}&/span&
&span class=&c1&&// pakage.json 配置启动脚本&/span&
&span class=&s2&&&scripts&&/span&&span class=&o&&:&/span& &span class=&p&&{&/span&
&span class=&s2&&&start&&/span&&span class=&o&&:&/span& &span class=&s2&&&webpack-dev-server --config build/webpack.dev.conf.js --open --hot&&/span&&span class=&p&&,&/span&
&span class=&p&&}&/span&
&/code&&/pre&&/div&&p&&br&&/p&&blockquote&写更漂亮的代码,所以需要支持es6、sass!&/blockquote&&p&上面说道:loader是用来处理资源源文件(如:xx.jsx、xx.vue、xx.js、xx.ts等),因此只要在配置相应的loader就可以了&/p&&div class=&highlight&&&pre&&code class=&language-js&&&span&&/span&&span class=&nx&&rules&/span&&span class=&o&&:&/span& &span class=&p&&[&/span&
&span class=&c1&&// ...&/span&
&span class=&p&&{&/span&
&span class=&nx&&test&/span&&span class=&o&&:&/span& &span class=&sr&&/\.js$/&/span&&span class=&p&&,&/span& &span class=&c1&&// 正则&/span&
&span class=&nx&&loader&/span&&span class=&o&&:&/span& &span class=&s1&&'babel-loader'&/span&&span class=&p&&,&/span& &span class=&c1&&// babel-loader&/span&
&span class=&nx&&exclude&/span&&span class=&o&&:&/span& &span class=&sr&&/(node_modules)/&/span&&span class=&p&&,&/span& &span class=&c1&&// 忽略目录&/span&
&span class=&p&&},&/span&
&span class=&p&&{&/span&
&span class=&nx&&test&/span&&span class=&o&&:&/span& &span class=&sr&&/\.(scss|css)$/&/span&&span class=&p&&,&/span&
&span class=&nx&&use&/span&&span class=&o&&:&/span& &span class=&nx&&ExtractTextPlugin&/span&&span class=&p&&.&/span&&span class=&nx&&extract&/span&&span class=&p&&({&/span&
&span class=&nx&&use&/span&&span class=&o&&:&/span& &span class=&p&&[&/span&
&span class=&p&&{&/span&
&span class=&nx&&loader&/span&&span class=&o&&:&/span& &span class=&s1&&'css-loader'&/span&&span class=&p&&,&/span&
&span class=&nx&&options&/span&&span class=&o&&:&/span& &span class=&p&&{&/span&
&span class=&nx&&sourceMap&/span&&span class=&o&&:&/span& &span class=&kc&&false&/span&&span class=&p&&,&/span&
&span class=&nx&&minimize&/span&&span class=&o&&:&/span& &span class=&kc&&true&/span&&span class=&p&&,&/span&
&span class=&p&&}&/span&
&span class=&p&&},&/span&
&span class=&s1&&'postcss-loader'&/span&&span class=&p&&,&/span&
&span class=&s2&&&sass-loader?sourceMap&&/span&&span class=&p&&,&/span&
&span class=&p&&],&/span&
&span class=&nx&&fallback&/span&&span class=&o&&:&/span& &span class=&s2&&&style-loader&&/span&
&span class=&p&&})&/span&
&span class=&p&&},&/span&
&span class=&c1&&// ...&/span&
&span class=&p&&]&/span&
&/code&&/pre&&/div&&p&具体各个loader的配置规则可以到github上搜索该loader文档。&/p&&p&&br&&/p&&blockquote&不想每次都import jquery,所以需要引入到全局!&/blockquote&&p&这只需要将jQuery配置到全局即可。&/p&&div class=&highlight&&&pre&&code class=&language-js&&&span&&/span&&span class=&nx&&plugins&/span&&span class=&o&&:&/span& &span class=&p&&[&/span&
&span class=&c1&&// ...&/span&
&span class=&k&&new&/span& &span class=&nx&&webpack&/span&&span class=&p&&.&/span&&span class=&nx&&ProvidePlugin&/span&&span class=&p&&({&/span&
&span class=&nx&&$&/span&&span class=&o&&:&/span& &span class=&s1&&'jquery'&/span&&span class=&p&&,&/span&
&span class=&nx&&jQuery&/span&&span class=&o&&:&/span& &span class=&s1&&'jquery'&/span&&span class=&p&&,&/span&
&span class=&s1&&'window.jQuery'&/span&&span class=&o&&:&/span& &span class=&s1&&'jquery'&/span&&span class=&p&&,&/span&
&span class=&s1&&'window.$'&/span&&span class=&o&&:&/span& &span class=&s1&&'jquery'&/span&&span class=&p&&,&/span&
&span class=&p&&}),&/span&
&span class=&p&&]&/span&
&/code&&/pre&&/div&&p&这样如要在如index.js中用到jquery,就可以不用import 'jquery',直接使用$。&/p&&p&&br&&/p&&blockquote&图片太大了,所以需要压缩图片!&/blockquote&&p&配置图片压缩插件即可:&/p&&p&&a href=&/?target=https%3A///tcoopman/image-webpack-loader& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&tcoopman/image-webpack-loader&i class=&icon-external&&&/i&&/a&&/p&&p&&br&&/p&&blockquote&1、需要部署多个环境,开发环境、测试环境、beta环境、正式环境!&br&2、服务端,需求并不确定,可能会频繁的需要改tmd构建目录!&br&3、他们说,图片需要发布CDN!&br&4、CND可能会有缓存,现在还不确定静态资源用文件hash的形式好,还是参数hash的形式好!&/blockquote&&p&这些涉及到部署规范的需求可以统一处理。&/p&&p&具体方法维护一份配置文档,如config.js,里面配置各个部署环境的需求;如下:&/p&&div class=&highlight&&&pre&&code class=&language-js&&&span&&/span&&span class=&nx&&module&/span&&span class=&p&&.&/span&&span class=&nx&&exports&/span& &span class=&o&&=&/span& &span class=&p&&{&/span&
&span class=&nx&&dev&/span&&span class=&o&&:&/span& &span class=&p&&{&/span&
&span class=&c1&&// 开发环境配置&/span&
&span class=&nx&&port&/span&&span class=&o&&:&/span& &span class=&mi&&9000&/span&&span class=&p&&,&/span&
&span class=&nx&&NODE_ENV&/span&&span class=&o&&:&/span& &span class=&s1&&'development'&/span&&span class=&p&&,&/span&
&span class=&nx&&devtool&/span&&span class=&o&&:&/span& &span class=&s1&&'source-map'&/span&&span class=&p&&,&/span&
&span class=&nx&&jsSourceMap&/span&&span class=&o&&:&/span& &span class=&kc&&false&/span&&span class=&p&&,&/span&
&span class=&nx&&cssSourceMap&/span&&span class=&o&&:&/span& &span class=&kc&&false&/span&&span class=&p&&,&/span&
&span class=&nx&&eslint&/span&&span class=&o&&:&/span& &span class=&kc&&true&/span&&span class=&p&&,&/span&
&span class=&nx&&path&/span&&span class=&o&&:&/span& &span class=&s1&&'../dist'&/span&&span class=&p&&,&/span& &span class=&c1&&// 生成目录&/span&
&span class=&nx&&jsPath&/span&&span class=&o&&:&/span& &span class=&s1&&''&/span&&span class=&p&&,&/span&
&span class=&c1&&// js静态资源&/span&
&span class=&nx&&cssPath&/span&&span class=&o&&:&/span& &span class=&s1&&''&/span&&span class=&p&&,&/span&
&span class=&c1&&// css静态资源地址&/span&
&span class=&nx&&imgPath&/span&&span class=&o&&:&/span& &span class=&s1&&'http://localimg.'&/span&&span class=&p&&,&/span&
&span class=&nx&&filenameHash&/span&&span class=&o&&:&/span& &span class=&kc&&false&/span&&span class=&p&&,&/span&
&span class=&c1&&// 文件名hash的形式?否则为参数hash&/span&
&span class=&nx&&API_PATH&/span&&span class=&o&&:&/span& &span class=&s1&&'/v1/'&/span&&span class=&p&&,&/span&
&span class=&c1&&// 配置api地址&/span&
&span class=&p&&},&/span&
&span class=&nx&&production&/span&&span class=&o&&:&/span& &span class=&p&&{&/span&
&span class=&c1&&//生产环境&/span&
&span class=&nx&&port&/span&&span class=&o&&:&/span& &span class=&mi&&9000&/span&&span class=&p&&,&/span&
&span class=&nx&&NODE_ENV&/span&&span class=&o&&:&/span& &span class=&s1&&'production'&/span&&span class=&p&&,&/span&
&span class=&nx&&devtool&/span&&span class=&o&&:&/span& &span class=&s1&&''&/span&&span class=&p&&,&/span&
&span class=&nx&&jsSourceMap&/span&&span class=&o&&:&/span& &span class=&kc&&false&/span&&span class=&p&&,&/span&
&span class=&nx&&cssSourceMap&/span&&span class=&o&&:&/span& &span class=&kc&&false&/span&&span class=&p&&,&/span&
&span class=&nx&&eslint&/span&&span class=&o&&:&/span& &span class=&kc&&true&/span&&span class=&p&&,&/span&
&span class=&nx&&path&/span&&span class=&o&&:&/span& &span class=&s1&&'../dist'&/span&&span class=&p&&,&/span& &span class=&c1&&// 生成目录&/span&
&span class=&nx&&jsPath&/span&&span class=&o&&:&/span& &span class=&s1&&''&/span&&span class=&p&&,&/span&
&span class=&c1&&// js静态资源&/span&
&span class=&nx&&cssPath&/span&&span class=&o&&:&/span& &span class=&s1&&''&/span&&span class=&p&&,&/span&
&span class=&c1&&// css静态资源地址&/span&
&span class=&nx&&imgPath&/span&&span class=&o&&:&/span& &span class=&s1&&'http://img.'&/span&&span class=&p&&,&/span&
&span class=&nx&&filenameHash&/span&&span class=&o&&:&/span& &span class=&kc&&false&/span&&span class=&p&&,&/span&
&span class=&c1&&// 文件名hash的形式?否则为参数hash&/span&
&span class=&nx&&API_PATH&/span&&span class=&o&&:&/span& &span class=&s1&&'/v1/'&/span&&span class=&p&&,&/span&
&span class=&c1&&// 配置api地址&/span&
&span class=&p&&},&/span&
&span class=&nx&&test&/span&&span class=&o&&:&/span& &span class=&p&&{&/span&
&span class=&c1&&// 测试环境&/span&
&span class=&c1&&// ...&/span&
&span class=&p&&},&/span&
&span class=&nx&&bata&/span&&span class=&o&&:&/span& &span class=&p&&{&/span& &span class=&c1&&// bata环境&/span&
&span class=&c1&&// ...&/span&
&span class=&p&&}&/span&
&span class=&p&&};&/span&
&/code&&/pre&&/div&&p&建立各个个环境的webpack文件,如:webpack.dev.config.js、webpack.test.config.js、webpack.production.config.js,并在文件中引入对应config的配置,如下:&/p&&p&webpack.production.config.js 内容:&/p&&div class=&highlight&&&pre&&code class=&language-js&&&span&&/span&&span class=&kr&&const&/span& &span class=&nx&&merge&/span& &span class=&o&&=&/span& &span class=&nx&&require&/span&&span class=&p&&(&/span&&span class=&s1&&'webpack-merge'&/span&&span class=&p&&);&/span&
&span class=&kr&&const&/span& &span class=&nx&&webpackBaseConfig&/span& &span class=&o&&=&/span& &span class=&nx&&require&/span&&span class=&p&&(&/span&&span class=&s1&&'./webpack.base.config.js'&/span&&span class=&p&&)(&/span&&span class=&s1&&'production'&/span&&span class=&p&&);&/span&
&span class=&kr&&const&/span& &span class=&nx&&webpackConfig&/span& &span class=&o&&=&/span& &span class=&nx&&merge&/span&&span class=&p&&(&/span&&span class=&nx&&webpackBaseConfig&/span&&span class=&p&&,&/span& &span class=&p&&{&/span&
&span class=&c1&&// 各个部署环境的特殊配置&/span&
&span class=&p&&});&/span&
&span class=&nx&&module&/span&&span class=&p&&.&/span&&span class=&nx&&exports&/span& &span class=&o&&=&/span& &span class=&nx&&webpackConfig&/span&&span class=&p&&;&/span&
&/code&&/pre&&/div&&p&webpack.base.config.js内容(通用的入口文件、规则、插件、构建后的文件)&/p&&div class=&highlight&&&pre&&code class=&language-js&&&span&&/span&&span class=&kr&&const&/span& &span class=&nx&&webpack&/span& &span class=&o&&=&/span& &span class=&nx&&require&/span&&span class=&p&&(&/span&&span class=&s1&&'webpack'&/span&&span class=&p&&);&/span&
&span class=&kr&&const&/span& &span class=&nx&&HtmlWebpackPlugin&/span& &span class=&o&&=&/span& &span class=&nx&&require&/span&&span class=&p&&(&/span&&span class=&s1&&'html-webpack-plugin'&/span&&span class=&p&&);&/span&
&span class=&kr&&const&/span& &span class=&nx&&ExtractTextPlugin&/span& &span class=&o&&=&/span& &span class=&nx&&require&/span&&span class=&p&&(&/span&&span class=&s1&&'extract-text-webpack-plugin'&/span&&span class=&p&&);&/span&
&span class=&kr&&const&/span& &span class=&p&&{&/span&&span class=&nx&&resolve&/span&&span class=&p&&}&/span& &span class=&o&&=&/span& &span class=&nx&&require&/span&&span class=&p&&(&/span&&span class=&s1&&'./utils'&/span&&span class=&p&&);&/span&
&span class=&kd&&var&/span& &span class=&nx&&glob&/span& &span class=&o&&=&/span& &span class=&nx&&require&/span&&span class=&p&&(&/span&&span class=&s1&&'glob'&/span&&span class=&p&&);&/span&
&span class=&nx&&module&/span&&span class=&p&&.&/span&&span class=&nx&&exports&/span& &span class=&o&&=&/span& &span class=&kd&&function&/span& &span class=&nx&&webpackBaseConfig&/span& &span class=&p&&(&/span&&span class=&nx&&NODE_ENV&/span& &span class=&o&&=&/span& &span class=&s1&&'development'&/span&&span class=&p&&)&/span& &span class=&p&&{&/span&
&span class=&kr&&const&/span& &span class=&nx&&_config&/span& &span class=&o&&=&/span& &span class=&nx&&require&/span&&span class=&p&&(&/span&&span class=&s1&&'./config.js'&/span&&span class=&p&&)(&/span&&span class=&nx&&NODE_ENV&/span&&span class=&p&&);&/span&
&span class=&c1&&// 各个部署环境的配置需求&/span&
&span class=&nx&&process&/span&&span class=&p&&.&/span&&span class=&nx&&env&/span&&span class=&p&&.&/span&&span class=&nx&&NODE_ENV&/span& &span class=&o&&=&/span& &span class=&nx&&NODE_ENV&/span&&span class=&p&&;&/span&
&span class=&kr&&const&/span& &span class=&nx&&webpackConfig&/span& &span class=&o&&=&/span& &span class=&p&&{&/span&
&span class=&nx&&devtool&/span&&span class=&o&&:&/span& &span class=&nx&&_config&/span&&span class=&p&&.&/span&&span class=&nx&&devtool&/span&&span class=&p&&,&/span&
&span class=&nx&&entry&/span&&span class=&o&&:&/span& &span class=&p&&{&/span&
&span class=&c1&&// ...&/span&
&span class=&p&&},&/span&
&span class=&nx&&output&/span&&span class=&o&&:&/span& &span class=&p&&{&/span&
&span class=&nx&&path&/span&&span class=&o&&:&/span& &span class=&nx&&_config&/span&&span class=&p&&.&/span&&span class=&nx&&path&/span&&span class=&p&&,&/span&
&span class=&nx&&publicPath&/span&&span class=&o&&:&/span& &span class=&nx&&_config&/span&&span class=&p&&.&/span&&span class=&nx&&jsPath&/span&&span class=&p&&,&/span&
&span class=&nx&&filename&/span&&span class=&o&&:&/span& &span class=&nx&&_config&/span&&span class=&p&&.&/span&&span class=&nx&&filenameHash&/span& &span class=&o&&?&/span& &span class=&s1&&'/js/[name].[chunkhash:8].js?'&/span& &span class=&o&&:&/span& &span class=&s1&&'/js/[name].js?[chunkhash:8]'&/span& &span class=&p&&,&/span&
&span class=&p&&},&/span&
&span class=&c1&&// ....&/span&
&span class=&p&&};&/span&
&span class=&k&&return&/span& &span class=&nx&&webpackConfig&/span&&span class=&p&&;&/span&
&span class=&p&&}&/span&
&/code&&/pre&&/div&&p&&br&&/p&&p&最后在 package.json 配置各个部署环境的运行脚本;如下&/p&&div class=&highlight&&&pre&&code class=&language-js&&&span&&/span& &span class=&s2&&&scripts&&/span&&span class=&o&&:&/span& &span class=&p&&{&/span&
&span class=&s2&&&start&&/span&&span class=&o&&:&/span& &span class=&s2&&&webpack-dev-server --config assets/build/webpack.dev.conf.js --open --hot&&/span&&span class=&p&&,&/span&
&span class=&s2&&&build:test&&/span&&span class=&o&&:&/span& &span class=&s2&&&webpack -p --config assets/build/webpack.test.conf.js --progress --hide-modules&&/span&&span class=&p&&,&/span&
&span class=&s2&&&build:bata&&/span&&span class=&o&&:&/span& &span class=&s2&&&composer update -o --no-dev --no-plugins --no-scripts --ignore-platform-reqs -n && webpack -p --config assets/build/webpack.bata.conf.js --progress --hide-modules&&/span&&span class=&p&&,&/span&
&span class=&s2&&&build&&/span&&span class=&o&&:&/span& &span class=&s2&&&composer update -o --no-dev --no-plugins --no-scripts --ignore-platform-reqs -n && webpack -p --config assets/build/webpack.production.conf.js --progress --hide-modules&&/span&
&span class=&p&&},&/span&
&/code&&/pre&&/div&&p&&br&&/p&&blockquote&3、有些页面,服务端没时间开发,需要前端写死!&/blockquote&&p&转换一下需求就是,需要前端维护一些惊天页面(比如:一些html5活动页等等);这个时候就涉及到用webpack配置多页应用(既:entry添加多个入口,plugins中配置多项html生成规范等),可以参考之前写的一篇文章。&/p&&p&&a href=&/p/& class=&internal&&美图商城改版之——webpack多页应用环境搭建&/a&&/p&&p&&br&&/p&&blockquote&好多人合作,所以需要检查代码规范!&/blockquote&&p&可以通过配置eslint来检查代码规范。&/p&&p&&a href=&/?target=https%3A///eslint/eslint& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&eslint/eslint&i class=&icon-external&&&/i&&/a&&/p&&p&&br&&/p&&h2&五、补充hash指纹说明&/h2&&p&hash指纹是什么呢?实现前端惊天资源的增量更新。我们知道用户访问过某个网站后浏览器缓存前端资源文件(或者cdn),比如:同时缓存了index.deadk12.js、h5.kdjkjf3.js。同样适用于图片文件、css文件、字体文件等前端静态资源。&/p&&p&当网站升级(假设更新了h5涉及的js内容),发布新版本的时候就需要生成新的版本号来使新的及时体现,不然就要等浏览器缓存过期(或者强刷浏览器、刷cdn等)&/p&&p&比如:查看知乎的页面源码,红线框住的内容就用了增量更新的形式。&/p&&img src=&/v2-0d1ff9fa2ddae5288cfe0_b.jpg& data-caption=&& data-rawwidth=&3050& data-rawheight=&202& class=&origin_image zh-lightbox-thumb& width=&3050& data-original=&/v2-0d1ff9fa2ddae5288cfe0_r.jpg&&&p&webpack 提供两种hash配置:hash与chunkhash&/p&&div class=&highlight&&&pre&&code class=&language-js&&&span&&/span&&span class=&nx&&output&/span&&span class=&o&&:&/span& &span class=&p&&{&/span&
&span class=&nx&&path&/span&&span class=&o&&:&/span& &span class=&s1&&'../dist'&/span&&span class=&p&&,&/span&
&span class=&nx&&publicPath&/span&&span class=&o&&:&/span& &span class=&nx&&config&/span&&span class=&p&&.&/span&&span class=&nx&&staticPath&/span&&span class=&p&&,&/span&
&span class=&nx&&filename&/span&&span class=&o&&:&/span& &span class=&s1&&'/v1/js/[name].[chunkhash:8].js'&/span&&span class=&p&&,&/span&
&span class=&nx&&chunkFilename&/span&&span class=&o&&:&/span& &span class=&s1&&'[id].[chunkhash:8].js'&/span&
&span class=&p&&}&/span&
&/code&&/pre&&/div&&blockquote&1、hash&/blockquote&&p&代表的是&i&compilation&/i&的hash值&/p&&p&compilation代表各个版本的资源对应的编译进程。每次构建中有文件有改动就会创建一个新compilation。&/p&&p&因此,项目中如果有一个文件修改,那么每次编译生成hash都会不一样,不同入口文件(index、h5)的hash是一样的。&/p&&p&导致的问题是,一旦有一个文件做修改,那么所有的缓存都会失效。&/p&&p&&br&&/p&&blockquote&2、chunkhash&/blockquote&&p&chunkhash是根据具体模块文件的内容计算所得的hash值,所以某个文件的改动只会影响它本身的hash指纹,不会影响其他文件。&/p&&p&既如何h5的内容修改,不会影响index.xxx.js的缓存。&/p&&p&&br&&/p&&p&注:经测试相同的源代码,由于node.js版本的不一样,会导致依赖自已不一样,因此生成的hash、contenthash会不一样。&/p&&p&&br&&/p&&blockquote&3、contenthash&/blockquote&&p&contenthash 是webpack第三方插件 extract-text-webpack-plugin 的另一种hash指纹。只跟css样式内容有关系;&/p&&div class=&highlight&&&pre&&code class=&language-abap&&&span&&/span&&span class=&nv&&new&/span& &span class=&nv&&ExtractTextPlugin&/span&&span class=&p&&(&/span&&span class=&err&&{&/span&
&span class=&nv&&filename&/span&&span class=&p&&:&/span& &span class=&s1&&'v1/css/[name].css?[contenthash:8]'&/span&&span class=&p&&,&/span&
&span class=&nv&&allChunks&/span&&span class=&p&&:&/span& &span class=&nv&&true&/span&&span class=&p&&,&/span&
&span class=&err&&}&/span&&span class=&p&&),&/span&
&/code&&/pre&&/div&&p&&br&&/p&&p&具体文章可以看:&/p&&p&&a href=&/?target=http%3A///ihardcoder/p/5623411.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Webpack中hash与chunkhash的区别,以及js与css的hash指纹解耦方案 - 才子锅锅 - 博客园&i class=&icon-external&&&/i&&/a&&/p&&p&&/p&
一、写在前面产品经理:那谁,那个创建订单流程能不能改一下,改成创建订单的同时直接调取淘宝、微信支付,前端可以处理吧...... 设计:喂喂喂,这个这个这个二级导航高度不要55px,全部改成48px吧..... 测试:卧槽,死前端过来,那个预约按钮又显示不出来…
&img src=&/50/v2-c052f772c27deafd484df_b.jpg& data-rawwidth=&1280& data-rawheight=&720& class=&origin_image zh-lightbox-thumb& width=&1280& data-original=&/50/v2-c052f772c27deafd484df_r.jpg&&&p&由于公司的前端开始转向 VueJS,最近开始使用这个框架进行开发,遇到一些问题记录下来,以备后用。 主要写一些 &b&&a href=&/?target=https%3A//cn.vuejs.org/v2/guide/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&官方手册&i class=&icon-external&&&/i&&/a&&/b& 上没有写,但是实际开发中会遇到的问题,需要一定知识基础。&/p&&h2&涉及技术栈&/h2&&ul&&li&CLI: &a href=&/?target=https%3A///vuejs/vue-cli& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Vue-CLI&i class=&icon-external&&&/i&&/a&&/li&&li&UI: &a href=&/?target=http%3A//element.eleme.io/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Element&i class=&icon-external&&&/i&&/a&&/li&&li&HTML: &a href=&/?target=https%3A//pugjs.org/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Pug(Jade)&i class=&icon-external&&&/i&&/a&&/li&&li&CSS: &a href=&/?target=http%3A//lesscss.org/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Less&i class=&icon-external&&&/i&&/a&&/li&&li&JavaScript: &a href=&/?target=https%3A///lukehoban/es6features& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&ES6&i class=&icon-external&&&/i&&/a&&/li&&/ul&&p&&b&正文:&/b&&/p&&h2&polyfill 与 transform-runtime&/h2&&p&首先,vue-cli 为我们自动添加了 babel-plugin-transform-runtime 这个插件,该插件多数情况下都运作正常,可以转换大部分 ES6 语法。&/p&&p&  但是,存在如下两个问题:&/p&&ol&&li&&b&异步加载组件时,会产生&/b& &b&polyfill&/b& &b&代码冗余&/b&&/li&&li&&b&不支持对全局函数与实例方法的&/b& &b&polyfill&/b&&/li&&/ol&&p&两个问题的原因均归因于 babel-plugin-transform-runtime 采用了沙箱机制来编译我们的代码(即:不修改宿主环境的内置对象)。&/p&&p&由于异步组件最终会被编译为一个单独的文件,所以即使多个组件中使用了同一个新特性(例如:Object.keys()),那么在每个编译后的文件中都会有一份该新特性的 polyfill 拷贝。如果项目较小可以考虑不使用异步加载,但是首屏的压力会比较大。 &/p&&p&  不支持全局函数(如:Promise、Set、Map),Set 跟 Map 这两种数据结构应该大家用的也不多,影响较小。但是 Promise 影响可能就比较大了。&/p&&p&  不支持实例方法(如:'abc'.include('b')、['1', '2', '3'].find((n) =& n & 2) 等等),这个限制几乎废掉了大部分字符串和一半左右数组的新特性。&/p&&blockquote&一般情况下 babel-plugin-transform-runtime 能满足大部分的需求,当不满足需求时,推荐使用完整的 babel-polyfill。&/blockquote&&h2&替换 babel-polyfill&/h2&&p&首先,从项目中移除 babel-plugin-transform-runtime &/p&&p&  卸载该依赖:&/p&&div class=&highlight&&&pre&&code class=&language-bash&&&span&&/span&npm un babel-plugin-transform-runtime -D
&/code&&/pre&&/div&&p&修改 babel 配置文件&/p&&div class=&highlight&&&pre&&code class=&language-json&&&span&&/span&&span class=&err&&//&/span& &span class=&err&&.babelrc&/span&
&span class=&p&&{&/span&
&span class=&err&&//...&/span&
&span class=&nt&&&plugins&&/span&&span class=&p&&:&/span& &span class=&p&&[&/span&
&span class=&err&&//&/span& &span class=&err&&-&/span& &span class=&s2&&&transform-runtime&&/span&
&span class=&p&&]&/span&
&span class=&err&&//...&/span&
&span class=&p&&}&/span&
&/code&&/pre&&/div&&p&然后,安装 babel-polyfill 依赖:&/p&&div class=&highlight&&&pre&&code class=&language-bash&&&span&&/span&npm i babel-polyfill -D
&/code&&/pre&&/div&&p&最后,在入口文件中导入&/p&&div class=&highlight&&&pre&&code class=&language-js&&&span&&/span&&span class=&c1&&// src/main.js&/span&
&span class=&kr&&import&/span& &span class=&s1&&'babel-polyfill'&/span&
&/code&&/pre&&/div&&h2&ES6 import 引用问题&/h2&&p&在 ES6 中,模块系统的导入与导出采用的是引用导出与导入(非简单数据类型),也就是说,如果在一个模块中定义了一个对象并导出,在其他模块中导入使用时,导入的其实是一个变量引用(指针),如果修改了对象中的属性,会影响到其他模块的使用。&/p&&p&  通常情况下,系统体量不大时,我们可以使用 JSON.parse(JSON.stringify(str)) 简单粗暴地来生成一个全新的深度拷贝的 &b&数据对象&/b&。不过当组件较多、数据对象复用程度较高时,很明显会产生性能问题,这时我们可以考虑使用 &a href=&/?target=https%3A//facebook.github.io/immutable-js/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Immutable.js&i class=&icon-external&&&/i&&/a&。&/p&&blockquote&鉴于这个原因,进行复杂数据类型的导出时,需要注意多个组件导入同一个数据对象时修改数据后可能产生的问题。 此外,模块定义变量或函数时即便使用 let 而不是 const,在导入使用时都会变成只读,不能重新赋值,效果等同于用 const 声明。&/blockquote&&h2&在 Vue 中使用 Pug 与 Less&/h2&&h2&安装依赖&/h2&&p&Vue 中使用 vue-loader 根据 lang 属性自动判断所需要的 loader,所以不用额外配置 Loader,但是需要手动安装相关依赖:&/p&&div class=&highlight&&&pre&&code class=&language-bash&&&span&&/span&npm i pug -D
npm i less-loader -D
&/code&&/pre&&/div&&p&还是相当方便的,不用手动修改 webpack 的配置文件添加 loader 就可以使用了&/p&&blockquote&使用 pug 还是 pug-loader?sass 两种语法的 loader 如何设置? --- 请参考 &a href=&/?target=https%3A//vue-loader.vuejs.org/zh-cn/configurations/pre-processors.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&预处理器 · vue-loader&i class=&icon-external&&&/i&&/a&&/blockquote&&h2&使用&/h2&&div class=&highlight&&&pre&&code class=&language-js&&&span&&/span&&span class=&c&&&!--&/span& &span class=&nx&&xxx&/span&&span class=&p&&.&/span&&span class=&nx&&vue&/span& &span class=&o&&--&&/span&
&span class=&o&&&&/span&&span class=&nx&&style&/span& &span class=&nx&&lang&/span&&span class=&o&&=&/span&&span class=&s2&&&less&&/span&&span class=&o&&&&/span&
&span class=&p&&.&/span&&span class=&nx&&action&/span& &span class=&p&&{&/span&
&span class=&nx&&color&/span&&span class=&o&&:&/span& &span class=&err&&#&/span&&span class=&nx&&ddd&/span&&span class=&p&&;&/span&
&span class=&nx&&ul&/span& &span class=&p&&{&/span&
&span class=&nx&&overflow&/span&&span class=&o&&:&/span& &span class=&nx&&hidden&/span&&span class=&p&&;&/span&
&span class=&nx&&li&/span& &span class=&p&&{&/span&
&span class=&kr&&float&/span&&span class=&o&&:&/span& &span class=&nx&&left&/span&&span class=&p&&;&/span&
&span class=&p&&}&/span&
&span class=&p&&}&/span&
&span class=&p&&}&/span&
&span class=&o&&&&/span&&span class=&err&&/style&&/span&
&span class=&o&&&&/span&&span class=&nx&&template&/span& &span class=&nx&&lang&/span&&span class=&o&&=&/span&&span class=&s2&&&pug&&/span&&span class=&o&&&&/span&
&span class=&p&&.&/span&&span class=&nx&&action&/span&&span class=&p&&(&/span&&span class=&nx&&v&/span&&span class=&o&&-&/span&&span class=&k&&if&/span&&span class=&o&&=&/span&&span class=&s1&&'hasRight'&/span&&span class=&p&&)&/span&
&span class=&nx&&ul&/span&
&span class=&nx&&li&/span& &span class=&nx&&编辑&/span&
&span class=&nx&&li&/span& &span class=&nx&&删除&/span&
&span class=&o&&&&/span&&span class=&err&&/template&&/span&
&span class=&o&&&&/span&&span class=&nx&&script&/span&&span class=&o&&&&/span&
&span class=&kr&&export&/span& &span class=&k&&default&/span& &span class=&p&&{&/span&
&span class=&nx&&data&/span& &span class=&p&&()&/span& &span class=&p&&{&/span&
&span class=&k&&return&/span& &span class=&p&&{&/span&
&span class=&nx&&hasRight&/span&&span class=&o&&:&/span& &span class=&kc&&true&/span&
&span class=&p&&}&/span&
&span class=&p&&}&/span&
&span class=&p&&}&/span&
&span class=&o&&&&/span&&span class=&err&&/script&&/span&
&/code&&/pre&&/div&&h2&定义全局函数或变量&/h2&&p&许多时候我们需要定义一些全局函数或变量,来处理一些频繁的操作(这里拿 AJAX 的异常处理举例说明)。但是在 Vue 中,每一个单文件组件都有一个独立的上下文(this)。通常在异常处理中,需要在视图上有所体现,这个时候我们就需要访问 this 对象,但是全局函数的上下文通常是 window,这时候就需要一些特殊处理了。&/p&&h2&简单粗暴型&/h2&&p&最简单的方法就是直接在 window 对象上定义一个全局方法,在组件内使用的时候用 bind、call 或 apply 来改变上下文。&/p&&p&  定义一个全局异常处理方法:&/p&&div class=&highlight&&&pre&&code class=&language-js&&&span&&/span&&span class=&c1&&// errHandler.js&/span&
&span class=&nb&&window&/span&&span class=&p&&.&/span&&span class=&nx&&errHandler&/span& &span class=&o&&=&/span& &span class=&kd&&function&/span& &span class=&p&&()&/span& &span class=&p&&{&/span& &span class=&c1&&// 不能使用箭头函数&/span&
&span class=&k&&if&/span& &span class=&p&&(&/span&&span class=&nx&&err&/span&&span class=&p&&.&/span&&span class=&nx&&code&/span& &span class=&o&&&&&/span& &span class=&nx&&err&/span&&span class=&p&&.&/span&&span class=&nx&&code&/span& &span class=&o&&!==&/span& &span class=&mi&&200&/span&&span class=&p&&)&/span& &span class=&p&&{&/span&
&span class=&k&&this&/span&&span class=&p&&.&/span&&span class=&nx&&$store&/span&&span class=&p&&.&/span&&span class=&nx&&commit&/span&&span class=&p&&(&/span&&span class=&s1&&'err'&/span&&span class=&p&&,&/span& &span class=&kc&&true&/span&&span class=&p&&)&/span&
&span class=&p&&}&/span& &span class=&k&&else&/span& &span class=&p&&{&/span&
&span class=&c1&&// ...&/span&
&span class=&p&&}&/span&
&span class=&p&&}&/span&
&/code&&/pre&&/div&&p&在入口文件中导入:&/p&&div class=&highlight&&&pre&&code class=&language-js&&&span&&/span&&span class=&c1&&// src/main.js&/span&
&span class=&kr&&import&/span& &span class=&s1&&'errHandler.js'&/span&
&/code&&/pre&&/div&&p&在组件中使用:&/p&&div class=&highlight&&&pre&&code class=&language-js&&&span&&/span&&span class=&c1&&// xxx.vue&/span&
&span class=&kr&&export&/span& &span class=&k&&default&/span& &span class=&p&&{&/span&
&span class=&nx&&created&/span& &span class=&p&&()&/span& &span class=&p&&{&/span&
&span class=&k&&this&/span&&span class=&p&&.&/span&&span class=&nx&&errHandler&/span& &span class=&o&&=&/span& &span class=&nb&&window&/span&&span class=&p&&.&/span&&span class=&nx&&errHandler&/span&&span class=&p&&.&/span&&span class=&nx&&bind&/span&&span class=&p&&(&/span&&span class=&k&&this&/span&&span class=&p&&)&/span&
&span class=&p&&},&/span&
&span class=&nx&&method&/span&&span class=&o&&:&/span& &span class=&p&&{&/span&
&span class=&nx&&getXXX&/span& &span class=&p&&()&/span& &span class=&p&&{&/span&
&span class=&k&&this&/span&&span class=&p&&.&/span&&span class=&nx&&$http&/span&&span class=&p&&.&/span&&span class=&nx&&get&/span&&span class=&p&&(&/span&&span class=&s1&&'xxx/xx'&/span&&span class=&p&&).&/span&&span class=&nx&&then&/span&&span class=&p&&(({&/span& &span class=&nx&&body&/span&&span class=&o&&:&/span& &span class=&nx&&result&/span& &span class=&p&&})&/span& &span class=&o&&=&&/span& &span class=&p&&{&/span&
&span class=&k&&if&/span& &span class=&p&&(&/span&&span class=&nx&&result&/span&&span class=&p&&.&/span&&span class=&nx&&code&/span& &span class=&o&&===&/span& &span class=&mi&&200&/span&&span class=&p&&)&/span& &span class=&p&&{&/span&
&span class=&c1&&// ...&/span&
&span class=&p&&}&/span& &span class=&k&&else&/span& &span class=&p&&{&/span&
&span class=&k&&this&/span&&span class=&p&&.&/span&&span class=&nx&&errHandler&/span&&span class=&p&&(&/span&&span class=&nx&&result&/span&&span class=&p&&)&/span&
&span class=&p&&}&/span&
&span class=&p&&}).&/span&&span class=&k&&catch&/span&&span class=&p&&(&/span&&span class=&k&&this&/span&&span class=&p&&.&/span&&span class=&nx&&errHandler&/span&&span class=&p&&)&/span&
&span class=&p&&}&/span&
&span class=&p&&}&/span&
&span class=&p&&}&/span&
&/code&&/pre&&/div&&h2&优雅安全型&/h2&&p&在大型多人协作的项目中,污染 window 对象还是不太妥当的。特别是一些比较有个人特色的全局方法(可能在你写的组件中几乎处处用到,但是对于其他人来说可能并不需要)。这时候推荐写一个模块,更优雅安全,也比较自然,唯一不足之处就是每个需要使用该函数或方法的组件都需要进行导入。&/p&&p&  使用方法与前一种大同小异,就不多作介绍了。 ̄ω ̄=&/p&&h2&Moment.JS 与 Webpack&/h2&&p&在使用 Moment.js 遇到一些问题,发现最终打包的文件中将 Moment.js 的全部语言包都打包了,导致最终文件徒然增加 100+kB。查了一下,发现可能是 webpack 打包或是 Moment.js 资源引用问题(?),目前该问题还未被妥善处理,需要通过一些 trick 来解决这个问题。&/p&&p&  在 webpack 的生产配置文件中的 plugins 字段中添加一个插件,使用内置的方法类 &a href=&/?target=https%3A//webpack.js.org/plugins/context-replacement-plugin/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&ContextReplacementPlugin&i class=&icon-external&&&/i&&/a& 过滤掉 Moment.js 中那些用不到的语言包:&/p&&div class=&highlight&&&pre&&code class=&language-js&&&span&&/span&&span class=&c1&&// build/webpack.prod.conf.js&/span&
&span class=&k&&new&/span& &span class=&nx&&webpack&/span&&span class=&p&&.&/span&&span class=&nx&&ContextReplacementPlugin&/span&&span class=&p&&(&/span&&span class=&sr&&/moment[\\/]locale$/&/span&&span class=&p&&,&/span& &span class=&sr&&/^\.\/(zh-cn)$/&/span&&span class=&p&&)&/span&
&/code&&/pre&&/div&&blockquote&解决方案采自 &a href=&/?target=https%3A///webpack/webpack/issues/3128%23issuecomment-& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&oleg-nogin@webpack/webpack#3128&i class=&icon-external&&&/i&&/a&。 &br&问题讨论详见 GitHub Issue: &a href=&/?target=https%3A///moment/moment/issues/2373& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&moment/moment#2373&i class=&icon-external&&&/i&&/a&、&a href=&/?target=https%3A///webpack/webpack/issues/3128& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&webpack/webpack#3128&i class=&icon-external&&&/i&&/a&。&/blockquote&&h2&自定义路径别名&/h2&&p&可能有些人注意到了,在 vue-cli 生成的模板中在导入组件时使用了这样的语法:&/p&&div class=&highlight&&&pre&&code class=&language-js&&&span&&/span&&span class=&kr&&import&/span& &span class=&nx&&Index&/span& &span class=&nx&&from&/span& &span class=&s1&&'@/components/Index'&/span&
&/code&&/pre&&/div&&p&这个 @ 是什么东西?后来改配置文件的时候发现这个是 webpack 的配置选项之一:路径别名。&/p&&p&  我们也可以在基础配置文件中添加自己的路径别名,比如下面这个就把 ~ 设置为路径 src/components 的别名:&/p&&div class=&highlight&&&pre&&code class=&language-js&&&span&&/span&&span class=&c1&&// build/webpack.base.js&/span&
&span class=&p&&{&/span&
&span class=&nx&&resolve&/span&&span class=&o&&:&/span& &span class=&p&&{&/span&
&span class=&nx&&extensions&/span&&span class=&o&&:&/span& &span class=&p&&[&/span&&span class=&s1&&'.js'&/span&&span class=&p&&,&/span& &span class=&s1&&'.vue'&/span&&span class=&p&&,&/span& &span class=&s1&&'.json'&/span&&span class=&p&&],&/span&
&span class=&nx&&alias&/span&&span class=&o&&:&/span& &span class=&p&&{&/span&
&span class=&s1&&'vue$'&/span&&span class=&o&&:&/span& &span class=&s1&&'vue/dist/vue.esm.js'&/span&&span class=&p&&,&/span&
&span class=&s1&&'@'&/span&&span class=&o&&:&/span& &span class=&nx&&resolve&/span&&span class=&p&&(&/span&&span class=&s1&&'src'&/span&&span class=&p&&),&/span&
&span class=&s1&&'~'&/span&&span class=&o&&:&/span& &span class=&nx&&resolve&/span&&span class=&p&&(&/span&&span class=&s1&&'src/components'&/span&&span class=&p&&)&/span&
&span class=&p&&}&/span&
&span class=&p&&}&/span&
&span class=&p&&}&/span&
&/code&&/pre&&/div&&p&然后我们导入组件的时候就可以这样写:&/p&&div class=&highlight&&&pre&&code class=&language-js&&&span&&/span&&span class=&c1&&// import YourComponent from 'YourComponent'&/span&
&span class=&c1&&// import YourComponent from './YourComponent'&/span&
&span class=&c1&&// import YourComponent from '../YourComponent'&/span&
&span class=&c1&&// import YourComponent from '/src/components/YourComponent'&/span&
&span class=&kr&&import&/span& &span class=&nx&&YourComponent&/span& &span class=&nx&&from&/span& &span class=&s1&&'~/YourComponent'&/span&
&/code&&/pre&&/div&&p&既解决了路径过长的麻烦,又解决了相对路径的烦恼,方便很多吧!ヾ(???ゞ)&/p&&h2&CSS 作用域与模块&/h2&&h2&组件内样式&/h2&&p&通常,组件中 &style&&/style& 标签里的样式是全局的,在使用第三方 UI 库(如:Element)时,全局样式很可能影响 UI 库的样式。我们可以通过添加 scoped 属性来使 style 中的样式只作用于当前组件:&/p&&div class=&highlight&&&pre&&code class=&language-js&&&span&&/span&&span class=&o&&&&/span&&span class=&nx&&style&/span& &span class=&nx&&lang&/span&&span class=&o&&=&/span&&span class=&s2&&&less&&/span& &span class=&nx&&scoped&/span&&span class=&o&&&&/span&
&span class=&err&&@&/span&&span class=&kr&&import&/span& &span class=&s1&&'other.less'&/span&&span class=&p&&;&/span&
&span class=&p&&.&/span&&span class=&nx&&title&/span& &span class=&p&&{&/span&
&span class=&nx&&font&/span&&span class=&o&&-&/span&&span class=&nx&&size&/span&&span class=&o&&:&/span& &span class=&mf&&1.2&/span&&span class=&nx&&rem&/span&&span class=&p&&;&/span&
&span class=&p&&}&/span&
&span class=&o&&&&/span&&span class=&err&&/style&&/span&
&/code&&/pre&&/div&&blockquote&在有 scoped 属性的 style 标签内导入其他样式,同样会受限于作用域,变为组件内样式。复用程度较高的样式不建议这样使用。 &br&另,在组件内样式中应避免使用元素选择器,原因在于元素选择器与属性选择器组合时,性能会大大降低。 &br&--- 两种组合选择器的测试:&a href=&/?target=http%3A///efws/css-selectors/csscreate.php%3Fn%3D1000%26sel%3D.class%255Bclass%255E%253D%2527class%body%3Dbackground%253A%2B%2523CFD%26ne%3D1000& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&classes selector&i class=&icon-external&&&/i&&/a&,&a href=&/?target=http%3A///efws/css-selectors/csscreate.php%3Fn%3D1000%26sel%3Da%255Bclass%255E%253D%2527class%body%3Dbackground%253A%2B%2523CFD%26ne%3D1000& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&elements selector&i class=&icon-external&&&/i&&/a& &/blockquote&&h2&导入样式&/h2&&p&相对于 style 使用 scoped 属性时的组件内样式,有时候我们也需要添加一些全局样式。当然我们可以用没有 scoped 属性的 style 来写全局样式。但是相比较,更推荐下面这种写法:&/p&&div class=&highlight&&&pre&&code class=&language-css&&&span&&/span&&span class=&c&&/* 单独的全局样式文件 */&/span&
&span class=&c&&/* style-global.less */&/span&
&span class=&nt&&body&/span& &span class=&p&&{&/span&
&span class=&nb&&font-size&/span&&span class=&o&&:&/span& &span class=&m&&10px&/span&&span class=&p&&;&/span&
&span class=&p&&}&/span&
&span class=&nc&&.title&/span& &span class=&p&&{&/span&
&span class=&nb&&font-size&/span&&span class=&o&&:&/span& &span class=&m&&1&/span&&span class=&o&&.&/span&&span class=&m&&4&/span&&span class=&n&&rem&/span&&span class=&p&&;&/span&
&span class=&nb&&font-weight&/span&&span class=&o&&:&/span& &span class=&nb&&bolder&/span&&span class=&p&&;&/span&
&span class=&p&&}&/span&
&/code&&/pre&&/div&&p&然后在入口文件中导入全局样式:&/p&&div class=&highlight&&&pre&&code class=&language-js&&&span&&/span&&span class=&c1&&// src/main.js&/span&
&span class=&kr&&import&/span& &span class=&s1&&'style-global.less'&/span&
&/code&&/pre&&/div&&h2&获取表单控件值&/h2&&p&通常我们可以直接使用 v-model 将表单控件与数据进行绑定,但是有时候我们也会需要在用户输入的时候获取当前值(比如:实时验证当前输入控件内容的有效性)。&/p&&p&这时我们可以使用 @input 或 @change 事件绑定我们自己的处理函数,并传入 $event 对象以获取当前控件的输入值:&/p&&div class=&highlight&&&pre&&code class=&language-js&&&span&&/span&&span class=&o&&&&/span&&span class=&nx&&input&/span& &span class=&nx&&type&/span&&span class=&o&&=&/span&&span class=&s1&&'text'&/span& &span class=&err&&@&/span&&span class=&nx&&change&/span&&span class=&o&&=&/span&&span class=&s1&&'change($event)'&/span&&span class=&o&&&&/span&
&span class=&nx&&change&/span& &span class=&p&&(&/span&&span class=&nx&&e&/span&&span class=&p&&)&/span& &span class=&p&&{&/span&
&span class=&kd&&let&/span& &span class=&nx&&curVal&/span& &span class=&o&&=&/span& &span class=&nx&&e&/span&&span class=&p&&.&/span&&span class=&nx&&target&/span&&span class=&p&&.&/span&&span class=&nx&&value&/span&
&span class=&k&&if&/span& &span class=&p&&(&/span&&span class=&sr&&/^\d+$/&/span&&span class=&p&&.&/span&&span class=&nx&&test&/span&&span class=&p&&(&/span&&span class=&nx&&curVal&/span&&span class=&p&&))&/span& &span class=&p&&{&/span&
&span class=&k&&this&/span&&span class=&p&&.&/span&&span class=&nx&&num&/span& &span class=&o&&=&/span& &span class=&o&&+&/span&&span class=&nx&&curVal&/span&
&span class=&p&&}&/span& &span class=&k&&else&/span& &span class=&p&&{&/span&
&span class=&nx&&console&/span&&span class=&p&&.&/span&&span class=&nx&&error&/span&&span class=&p&&(&/span&&span class=&s1&&'%s is not a number!'&/span&&span class=&p&&,&/span& &span class=&nx&&curVal&/span&&span class=&p&&)&/span&
&span class=&p&&}&/span&
&span class=&p&&}&/span&
&/code&&/pre&&/div&&blockquote&当然,如果 UI 框架采用 Element 会更简单,它的事件回调会直接传入当前值。&/blockquote&&h2&v-for 的使用 tips&/h2&&p&v-for 指令很强大,它不仅可以用来遍历数组、对象,甚至可以遍历一个数字或字符串。&/p&&p&基本语法就不讲了,这里讲个小 tips:&/p&&h2&索引值&/h2&&p&在使用 v-for 根据对象或数组生成 DOM 时,有时候需要知道当前的索引。我们可以这样:&/p&&div class=&highlight&&&pre&&code class=&language-html&&&span&&/span&&span class=&p&&&&/span&&span class=&nt&&ul&/span&&span class=&p&&&&/span&
&span class=&p&&&&/span&&span class=&nt&&li&/span& &span class=&na&&v-for&/span&&span class=&o&&=&/span&&span class=&s&&'(item, key) in items'&/span& &span class=&na&&:key&/span&&span class=&o&&=&/span&&span class=&s&&'key'&/span&&span class=&p&&&&/span& {{ key }} - {{ item }}
&span class=&p&&&/&/span&&span class=&nt&&ul&/span&&span class=&p&&&&/span&
&/code&&/pre&&/div&&p&&b&但是&/b&,在遍历数字的时候需要注意,数字的 value 是从 1 开始,而 key 是从 0 开始:&/p&&div class=&highlight&&&pre&&code class=&language-html&&&span&&/span&&span class=&p&&&&/span&&span class=&nt&&ul&/span&&span class=&p&&&&/span&
&span class=&p&&&&/span&&span class=&nt&&li&/span& &span class=&na&&v-for&/span&&span class=&o&&=&/span&&span class=&s&&'(v, k) in 3'&/span& &span class=&na&&:key&/span&&span class=&o&&=&/span&&span class=&s&&'k'&/span&&span class=&p&&&&/span& {{ k }}-{{ v }}
&span class=&c&&&!-- output to be 0-1, 1-2, 2-3 --&&/span&
&span class=&p&&&/&/span&&span class=&nt&&ul&/span&&span class=&p&&&&/span&
&/code&&/pre&&/div&&blockquote&2.2.0+ 的版本里,当在组件中使用 v-for 时,key 现在是必须的。&/blockquote&&h2&模板的唯一根节点&/h2&&p&与 JSX 相同,组件中的模板只能有一个根节点,即下面这种写法是 &b&错误&/b& 的:&/p&&div class=&highlight&&&pre&&code class=&language-html&&&span&&/span&&span class=&p&&&&/span&&span class=&nt&&template&/span&&span class=&p&&&&/span&
&span class=&p&&&&/span&&span class=&nt&&h1&/span&&span class=&p&&&&/span&Title&span class=&p&&&/&/span&&span class=&nt&&h1&/span&&span class=&p&&&&/span&
&span class=&p&&&&/span&&span class=&nt&&article&/span&&span class=&p&&&&/span&Balabala...&span class=&p&&&/&/span&&span class=&nt&&article&/span&&span class=&p&&&&/span&
&span class=&p&&&/&/span&&span class=&nt&&template&/span&&span class=&p&&&&/span&
&/code&&/pre&&/div&&p&我们需要用一个块级元素把他包裹起来:&/p&&div class=&highlight&&&pre&&code class=&language-html&&&span&&/span&&span class=&p&&&&/span&&span class=&nt&&template&/span&&span class=&p&&&&/span&
&span class=&p&&&&/span&&span class=&nt&&div&/span&&span class=&p&&&&/span&
&span class=&p&&&&/span&&span class=&nt&&h1&/span&&span class=&p&&&&/span&Title&span class=&p&&&/&/span&&span class=&nt&&h1&/span&&span class=&p&&&&/span&
&span class=&p&&&&/span&&span class=&nt&&article&/span&&span class=&p&&&&/span&Balabala...&span class=&p&&&/&/span&&span class=&nt&&article&/span&&span class=&p&&&&/span&
&span class=&p&&&/&/span&&span class=&nt&&div&/span&&span class=&p&&&&/span&
&span class=&p&&&/&/span&&span class=&nt&&template&/span&&span class=&p&&&&/span&
&/code&&/pre&&/div&&blockquote&原因参考:&a href=&/?target=https%3A//blog.beard.ink/JavaScript/React-%25E5%25B0%258F%25E8%25AE%25B0%25EF%25BC%259A%25E7%25BB%%25BB%25B6%25E5%25BC%%258F%%25B3%25A8%25E6%E4%25BA%258B%25E9%25A1%25B9/%23%25E5%2594%25AF%25E4%25B8%%25A0%25B9%25E8%258A%%& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&React-小记:组件开发注意事项#唯一根节点&i class=&icon-external&&&/i&&/a&&/blockquote&&h2&项目路径配置&/h2&&p&由于 vue-cli 配置的项目提供了一个内置的静态服务器,在开发阶段基本不会有什么问题。但是,当我们把代码放到服务器上时,经常会遇到静态资源引用错误,导致界面一片空白的问题。&/p&&p&这是由于 vue-cli 默认配置的 webpack 是以站点根目录引用的文件,然而有时候我们可能需要把项目部署到子目录中。&/p&&p&我们可以通过 config/index.js 来修改文件引用的相对路径:&/p&&div class=&highlight&&&pre&&code class=&language-js&&&span&&/span&&span class=&nx&&build&/span&&span class=&p&&.&/span&&span class=&nx&&assetsSubDirectory&/span&&span class=&o&&:&/span& &span class=&s1&&'static'&/span&
&span class=&nx&&build&/span&&span class=&p&&.&/span&&span class=&nx&&assetsPublicPath&/span&&span class=&o&&:&/span& &span class=&s1&&'/'&/span&
&span class=&nx&&dev&/span&&span class=&p&&.&/span&&span class=&nx&&assetsSubDirectory&/span&&span class=&o&&:&/span& &span class=&s1&&'static'&/span&
&span class=&nx&&dev&/span&&span class=&p&&.&/span&&span class=&nx&&assetsPublicPath&/span&&span class=&o&&:&/span& &span class=&s1&&'/'&/span&
&/code&&/pre&&/div&&p&我们可以看到导出对象中 build 与 dev 均有 assetsSubDirectory、assetsPublicPath 这两个属性。&/p&&p&其中 &b&assetsSubDirectory&/b& 指静态资源文件夹,也就是打包后的 js、css、图片等文件所放置的文件夹,这个默认一般不会有问题。&/p&&p&&b&assetsPublicPath&/b& 指静态资源的引用路径,默认配置为 /,即网站根目录,与 &b&assetsSubDirectory&/b& 组合起来就是完整的静态资源引用路径 /static。&/p&&p&写到这里解决方法已经很明显了,只要把根目录改为相对目录就好了:&/p&&div class=&highlight&&&pre&&code class=&language-js&&&span&&/span&&span class=&nx&&build&/span&&span class=&p&&.&/span&&span class=&nx&&assetsSubDirectory&/span&&span class=&o&&:&/span& &span class=&s1&&'static'&/span&
&span class=&nx&&build&/span&&span class=&p&&.&/span&&span class=&nx&&assetsPublicPath&/span&&span class=&o&&:&/span& &span class=&s1&&'./'&/span&
&/code&&/pre&&/div&&p&没错!就是一个 . 的问题。ㄟ( ▔, ▔ )ㄏ&/p&&h2&异步组件&/h2&&p&  使用处于 Stage.3 阶段的动态导入函数 import(),同时借助 webpack 的代码分割功能,在 Vue.js 中我们可以很轻松地实现一个异步组件。&/p&&h2&异步路由组件&/h2&&div class=&highlight&&&pre&&code class=&language-js&&&span&&/span&&span class=&kr&&const&/span& &span class=&nx&&AsyncComponent&/span& &span class=&o&&=&/span& &span class=&p&&()&/span& &span class=&o&&=&&/span& &span class=&kr&&import&/span&&span class=&p&&(&/span&&span class=&s1&&'./AsyncComponent'&/span&&span class=&p&&)&/span&
&/code&&/pre&&/div&&h2&异步组件工厂&/h2&&div class=&highlight&&&pre&&code class=&language-js&&&span&&/span&&span class=&nx&&Vue&/span&&span class=&p&&.&/span&&span class=&nx&&component&/span&&span class=&p&&(&/span&
&span class=&s1&&'async-webpack-example'&/span&&span class=&p&&,&/span&
&span class=&p&&()&/span& &span class=&o&&=&&/span& &span class=&kr&&import&/span&&span class=&p&&(&/span&&span class=&s1&&'./my-async-component'&/span&&span class=&p&&)&/span&
&span class=&p&&)&/span&
&/code&&/pre&&/div&&blockquote&相比于异步路由组建,异步组件工厂一般适用于组件内进一步小颗粒度的拆分处理,如:大体量组件内初次加载时的非必要组件(组件内嵌套的弹窗组件或 Popover 组件等)。&/blockquote&&p&&br&&/p&&p&&b&To be continue...&/b&&/p&&blockquote&&b&文章还在完善中,欢迎大家一起讨论 Vue.JS 开发中遇到的一些问题哈 (?▽?)/&/b&&br&&br&看看你的收藏列表,你确定收藏了会记得看吗_(:зゝ∠)_&br&读一读开发的时候至少会有个印象,点个赞打卡啦~&br&&br&原文:&a href=&/?target=https%3A//blog.beard.ink/JavaScript/VueJS-%25E5%25BC%%258F%%25B8%25B8%25E8%25A7%%2597%25AE%25E9%25A2%%259B%%/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&VueJS 开发常见问题集锦&i class=&icon-external&&&/i&&/a&&/blockquote&
由于公司的前端开始转向 VueJS,最近开始使用这个框架进行开发,遇到一些问题记录下来,以备后用。 主要写一些
上没有写,但是实际开发中会遇到的问题,需要一定知识基础。涉及技术栈CLI: UI: HTML: CSS: JavaScript:
&img src=&/50/v2-5f211d6daceee8f7c328218_b.jpg& data-rawwidth=&686& data-rawheight=&437& class=&origin_image zh-lightbox-thumb& width=&686& data-original=&/50/v2-5f211d6daceee8f7c328218_r.jpg&&&p&如果你使用 Laravel 加 Vuejs 技术栈来开发 Web 应用的话,其实你会发现,这两个框架直接有很多思想相通的地方,比如本文要介绍的这个表单验证组件 vee-validate ,这个组件总结为一句话就是:在前端验证里面实现了 laravel 的表单验证,这种实现是指,语法和思想的实现。我们看看&/p&&h2&安装 vee-validate&/h2&&p&直接可以使用 npm 来安装:&/p&&div class=&highlight&&&pre&&code class=&language-bash&&&span&&/span&npm install vee-validate --save
&/code&&/pre&&/div&&h2&使用&/h2&&p&很简单的,在 Laravel 项目的 resources/assets/js/app.js 中添加:&/p&&div class=&highlight&&&pre&&code class=&language-js&&&span&&/span&&span class=&kr&&import&/span& &span class=&nx&&Vue&/span& &span class=&nx&&from&/span& &span class=&s1&&'vue'&/span&&span class=&p&&;&/span&
&span class=&kr&&import&/span& &span class=&nx&&VeeValidate&/span& &span class=&nx&&from&/span& &span class=&s1&&'vee-validate'&/span&&span class=&p&&;&/span&
&span class=&nx&&Vue&/span&&span class=&p&&.&/span&&span class=&nx&&use&/span&&span class=&p&&(&/span&&span class=&nx&&VeeValidate&/span&&span class=&p&&);&/span&
&/code&&/pre&&/div&&p&在组件的表单中使用:&/p&&div class=&highlight&&&pre&&code class=&language-html&&&span&&/span&&span class=&p&&&&/span&&span class=&nt&&input&/span&
&span class=&na&&v-validate&/span&&span class=&o&&=&/span&&span class=&s&&&'required|email'&&/span&
&span class=&na&&type&/span&&span class=&o&&=&/span&&span class=&s&&&text&&/span&
&span class=&na&&name&/span&&span class=&o&&=&/span&&span class=&s&&&email&&/span&&span class=&p&&&&/span&
&/code&&/pre&&/div&&p&你看,这写法跟 laravel 的验证是不是一模一样?或者你也可以这样:&/p&&div class=&highlight&&&pre&&code class=&language-html&&&span&&/span&&span class=&p&&&&/span&&span class=&nt&&input&/span&
&span class=&na&&v-validate&/span&&span class=&o&&=&/span&&span class=&s&&&{ rules: { required: true, email: true } }&&/span&
&span class=&na&&type&/span&&span class=&o&&=&/span&&span class=&s&&&text&&/span&
&span class=&na&&name&/span&&span class=&o&&=&/span&&span class=&s&&&email&&/span&&span class=&p&&&&/span&
&/code&&/pre&&/div&&p&再或者,你可以这样:&/p&&div class=&highlight&&&pre&&code class=&language-html&&&span&&/span&&span class=&p&&&&/span&&span class=&nt&&input&/span&
&span class=&na&&type&/span&&span class=&o&&=&/span&&span class=&s&&&text&&/span&
&span class=&na&&name&/span&&span class=&o&&=&/span&&span class=&s&&&email&&/span&
&span class=&na&&v-validate&/span&&span class=&err&&.&/span&&span class=&na&&initial&/span&&span class=&o&&=&/span&&span class=&s&&&'required|email'&&/span&
&span class=&na&&:class&/span&&span class=&o&&=&/span&&span class=&s&&&{'form-control': true, 'is-danger': errors.has('email') }&&/span&
&span class=&na&&placeholder&/span&&span class=&o&&=&/span&&span class=&s&&&Email&&/span& &span class=&p&&/&&/span&
&/code&&/pre&&/div&&p&这个例子注意的是,我们通过 :class 绑定 css 的类,里面使用了 errors.has('email') 来判断 email 验证是否通过。这里能直接使用 errors 来判断就是因为我们在 app.js 添加Vue.use(VeeValidate)。&/p&&h2&如何获取错误提示&/h2&&p&Easy ! 就像 laravel 那样:&/p&&div class=&highlight&&&pre&&code class=&language-html&&&span&&/span&&span class=&p&&&&/span&&span class=&nt&&div&/span& &span class=&na&&v-show&/span&&span class=&o&&=&/span&&span class=&s&&&errors.has('email')&&/span&
&span class=&na&&class&/span&&span class=&o&&=&/span&&span class=&s&&&help is-danger&&/span&&span class=&p&&&&/span&
{{ errors.first('email') }}
&span class=&p&&&/&/span&&span class=&nt&&div&/span&&span class=&p&&&&/span&
&/code&&/pre&&/div&&p&有没有很像!直接 errors.first('email') 就可以获取到 email 验证的错误信息,而且这个验证信息的显示与否都是实时的!&/p&&h2&最后&/h2&&p&写这个主要是因为我最近在升级 Laravist ,全面改版之后使用了很多 Vuejs 来重写,其中就有用到 vee-validate 来做验证。使用感觉非常不错,就此推荐一波。&/p&&br&&p&&b&关注&/b& &b&codecasts&/b& &b&公众号啊,这周再送书!&/b&&/p&
如果你使用 Laravel 加 Vuejs 技术栈来开发 Web 应用的话,其实你会发现,这两个框架直接有很多思想相通的地方,比如本文要介绍的这个表单验证组件 vee-validate ,这个组件总结为一句话就是:在前端验证里面实现了 laravel 的表单验证,这种实现是指,语法…
&p&———————————更新于日——————————————&/p&&p&写了篇vue项目如何debug的文章:&a href=&///?target=http%3A///vuejs-project-debug.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&VueJS项目调试(debug) - Yakima Teng | 滕运锋&i class=&icon-external&&&/i&&/a&&/p&&p&还有篇讲vue+vuex项目本地数据持久化的:&a href=&///?target=http%3A///vuex-data-persistence.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Vuex Data Persistence数据持久化 - Yakima Teng | 滕运锋&i class=&icon-external&&&/i&&/a&&/p&&p&———————————旧文(发布于日)——————————————&/p&&p&我们项目部也在用,因为就我一个前端,所以框架我自己定的。&/p&&p&公司不大,说出来你们也没听过-_-。&/p&&p&从最初用客户端vue.js,到后面用vue-cli使用的Vue1 + webpack模版,再到后面使用Vue2+webpack,用这个框架做SPA应用也有一年半的时间了。做一些总结吧,想到哪里写哪里(针对Vue2 + webpack)。&/p&&h2&一、页面按需加载&/h2&&p&这主要是为了加快首屏加载速度。这样做的好处是第一屏所需加载的文件大小变小了,代价是如果用户会走完整个SPA的话,实际的总代码下载量是变多了的。按需加载页面主要就是修改/src/router/index.js文件,示例代码如下:&/p&&div class=&highlight&&&pre&&code class=&language-text&&import Vue from 'vue'
import Router from 'vue-router'
Vue.use(Router)
const Home = resolve =& require(['@/views/Home.vue'], resolve)
const MyRoot = resolve =& require(['@/views/my/Root.vue'], resolve)
const MyIndex = resolve =& require(['@/views/my/Index.vue'], resolve)
const MyLogs = resolve =& require(['@/views/my/Logs.vue'], resolve)
const MyBrokerages = resolve =& require(['@/views/my/Brokerages.vue'], resolve)
export default new Router({
path: '/home',
name: 'Home',
component: Home,
meta: { needLogin: false }
path: '/my',
name: 'MyRoot',
component: MyRoot,
meta: { needLogin: true },
children: [
redirect: 'index'
path: 'index',
name: 'MyIndex',
component: MyIndex,
meta: { needLogin: true }
path: 'logs',
name: 'MyLogs',
component: MyLogs,
meta: { needLogin: true }
path: 'brokerages',
name: 'MyBrokerages',
component: MyBrokerages,
meta: { needLogin: true }
// must be placed at the bottom
{ path: '*', redirect: '/home' }
&/code&&/pre&&/div&&p&因为觉得上面那样引入组件的代码重复的地方很多,本着DRY(Don't Repeat Yourself,中文意思是“懒” -_-)的原则,试过用下面这种方式引入组件:&/p&&div class=&highlight&&&pre&&code class=&language-text&&function generateComponentFunction (path) {
retur}

我要回帖

更多关于 vue import from 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信