项目前期准备
- 安装Node.js
- 安装vue-cli 脚手架构建工具
- 使用vue-cli脚手架创建工程
vue-cli创建的项目目录结构
了解多页应用与单页应用
多页应用
多页应用由多个完整页面构成,每次页面跳转,后台都会返回一个新的HTML文档。
页面切换慢是因为每一次切换页面都需要发起一个HTTP请求,假设网络较慢就会出现卡顿情况。
单页应用
单页应用由一个外壳页面和多个页面片段构成。
用vue写的项目是单页应用,刷新页面会请求一个HTML文件,切换页面的时候,并不会发起新的请求一个HTML文件,只是页面内容发生了变化。
项目代码的初始化——在移动设备上进行网页的重构或开发
1.在/public/index.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no"> <title>travel</title> </head> <body> <div id="app"></div> </body> </html>
2.在 src/assets 中添加样式初始化文件 reset.css ; border.css
3.本地引入取消延迟300毫秒的控件
npm install fastclick --save
4.在mian.js中引入初始化样式文件及文件的使用
import fastClick from ‘fastclick’ import ‘./assets/reset.css’ import ‘./assets/border.css’ fastClick.attach(document.body)
项目实战 - 旅游网站首页开发
header区域开发——Header.vue
- 本项目使用scss编写css样式
- 限制样式只在当前页面有用,使用scoped对css区域进行修饰。
scoped:在vue组件中,在style标签上添加scoped属性,以表示它的样式作用于当下的模块,很好的实现了样式私有化的目的,这是一个非常好的机制。当一个style标签拥有scoped属性时,它的CSS样式就只能作用于当前的组件,不会对其他组件产生影响
- 移动端布局通常采用rem,由于reset.css里设置了html font-size:50px rem相对于50像素尺寸
- 可以将常使用的CSS值设为全局变量或全局方法
-
在styles文件夹中添加varibles.style和mixins.scss
例如:
@mixin ellipsis() { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
设置以下变量
$bgColor: #00bcd4; $darkTextColor : #333; $headerHeight:0.86rem;
设置以下方法 实现溢出的文字省略号显示 -
在vue.config.js文件中引入varibles.style文件.(注意:由于scss-loader版本不同,loaderOptions 中 additionalData的键名也不同)
css: {
loaderOptions: {
scss: {
additionalData: `@import "~@/assets/styles/varibles.scss";
@import "~@/assets/styles/mixins.scss";`,
} } } -
直接使用全局变量或全局方法
background: $bgColor; @include ellipsis();
使用轮播图
- 在GitHub上搜索vue-awesome-swiper查看该插件与语法
- 安装vue-awesome-swiper查看
cnpm install vue-awesome-swiper --save
- 在main.js中引入vue-awesome-swiper,具体参考 vue-awesome-swiper
import VueAwesomeSwiper from 'vue-awesome-swiper'; import 'swiper/swiper-bundle.min.css'; Vue.use(VueAwesomeSwiper /* { default options with global component } */);
- 完成轮播图组件——Swiper.vue
<template> <div class="wrapper"> <swiper ref="mySwiper" :options="swiperOptions" v-if="showSwiper"> <swiper-slide v-for="item of list" :key="item.id"> <img class="swiper-img" :src="item.imgUrl"> </swiper-slide> <div class="swiper-pagination" slot="pagination"></div> </swiper> </div> </template> <script> export default { name: 'HomeSwiper', props: { list: Array, }, data() { return { swiperOptions: { loop: true, autoplay: 5000, pagination: '.swiper-pagination', clickable: true, }, }; }, computed: { showSwiper() { return this.list.length; }, }, }; </script> <style scoped lang="scss"> // 深度作用选择器 >>> 但如果是sass/less的话可能无法识别,这时候需要使用 /deep/ 选择器 /deep/.swiper-pagination-bullet-active { background-color: #fff !important; } .wrapper { overflow: hidden; width: 100%; height: 0; padding-bottom: 30.47%; background: #eee; .swiper-img { width: 100%; } } // .swiper-slide { // width: 3.75rem; // } </style>此css样式中:
.wrapper { overflow: hidden; width: 100%; height: 0; padding-bottom: 30.47%; }该样式主要是防止网速过慢时页面布局的抖动,其含义是,
wrapper
宽度100%
,高度由宽度的30.47%
自动撑开。
图标区域的开发
- 在iconfont中选择图标并下载至本地,在
src/assets
中放入iconfont目录及iconfont.css
- 修改
iconfont.css
文件中src: url()
路径 -
在
main.js
中引入import './assets/styles/iconfont.css';
-
使用
swiper
进行分页,并利用computed进行计算:每8个图表放一个页面,实现自动构建多页切换的功能computed: { pages() { const pages = []; this.list.forEach((item, index) => { const page = Math.floor(index / 8); if (!pages[page]) { pages[page] = []; } pages[page].push(item); }); return pages; }, },
推荐区域的开发
-
遇到的问题:需要设置min-width让ellipsis()生效
.item-info { flex: 1; padding: .1rem; min-width: 0; }
Ajax获取首页数据
- 使用
axios
进行 ajax 请求
npm install axios --save
- 处理请求的api在开发环境进行重定向
- 将静态资源放在public,然后建立index.json文件(注意:vue cli 3以上 没有static文件 本地文件要放在public)
-
在vue.config.js中添加
devServer: { // webpack-dev-serve提供的 proxy: { '/api': { target: 'http://localhost:8080', pathRewrite: { '^/api': '/mock', } } } }
- 使用ajax传递数据
在Home.vue进行引入:import axios from ‘axios’,调用其他vue页面将参数传递进去
<template> <div> <home-header :city="city"></home-header> <home-swiper :list="swiperList"></home-swiper> <home-icons :list="iconList"></home-icons> <home-recommend :list="recommendList"></home-recommend> <home-weekend :list="weekendList"></home-weekend> </div> </template> <script> import axios from 'axios'; import HomeHeader from './components/Header.vue'; import HomeSwiper from './components/Swiper.vue'; import HomeIcons from './components/Icons.vue'; import HomeRecommend from './components/Recommend.vue'; import HomeWeekend from './components/Weekend.vue'; export default { name: 'Home', components: { HomeHeader, HomeSwiper, HomeIcons, HomeRecommend, HomeWeekend, }, data() { return { city: '', swiperList: [], iconList: [], recommendList: [], weekendList: [], }; }, methods: { getHomeInfo() { axios.get('/api/index.json').then(this.getHomeInfoSucc); }, getHomeInfoSucc(res) { // eslint-disable-next-line no-param-reassign res = res.data; if (res.ret && res.data) { const { data } = res; this.city = data.city; this.swiperList = data.swiperList; this.iconList = data.iconList; this.recommendList = data.recommendList; this.weekendList = data.weekendList; } }, }, mounted() { this.getHomeInfo(); }, }; </script>被调用的页面接收参数并进行使用
props: { list: Array, }, <swiper-slide v-for="item of list" :key="item.id"> <img class="swiper-img" :src="item.imgUrl"> </swiper-slide>
旅游网站首页效果图