当前位置: 首页 > Web前端 > CSS

Vue2.0项目开发总结

时间:2023-03-30 23:21:54 CSS

项目架构项目目录├──build├──config├──dist│└──static│├──css│├──fonts│├──images│├──js│└──lib├──src│├──api│├──assets││├──global││└──images││└──footer│├──components││├──common││├──新闻││└──简介││└──收费│├──配置│├──mixin│├──路由器│├──服务│├──store│└──util└──static├──images└──lib项目目录是vue-cli自动生成的,你可以根据需要创建其他的。开发实践动态修改不同路由页面的文档标题。我们需要动态修改文档标题。我们可以在路由元信息中配置每个页面的标题,然后在router中修改afterEach钩子函数:importVuefrom'vue';importRouterfrom'vue-router';Vue.use(Router);constrouter=newRouter({mode:'history',routes:[{path:'/',component:Index,meta:{title:'推荐产品获得巨额红利'}},{path:'/news',component:新闻,meta:{title:'ListofAnnouncements'},children:[{path:'',redirect:'list'},{path:'list',component:NewsList},{path:'detail/:newsId',component:NewsDetail,meta:{title:'公告详情'}}]},{path:'/guide',component:GuideProtocol,meta:{title:'新手指南'}}]});//使用afterEach钩子函数确保在路由成功重定向后修改标题。afterEach((route)=>{letdocumentTitle='xxx商城会员平台';route.matched.forEach((path)=>{if(path.meta.title){documentTitle+=`-${path.meta.title}`;}});document.title=documentTitle;});根据URL变化动态更新数据通常在一个列表集合页面中,我们需要进行分页操作,而分页数据需要体现在URL中,那么如何根据URL的变化动态获取数据,我们可以使用watchAPI来监控$watch中的route,同样使用this.$router.replaceAPI改变URL值以下是示例代码common.js:importqsfrom'qs';exportdefault{data(){return{queryParams:{currentPage:1,pageSize:10}};},方法:{handlePageNoChange(e){this.queryParams.currentPage=e;这个.replaceRouter();},replaceRouter(){constquery=qs.stringify(this.queryParams);this.$router.replace(`${location.pathname}?${query}`);},routeChange(){this.assignParams();这个.fetchData();},assignParams(){this.queryParams=Object.assign({},this.queryParams,this.$route.query);}},mounted(){this.assignParams();这个.fetchData();},观看:{$route:'routeChange'}};我们把这部分代码抽取出来放到一个公共的mixin中,在需要的组件中引入它也实现了自定义的fetchData()方法mixin的同名API文档:https://cn.vuejs.org/v2/guide...exportdefaultDemoComponent{mixins:[common],data(){return{//组件内部同名的自定义查询参数将与mixin中的默认参数合并queryParams:{categoryId:'',pageSize:12},}},methods:{fetchData(){//发送请求}}}EventBus使用场景我们在项目中引入了vuex,通常是不需要使用eventbus的,但是有一种情况我们需要用到,也就是在routinghook函数里面的时候,在项目中,我们需要在beforeEnter路由hook外面抛出一个事件,在这个hook函数里面我们是不能去this对象的beforeEnter:(to,from,next)=>{constuserInfo=localStorage.getItem(userFlag);如果(isPrivateMode()){EventBus.$emit('get-localdata-error');下一个(假);返回;}})在App.vueEventBus的mounted方法中监听这个事件。$on('get-localdata-error',()=>{this.$alert('Donotbrowseinincognitomode');});自定义命令实现埋点数据统计在项目中,通常需要做数据埋点。这时候使用自定义命令就会变得非常简单。在项目入口文件main.js中配置我们的自定义命令//坑埋点指令Vue.directive('stat',{bind(el,binding){el.addEventListener('click',()=>{constdata=binding.value;letprefix='store';if(OS.isAndroid||OS.isPhone){prefix='mall';}analytics.request({ty:`${prefix}_${data.type}`,dc:data.desc||''},'n');},false);}});在页面级别使用路由拦截统计pv第一次尝试在单页应用中埋点数据,项目上线一周后,数据统计后台发现首页的PV高了很多,其他页面的数据非常不正常。后来和数据后台的人交流,问了他们埋点的统计原理,才发现问题所在。传统应用在页面加载的时候一般都会有一个异步的js加载,就像百度的统计代码一样,所以我们会在每个页面加载的时候统计数据;但是,在单页应用中,页面加载只有一次初始化,所以我们需要手动上报其他页面的统计信息。解决方法是使用vue-router的beforeEach或者afterEachhook来上报数据。使用哪一个最好根据业务逻辑来选择。constanalyticsRequest=(to,from)=>{//只统计页面跳转数据,不统计当前页面query的不同数据//所以这里只用path,如果需要统计query可以使用to.fullPathif(to.path!==from.path){analytics.request({url:`${location.protocol}//${location.host}${to.path}`});}};router.beforeEach((to,from,next)=>{if(to.matched.some(record=>record.meta.requiresAuth)){//这里是登录等前置逻辑判断。//判断通过后,上报数据...analyticsRequest(to,from);}else{//不用判断,直接上报数据analyticsRequest(to,from);next();}});在组件中使用我们自定义的指令使用过滤器来实现显示信息的格式如下图的bonusdata信息所示。我们需要把后台返回的bonus格式化成小数点后两位的格式。同时,如果返回的金额是区间类型,我们需要添加From和¥金额符号配置在入口文件main.js中,我们自定义Vue.filter('money',(value,config={unit:'¥',fixed:2})=>{constmoneyStr=`${value}`;if(moneyStr.indexOf('-')>-1){constscope=moneyStr.split('-');返回`${config.大学t}${parseFloat(scope[0]).toFixed(config.fixed).toString()}from`;}elseif(value===0){返回值;}返回`${config.unit}${parseFloat(moneyStr).toFixed(config.fixed).toString()}`;});在组件中使用:{{detail.priceScope|money}}

费率:{{detail.commissionRateScope}}%

奖金:{{detail.expectedIncome|money}}

axios使用配置在项目中,我们使用axios作为接口请求,在项目/api/common.jsimportaxiosfrom'axios';importqsfrom'qs'中进行全局配置;importstorefrom'../store';//全局默认配置//设置POST请求头axios.defaults.headers.post['Content-Type']='application/x-www-form-urlencoded';//配置CORS跨域axios.defaults.withCredentials=true;axios.defaults.crossDomain=true;//请求发起前的拦截器axios.interceptors.request.use((config)=>{//全局加载状态,触发加载效果store.dispatch('updateLoadingStatus',{isLoading:true});//POST请求参数处理成axiospost方法需要的格式if(config.method==='post'){config.data=qs.stringify(config.data);}//这句话不能省略,否则后续请求无法发起成功。因为无法读取配置参数returnconfig;},()=>{//异常处理store.dispatch('updateLoadingStatus',{isLoading:false});});//响应拦截axios.interceptors.response.use((response)=>{//关闭加载效果store.dispatch('updateLoadingStatus',{isLoading:false});//全局登录过滤,如果没有登录,直接跳转到登录urlif(response.data.code===300){//没有登录window.location.href=getLoginUrl();returnfalse;}//这里返回的response.data被axios包裹了10%,所以这里提取出来returnresponse.data;},(error)=>{store.dispatch('updateLoadingStatus',{isLoading:false});returnPromise.reject(error);});//exportdefaultaxios;那么我们在接口/api/xxx.js中使用importaxiosfrom'./common'就方便多了;constbaseURL='/api/profile';constUSER_BASE_INFO=`${baseURL}/getUserBaseInfo.json`;constUPDATE_USER_INFO=`${baseURL}/saveUserInfo.json`;//更新用户实名认证信息constupdateUserInfo=userinfo=>axios.post(UPDATE_USER_INFO,userinfo);//获取用户基本信息constgetUserBaseInfo=()=>axios.get(USER_BASE_INFO);vuex状态在响应式页面中的妙用由于项目是响应式页面,PC端和移动端存在很多不一致的地方。有时仅通过CSS无法实现交互。这时候我们的vuex状态就派上用场了。我们首先在App.vue中监听页面的resize事件,动态更新vuex中isMobile的状态值window.onresize=throttle(()=>{this.updatePlatformStatus({isMobile:isMobile()});},500);然后,我们就可以在组件层响应不同dom结构的渲染最常见的就是PC端和手机端加载的图片需要不同的规格。这个时候,我们可以这样做:{loadImgAssets(name,suffix='.jpg'){returnrequire(`../assets/images/${name}${this.isMobile?'-mobile':''}${后缀}`);},//动态渲染不同规格的日志下图分别是PC端和移动端的简写,然后配合CSSmediaQuery实现各种布局开发相关的配置反向代理在项目目录config文件下的index.js中configure我们本地的反向代理和端口信息profile':{target:'[真实接口地址]:[端口号]',//例如:http://api.xxx.comchangeOrigin:true,pathRewrite:{'^/api/profile':'/profile'}}...},然后就是我们调用interfac的形式e会变成下面的映射,当我们调用/api/profilee/xxxx,实际调用的是[真实接口地址]/profile/xxxx/api/profile/xxxx=>[真实接口地址]/profile/xxxxnginxconfigureupstreamapi.xxx.com{#ip_hash;server[interfaceServeripaddress]:[port];}server{...location^~/api/profile{indexindex.phpindex.htmlindex.html;proxy_redirect关闭;proxy_set_header主机$host;proxy_set_headerX-Real-IP$remote_addr;proxy_set_headerX-Forwarded-For$proxy_add_x_forwarded_for;proxy_passhttp://api.xxx.com;重写^/api/profile/(.*)$/profile/$1中断;}...}在线部署如果使用路由history模式,需要在nginx中配置将所有请求转发到index.html,在nginx中配置location/{try_files$uri$uri//index.html;}优化。conf或相应站点vhost文件启用静态资源长缓存位置~.*\.(gif|jpg|jpeg|png|bmp|swf|woff|ttf|eot|svg)${expires1y;}location~.*\.(js|css)${expires1y;}对静态资源启用gzip压缩//找到nginx.conf配置文件vim/data/nginx/conf/nginx.confgzipon;gzip_min_length1k;gzip_buffers48k;gzip_http_version1.1;gzip_types文本/普通应用程序/javascript应用程序ation/x-javascript文本/javascript文本/xml文本/css;开启gzip压缩后,页面资源请求大小会大大降低,如下图,说明开启了gzip压缩,问答文章到此结束。如有疏漏或错误,请私信指出,希望本文能给大家带来一点点收获。