使用vue重构资讯页面的实例代码解析

从我接手到将这个页面代码重构前,一直都还是使用angular1的代码去做的,需求来了也是用angular去实现;作为一个憧憬新技术的前端,怎么忍受得了现在还在使用这么有历史感的框架,所以,以前就一直在酝酿着如何将angular重构成vue。

代码结构设计

这个资讯项目代码整体都是使用angular.js来去实现的,而此次想重构的资讯详情页面只是其中的一个页面,所以新建了一个文件夹 /newApp 、作为以后新技术的文件夹,以后使用vue技术的都放在这个文件夹下,区别于原先文件夹 /app 。

在旧的angular1的js文件中,由于页面功能丰富,所有的功能代码全都挤在了同一个js中,这就导致主要的js一共有1500+行的代码。每次打开看到长长的一摞代码、还要在里面找到对应的功能代码,就不禁吐槽其中的不合理。。

所以这次重构,我按照页面中的每个模块、每个功能,来将页面拆分成不同的.vue组件模块,以后想要去维护、或者新增功能时,可以直接去对应的模块文件中修改或者是新增一个vue文件。

components

存放着vue的组件代码

base

这个文件夹下,存放着一些可以被复用的组件

commentInput.vue -- 评论输入框
commentList.vue -- 评论列表
replyBar.vue -- 固定悬浮于底部的评论条、提示用户可以评论
report.vue -- 对评论进行举报会弹出的举报信息框

photoswipe.vue

资讯里面的图片浏览组件、在app内会调用客户端的浏览器组件能力、端外使用第三方组件库photoSwipe的来实现点击浏览大图。

adImg.vue -- 广告展示模块
audioBar.vue -- 语音播放功能模块
bannerTop.vue -- 站外显示的顶部拉新banner模块
comments.vue -- 评论列表功能模块
fontconfig.vue -- 设置字体大小功能模块
footBar.vue -- 展示点赞人数和浏览人数模块
hotRecommend.vue -- 热点推荐模块
mask.vue -- 页面蒙版
relatedStock.vue -- 相关个股模块
relatedTopic.vue -- 关联专题模块
shareBar.vue -- 文末快速分享模块

detailBusiness

在这个文件夹下放着一些资讯的业务js

detailSensor.js -- 引入神策统计的sdk
drawTimeline.js -- 画出股票的行情线图

i18n

语言包

sass

资讯页面用到的sass文件、不过由于node-sass的安装有点麻烦(在技术选型时未考虑此情况),后面可能会重构成使用less来做css的预处理器。

utils

一些公用的函数被抽成单独的文件放在这里

allCommentsMain.js

评论列表页面主js

commentDetailMain.js

评论详情页面主js

eventBus.js --

使用eventBus来实现页面的通信

i18n.js

使用vue-i18n来实现页面的多语言

Main.js

资讯详情页面主js

mixin.js

混入

shareInfoSettingMain.js

将分享的逻辑单独抽取成一个js。这里单独抽成一个js是因为,在安卓的webview加载h5时,会等js文件执行完毕之后才渲染出页面(即用户看到东西),所以页面的主js是进行了延迟加载的,但是分享这一逻辑是希望还是能提前加载,所以单独将这一功能抽取成一个js,让页面按照顺序正常去加载。

组件间通信

因为将页面按照功能拆分成了很多小的模块,在不同的模块之间的通信就需要想方法实现,这些模块之间大多是一种兄弟组件的关系。

我们首先能想到的vue中父子组件的通信功能的实现,但是父子组件的场景不适合现在的多个兄弟组件之间的通信,或者说实现起来很啰嗦。

所以考虑另外两种方法实现:eventBus和vuex。考虑到资讯详情页只有一个单页面,引入vuex的话可能会太重了,使代码体积增加不少,因而使用了EventBus事件总线这一方法来实现。

事件总线

在Vue中可以使用 EventBus来作为沟通桥梁的概念,就像是所有组件共用相同的事件中心,可以向该中心注册发送事件或接收事件,所有组件都可以上下平行地通知其他组件。

具体做法是在eventBus.js这个文件中创建一个vue对象,并且将其export出去。其实就是创建一个vue对象作为eventBus,使用它的 $on 和 $emit 来实现。这种设计模式是发布/订阅模式,即 pub/sub 。

//eventBus.js
import vue from 'Vue';
export default new Vue();

在想要通信的组件中使用 $on 和 $emit 方法。

例如,资讯详情页面有一个接口是去请求几个数据:广告、相关个股等。这个接口其实在页面中只需要在初始化时去请求一次,然后将数据保存下来就好。

所以在Main.js中负责去请求这个接口,然后请求回来了,发布一个 dataReady 的事件,将数据也带出去。而在其他的、需要用到这个初始化数据的组件就去订阅这个事件,拿到初始化的数据后,就将其render到页面中。

// Main.js

_initData() {
 // ****

 //使用eventBus广播这个事件,多个子组件中用到了初始化数据
 EventBus.$emit('dataReady', data);
}

//adImg.vue 广告模块
mounted() {
 EventBus.$on('dataReady', data => {
  // *****
 })
}

//relatedStock.vue 相关个股模块
mounted() {
 Event.$on('dataReady', data => {
  // ****
 })
}

在这里其实有个小优化,可以将直接在Vue的原型上添加一个vue对象实例作为全局的消息总线,就不用每次都去import 一次eventBus.js。

//Main.js
Vue.prototype.$bus = new Vue();
//使用时:
this.$bus.$on('', () => {});

在使用eventbus完成项目之后发现,事件总线这一个机制确实很方便,不同的组件之间可以随意通信,但是由此很容易造成难以管理的灾难。比如,在某个模块中订阅了某个事件,这个事件是从哪里发布的、什么时候发布的,在代码中似乎有点难以搜索发布的时机。

其他特性

资讯详情页面中实现了其他的一些功能,比如多皮肤、多语言这些特性。

多皮肤

多皮肤,使用了css的预处理器sass来实现,用到了sass的变量、混入指令等特性。

首先让视觉给一个不同皮肤下的色彩对照表,然后将其写入sass文件中,用变量来保存对应的颜色值。根据外部的class来使用对应的颜色变量。

面的class则是由后端在渲染html时,将对应的皮肤class添加在最外层的div中,在.vue组件中加入对应的class样式,就能做到随肤、且不闪屏。

不过我一开始在重构时的想法并不是通过三组对皮肤的变量来实现,我一开始的想法是在sass里面,就能拿到对应的皮肤的值,从而在使用时都是只需要知道是要哪个层级的颜色值就可以,而不需要在外部的sass代码里分别写三种。

但是问题在于, 无法将js能拿到的皮肤信息传入sass中 ,这个想了很久也没想到解决方案。如果能在sass中就可以拿到皮肤信息,从而直接赋予元素对应的皮肤值,这样就很方便了。所以这里对sass、less这些语言的局限性也深有感触,它们终究只是一个“预处理器”而已。

多语言

多语言特性,使用了vue-i18n这个插件来实现。

可改进的地方

整合资讯详情页面

其实现在包括资讯详情说是只有一个页面,但由于它具有的评论功能,是可以聚合成一个spa的,包括资讯详情页面(Main.js)、资讯评论列表页面(commentDetailMain.js)、评论详情页面(allCommentsMain.js)。这三个页面用到的技术栈在重构之后非常相似,甚至将公共的组件都已经抽取出来了。但是我在重构时还是把它们三个当成不同的页面拆开了,这一点有待改进。

目前是通过mixin这一特性,将三个页面公共的一些东西抽取在其中,分别在三个页面的js中引入这个mixin,可以避免一些重复的东西。

//mixin.js
// 资讯详情页、资讯评论列表页、资讯评论详情页公用的一些东西

import i18n from './i18n';
import ReplyBar from '**/replyBar.vue';
import BannerTop from '**/bannerTop.vue';
import CommentInput from '**/commentInput.vue';

let mixin = {
 i18n,
 components: {
  ReplyBar, //底部悬浮框
  BannerTop, //顶部的banner条
  CommentInput //评论输入框
 }
}

export default mixin;

---- 后来又想了下,由于当前模式还是使用php渲染html的方式,所以没法做成SPA这样子,只能等待加上了node的ssr之后才能实现= =。

使用less代替sass

由于node-sass的安装有时会出现一些问题,所以还是使用less作为替代比较稳妥..

总结

以上所述是小编给大家介绍的使用vue重构资讯页面的实例代码解析,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对我们网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!

(0)

相关推荐

  • 基于vue cli重构多页面脚手架过程详解

    官方提供的项目生成工具vue-cli没有对多页面webApp的支持,但是在实际的项目中,我们需要这样的脚手架,参考了很多大牛的方法,这里提供了一种我的单页面脚手架转换为多页面脚手架的方案,供大家参考.不好的地方也请大家指正. 准备 使用vue-cli生成一个你需要的单页面项目脚手架,然后我们就要开始我们的改装工程了. 重构过程 步骤一 改变目录结构 step1 在src目录下面新建views文件夹,然后再views文件夹下新建index文件夹 step2 将src目录下的main.js和App.

  • 浅谈vue项目重构技术要点和总结

    前言 最近太忙了,博客好久没有更新了.今天忙里偷闲,简单总结一下最近vue项目重构的一些技术要点. vue数据更新, 视图未更新 这个问题我们经常会遇到,一般是vue数据赋值的时候,vue数据变化了,但是视图没有更新.这个不算是项目重构的技术要点,也和大家分享一下vue2.0通常的解决方案吧! 解决方案如下: 1.通过vue.set方式赋值 Vue.set(数据源, key, newValue) 2. 通过Array.prototype.splice方法 数据源.splice(indexOfIt

  • 利用vue重构有赞商城的思路以及总结整理

    这个是我的第一个vue项目,历时了两个多星期完成吧,通过这个项目了解了vue框架的基本语法以及生命周期等特性,并且了解了vue-loader.vue-cli.vue-router.vuex的基本使用方法,以及使用到axios,swiper,mint-ui,Volecity库,收获颇深,因此想在此简单地叙述一下重构有赞商城的基本思路以及当中的一些重要操作,另外当作对自己项目的回顾以及相关vue知识的总结. 以下是本次项目的代码链接和预览链接: 代码链接:https://github.com/Leo

  • Map.vue基于百度地图组件重构笔记分享

    Map.vue是为iview组件开发的一个基于百度地图的组件,实现了点是否在框内的判断,画多边形覆盖物,添加自定义富文本标记物等功能. 第一步:重构自定义的富文本对象,设置为全局对象. 原代码的富文本对象是声明在addResource这个方法里面的,代码结构非常复杂,在beforeCreate这个钩子函数里面申明为全局的,就可以多次复用,不需要重复声明来了, 否则,每调用一次paintPolygon方法,都要重新声明一次,非常麻烦,效率太低下. 原代码是在父组件中处理好这个富文本对象需要的数据,

  • 使用vue重构资讯页面的实例代码解析

    从我接手到将这个页面代码重构前,一直都还是使用angular1的代码去做的,需求来了也是用angular去实现:作为一个憧憬新技术的前端,怎么忍受得了现在还在使用这么有历史感的框架,所以,以前就一直在酝酿着如何将angular重构成vue. 代码结构设计 这个资讯项目代码整体都是使用angular.js来去实现的,而此次想重构的资讯详情页面只是其中的一个页面,所以新建了一个文件夹 /newApp .作为以后新技术的文件夹,以后使用vue技术的都放在这个文件夹下,区别于原先文件夹 /app . 在

  • 新手vue构建单页面应用实例代码

    本文介绍了新手vue构建单页面应用实例代码,分享给大家,具体如下 步骤: 1.使用vue-cli创建项目 2.使用vue-router实现单页路由 3.用vuex管理我们的数据流 4.使用vue-resource请求我们的node服务端 5.使用.vue文件进行组件化的开发 一.目录结构: 二.搭建项目 先安装 vue-cli: sudo npm install -g vue-cli 使用vue-cli构建初始化项目:vue init webpack project(创建webpack项目并下载

  • Vue仿手机qq的实例代码(demo)

    vue简介 Vue.js(读音 /vjuː/, 类似于 view) 是一套构建用户界面的渐进式框架. Vue 只关注视图层, 采用自底向上增量开发的设计. Vue 的目标是通过尽可能简单的 API 实现响应的数据绑定和组合的视图组件. Vue 学习起来非常简单,本教程基于 Vue 2.1.8 版本测试. 概述 这是一个16年9月份找的开源项目源代码,结合自己的实际情况进行的修改项目,以后内容将会有很大的不同,项目的目标是向QQ看齐 页面效果展示 免责声明 本项目为开源项目,如有类同,纯属巧合.

  • 基于vue 实现token验证的实例代码

    vue-koa2-token 基于vue的 做了token验证 前端部分(对axios设置Authorization) import axios from 'axios' import store from '../store' import router from '../router' //设置全局axios默认值 axios.defaults.timeout = 6000; //6000的超时验证 axios.defaults.headers.post['Content-Type'] =

  • vue超时计算的组件实例代码

    需要对预约单进行超时计算,但是后台和客户端时间不能保证一定一直,所以后台返回客户提交时间和请求结束时间的时间差进行计算. 效果如下(此处只是demo效果,所以有点丑.) 父页面 <template> <div> <div class="dateDiv" :key="index" v-for="(item,index) in TimeArray"> <p>{{item.name}}</p>

  • vue 地图可视化 maptalks 篇实例代码详解

    Maptalks 项目是一个 HTML5 的地图引擎, 基于原生 ES6 Javascript 开发: - 二三维一体化地图, 通过二维地图的旋转 /倾斜增加三维视角 - 插件化设计, 能与其他图形库结合, 开发各种二三维效果, 例如 echarts/d3/THREE 等 - 很认真的优化了绘制性能 - 很重视测试, 有接近 1.5K 个单元测试用例, 所以稳定性还不错, 已经应用在很多大大小小的系统上了 上面是一段 maptalks 官方介绍,下面来创建工程.首先利用 vue-cli3 搭建一

  • vue+Element-ui实现分页效果实例代码详解

    当我们向后台请求大量数据的时候,并要在页面展示出来,请求的数据可能上百条数据或者更多的时候,并不想在一个页面展示,这就需要使用分页功能来去完成了. 1.本次所使用的是vue2.0+element-ui实现一个分页功能,element-ui这个组件特别丰富,分页中给我提供了一个Pagination 分页,使用Pagination 快速完成分页功能 最终效果展示 <div class="deit"> <div class="crumbs"> &l

  • vue中v-text / v-html使用实例代码详解

    废话少说,代码如下所述: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Vue实例中的数据,事件和方法</title> </head> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"><

  • 使用Ajax局部更新Razor页面的实例代码

    Razor功能非常强大,但是本身并不能做到无刷新,所以需要配合ajax使用 本文就做一个简单例子,实现Razor配合ajax做到局部刷新. 首先,我们创建一个MVC项目 让我们创建一个简单的Controller Book 然后对其添加一个视图,并且添加上一些简单的Html代码 @{ ViewBag.Title = "Index"; Layout = null; } <!DOCTYPE html> <html> <head> <meta http

  • Session过期后自动跳转到登录页面的实例代码

    最近做了一个项目其中有需求,要实现自动登录功能,通过查阅相关资料,打算用session监听来做,下面给大家列出了配置监听器的方法: 1.在项目的web.xml文件中添加如下代码: <!--添加Session监听器--> <listener> <listener-class> 监听器路径 </listener-class> </listener> 2.编写java类. public class SessionListener implements

随机推荐