vue2.0实践 —— Node + vue 实现移动官网
简介
使用 Node + vue 对公司的官网进行了一个简单的移动端的实现。
源码
https://github.com/wx1993/node-vue-fabaocn
效果
组件
- 轮播图(使用 vue-awesome-swiper 插件)
- 新闻列表
- 新闻详情
- 职位列表
- 联系我们页面(使用百度地图api)
技术
Express、Vue、Vue-Router、Vue-Resource、Webpack
Vue
vue 的组件化思想和 React 很像,一个 vue 组件将 html、css 和 js 都写在一个文件里面,组件管理和维护自己的数据和状态,方便编写也便于调试。
Vue-Resource
作为 vue 全家桶的一员,vue-resource 主要用在 HTTP 请求功能上,类似的工具还有 axios,虽然 vue2.0 推荐使用 axios,但是个人还是习惯于用 vue-resource,使用起来也十分简单,在实例中可以使用以下格式的写法:
this.$http.post('/someUrl', [body], [options]).then(successCallback, errorCallback);
关于 vue-resource 的使用可以参考: http://www.jianshu.com/p/3ce2bd36596e
Vue-Router
vue 通过配合 vue-router 来创建单页应用,其思想是将 vue 组件映射到路由,并将路由挂载到 app 上,在页面中通过 router-link 和 router-view 来定义页面路由并切换到不同的组件。
<!-- html -->
<router-link to="/home">Home</router-link>
// js
import Home from './components/home'
const routes = [
{ path: '/home', component: Home },
]
const router = new VueRouter({
routes
})
const app = new Vue({
router
}).$mount('#app')
构建
Express + Vue + Webpack
项目结构
经典的 node 项目结构配合手动创建的 src 目录(用来放置所有的组件、入口和路由文件)。
安装启动
// 安装依赖
npm install // 项目打包
webpack -w // 启动项目
npm start
几个问题
因为项目本身并不复杂,所以这里仅针对几个难点和遇到的坑进行简单的解释和分析。
1、接口的封装和数据的请求
应用相关的接口都在node中进行封装,具体使用到了 request 模块的 get 和 post 方法,如下:
// 获取职位列表
router.post('/getJobs', function (req, res, next) {
console.log(req.body.jobId);
const jobsUrl = 'http://www.fabao.cn/api/FABAO_WEBSITE/job/getjobinfo?nonce=1494212786000§ionid=' + req.body.jobId +'&pageNumber=1&pageSize=20';
console.log(jobsUrl);
request(jobsUrl, function (error, response, body) {
if(!error && response.statusCode == '200') {
res.send(body)
}
})
})
请求接口在组件中通过 vue-resource 来实现,如下:
getJoblist () {
this.$http.post('/getJobs', { jobId }).then(data => {
console.log(data);
this.items = data.body.res;
}, error => {
console.log(error);
})
}
2、路由地址变化的的监听
在项目中的新闻详情页面有一个点击按钮查看上一篇或下一篇新闻的功能:
这里通过直接在按钮上定义路由中的新闻 id 的增减的方式来实现,如下:
<router-link :to="{name: 'news', params: {id: data.id - 1}}" replace>{{prevTxt}}</router-link>
<router-link :to="{name: 'news', params: {id: data.id + 1}}">{{nextTxt}}</router-link>
但是发现,在点击了按钮之后,地址栏中的 url 确实变了,新闻 id 对应的加1或减1,但是页面内容并没有发生变化,针对这个问题,可以通过监听router 来解决,如下:
watch: {
// 当路由发生变化时自动请求数据
"$route": "getNewsDetail"
}
这样,在 url 发生变化时,就获取新的 url 地址,并主动请求一次数据,从而实现了内容的更新。
getNewsDetail 方法如下:
getNewsDetail () {
// use vue-resource
const curId = this.$route.params.id;
this.$http.post('/getNewsDetail', {id: curId }).then(data => {
if (data.body.res) {
this.prevTxt = '上一篇';
this.nextTxt = '下一篇'
this.data = data.body.res[0]
}else {
if (curId > this.initialId) {
// 点击了下一篇
this.nextTxt = '没有啦';
this.prevTxt = '上一篇';
}else {
// 点击了上一篇
this.prevTxt = '没有啦'
this.nextTxt = '下一篇'
}
}
}, error => {
console.log(error);
})
}
3、元素的切换和显示隐藏
使用 jquery 来实现元素的切换和显示隐藏十分简单,只要控制元素的display属性或者show()/hide()方法或者通过添加和移除类名的方式来实现,但是在 vue 中,因为不便于直接操作 dom 元素,所以在实现这样的效果的时候需要转换思路。以"加入我们"页面的效果为例:
在实现上方标签的切换和高亮,以及下方职位列表信息的现实隐藏,都涉及到元素属性和样式的变化,这里主要是通过动态的类名和 v-show 的方式来实现。
首先,岗位标签的结构如下:
<div class="job-type">
<span @click="getJoblist(6)" :class="{active: activeId == 6}">急招岗位</span>
<span @click="getJoblist(7)" :class="{active: activeId == 7}">日常岗位</span>
<span @click="getJoblist(8)" :class="{active: activeId == 8}">校园招聘</span>
</div>
在这里,点击不同的标签会传入不同的参数,并请求不同的岗位信息来实现下方列表的更新,同时为每一个标签都绑定了一个 active 的类名,并通过判断当前点击的标签 id 来控制类名的有无。
getJoblist (jobId) {
this.activeId = jobId;
this.$http.post('/getJobs', { jobId }).then(data => {
console.log(data);
this.items = data.body.res;
}, error => {
console.log(error);
})
}
可以看到,在请求职位列表的方法中,首先便通过传入的 jobId 来设置当前的标签 id,因为标签 id 是定义在 data 中的,所以所有的标签都共享一个 activeId,因此当点击了标签时,传入的 id 便是当前的标签 id,对应的类名 active 也就为真,同时其他的标签对应的 active 为假,通过这种方式来实现类名的控制。
同样,在下方职位列表信息的现实隐藏上也使用了类似的方式,不同的地方在于,在点击了对应的职位时,不仅需要显示详细信息,还需明确当前点击的是哪一项,因此这里需要用到两个判断:
<section class="job-info" @click="showDetail(item.id)">
<h3>{{item.name}}</h3>
<div>
<address>{{item.company_name}}</address>
<span>{{item.type}}</span>
<time>{{item.create_date}}</time>
</div>
</section>
<transition name="fade">
<section class="job-detail" v-show="jobId === item.id && ifShow">
<h4>职位描述</h4>
<p>
<span>岗位职责</span>
<pre>{{item.require}}</pre>
<span>任职资格</span>
<pre>{{item.description}}</pre>
</p>
</section>
</transition>
ifShow 在 组件的 data 中定义,默认为 false,当点击列表,触发showDetail(item.id)方法时,传入当前列表项的id,并赋值给 jobId,同时修改 ifShow,这样通过两个布尔值的综合判断,可以决定当前点击项对应的详情是否显示。
4、百度地图的使用
在联系我们页面中使用到了百度地图,同时点击地址列表,会对地图信息进行切换和定位,如下:
下面简单介绍一下在vue组件中百度地图的使用方法。
首先进入百度地图API官网(http://lbsyun.baidu.com/index.php?title=jspopular),点击【获取密钥】,然后验证邮箱,之后根据提示(参照【开发指南】)进行配置,提交后就能获得一串密钥,这在引入的api库需要用到。
在 index.html 中引入百度地图API
<script src="http://api.map.baidu.com/api?v=2.0&ak=您的密钥" type="text/javascript"></script>
在组件中使用:
mounted () {
this.showMap(121.407585, 31.176521);
},
methods: {
showMap (x, y, locationId) {
this.locationId = locationId;
this.showNumber = !this.showNumber;
var map = new BMap.Map("container"); // 创建地图实例
var point = new BMap.Point(x, y); // 创建点坐标
map.centerAndZoom(point, 17); // 初始化地图,设置中心点坐标和地图级别
}
}
这里定义了一个 showMap() 方法,在里面初始化了地图并通过传入的经纬度参数来创建坐标。这部分代码直接参照百度地图api的实例即可。在方法中还传入了一个 locationId,这是因为这里有三个地址,所以要通过这个 id 进行区分。
<div class="location-item">
<div class="location-info clearfix" @click="showMap(121.407585, 31.176521, 1)">
<div class="location-icon">
<img src="/images/home1.png">
</div>
<div class="location-content">
<h3>上海总部</h3>
<p>徐汇区宜山路1009号18楼</p>
</div>
</div>
<div class="contact-way" v-show="showNumber && locationId == 1">
<p>电话:<a href="tel: 021-54268114">021-54268114</a></p>
<p>传真:<a href="tel: 021-54278114">021-54278114</a></p>
</div>
</div>
可以看到,在点击地址列表的时候触发了showMap()方法,并传入了当前地址的经纬度和列表项的 id,从而触发地图信息的更新。其中经纬度可以在百度地图中获取,这里推荐百度地图生成器,http://api.map.baidu.com/lbsapi/creatmap/index.html,在这里可以通过输入地名进行定位,并获取经纬度,同时可以设置级别,添加标注等等,更便捷的是,在设置了相关信息后可以直接获取代码,因此使用起来十分方便,如下所示:
百度地图还提供了很多其他的功能,比如缩放按钮,地图标注、实时交通等等,可以根据需要进行配置。这里就不一一介绍了。
关于项目中的其他问题,欢迎大家和我交流:QQ 596291080
vue2.0实践 —— Node + vue 实现移动官网的更多相关文章
- Node + vue 实现移动官网
简介 使用 Node + vue 对公司的官网进行了一个简单的移动端的实现. 源码 https://github.com/wx1993/node-vue-fabaocn 效果 组件 轮播图(使用 vu ...
- 《Vue2.0 实践揭秘》终于出版啦!
不知不觉间在园子开博都两年多了,最近一些园友问最近去哪了为何都没有新的文章了.最近确实发生了很多的事,一是忙工作二就是忙着写书.这还得多些园子的小编,自两年前发表的"架构师修炼"系 ...
- vue2.0+element+node+webpack搭建的一个简单的后台管理界面
闲聊: 今天是六一儿童节哟,小颖祝大家节日快乐哈哈哈.其实这个demo小颖断断续续做了将近两个礼拜了,心塞的,其实这个也没有多难,主要是小颖有点最近事情有点多,所以就把这个一直拖着,今天好不容易做好了 ...
- vue2.0实践的一些细节
最近用vue2.0做了个活动.做完了回头发现,好像并没有太多的技术难点,而自己好像又做了比较久...只能说效率有待提升啊...简单总结了一些比较细节的点. 1.对于一些已知肯定会有数据的模块,先用一个 ...
- 升讯威微信营销系统开发实践:所见即所得的微官网( 完整开源于 Github)
GitHub:https://github.com/iccb1013/Sheng.WeixinConstruction因为个人精力时间有限,不会再对现有代码进行更新维护,不过微信接口比较稳定,经测试至 ...
- vue框架muse-ui官网文档主题错误毕竟【01】
在使用了element-ui后,总觉得不尽兴,再学一个响应式的muse-ui发现是个小众框架,但是我很喜欢. 指出官网文档里的主题使用描述错误. 首先,在vue-cli里安装raw-loader:np ...
- vue2.0 正确理解Vue.nextTick()的用途
什么是Vue.nextTick() 官方文档解释如下: 在下次 DOM 更新循环结束之后执行延迟回调.在修改数据之后立即使用这个方法,获取更新后的 DOM. 获取更新后的DOM,言外之意就是DOM更新 ...
- Vue2.0 - 全局操作 Vue.set
引:http://www.cnblogs.com/zccblog/p/7192420.html Vue.set 的作用就是在构造器外部操作构造器内部的数据.属性或者方法.比如在vue构造器内部定义了一 ...
- vue 常用的官网
vue.js https://cn.vuejs.org/ v-charts https://v-charts.js.org/#/ (图表,地图) web ...
随机推荐
- 一次安装rpcbind失败引发的思考
问题: yum install rpcbind -y 出现如下错误: Error -.el6.x86_64 error: %pre(rpcbind--.el6.x86_64) scriptlet fa ...
- Java对象的内存模型(一)
前言 新人一枚,刚刚入门编程不久,各方面都在学习当中,博文有什么错误的地方,希望我们可以多多交流! 最近,在开发App后台过程中,需要将项目部署到云服务器上.而云服务器的内存大小却只有1G.要如何做到 ...
- 2.熟悉Java基本类库系列——Java IO 类库
Java中常用的IO操作基本上可以分为四大部分,分别是:File类操作.RandomAccessFile类操作.字节流操作.字符流操作.只要熟练掌握了本文中所列举的所有例子,基本上对于Java的IO流 ...
- asp.net core源码飘香:Configuration组件
简介: 这是一个基础组件,是一个统一的配置模型,配置可以来源于配置文件(json文件,xml文件,ini文件),内存对象,命令行参数,系统的环境变量又或者是你自己扩展的配置源,该组件将各个配置源的数据 ...
- css form表单样式清除
开发项目中表单常用的清楚样式: 1.改变placeholder默认字体颜色 ::-webkit-input-placeholder{color: #333;} :-moz-placeholder{co ...
- 跟着刚哥梳理java知识点——集合(十二)
Java集合分为Collection和Map两种体系 一.Collection接口: Collections接口为我们提供了以下方法: size():返回集合中元素的个数 add(Object obj ...
- jQuery控制元素隐藏和显示
1.jQuery隐藏和显示效果 通过 jQuery,您可以使用 hide() 和 show() 方法来隐藏和显示 HTML 元素: $("#hide").click(functio ...
- 4 安装MPush
cnblogs-DOC 1.服务器环境 2.安装Redis3.安装Zookeeper4.安装MPush5.安装Alloc服务6.完整测试7.常见问题 一.Linux安装Mpush [root@loca ...
- 第三章 Struts2配置详解
3.1 Struts2执行过程 1.获取Struts2资源 2.在应用程序中导入Struts2的类库 3.在web.xml中配置StrutsPrepareAndExecuteFilt ...
- 统计学习方法:罗杰斯特回归及Tensorflow入门
作者:桂. 时间:2017-04-21 21:11:23 链接:http://www.cnblogs.com/xingshansi/p/6743780.html 前言 看到最近大家都在用Tensor ...