1.初始化项目工程
1.1 开发环境
- 开发环境:Window 10
- 开发工具:VScode 1.59.0
- 项目运行环境:node 16.6.2
- 项目包管理工具:npm 7.20.3
- Vue 脚手架: vue-cli 4.5.13
- 代码版本管理工具:git 2.32.0
1.2 开发技术栈
- vue 全家桶(vuejs/vue-router/vuex)
- webpack 增量配置 proxy
- ui 组件库 vant
- axios
- nodejs 模拟数据
1.3 创建项目
vue create m.maizuo.huxinfeng.com
# OR
vue ui
# 1.选择
# ? Please pick a preset:
# Default ([Vue 2] babel, eslint)
# Default (Vue 3) ([Vue 3] babel, eslint)
# > Manually select features
# 2.勾选
# ? Check the features needed for your project:
# (*) Choose Vue version
# (*) Babel
# ( ) TypeScript
# ( ) Progressive Web App (PWA) Support
# (*) Router
# (*) Vuex
# (*) CSS Pre-processors
# >( ) Linter / Formatter
# ( ) Unit Testing
# ( ) E2E Testing
# 3.选择
# ? Choose a version of Vue.js that you want to start the project with (Use arrow keys)
# > 2.x
# 3.x
# 4.选择
# ? Use history mode for router? (Requires proper server setup for index fallback in production) (Y/n) Y
# 5.选择
# ? Pick a CSS pre-processor (PostCSS, Autoprefixer and CSS Modules are supported by default): (Use arrow keys)
# > Sass/SCSS (with dart-sass)
# Sass/SCSS (with node-sass)
# Less
# Stylus
# 6.选择
# ? Where do you prefer placing config for Babel, ESLint, etc.? (Use arrow keys)
# > In dedicated config files
# In package.json
# 7.不保存配置
# ? Save this as a preset for future projects? (y/N) N
1.4 git 版本配置、提交
# Git 全局设置:
git config --global user.name "星宿君"
git config --global user.email "bytedance.hu@qq.com"
# 创建 git 仓库:
cd m.maizuo.huxinfeng.com
git init
git add .
git commit -m "create m.maizuo.huxinfeng.com project in vue"
git remote add origin https://gitee.com/huxinfeng/m.maizuo.huxinfeng.com.git
git push -u origin master
# 创建 git 分支 hxf
git checkout -b hxf
1.5 初始化项目
在 ./ 目录下新建 jsconfig.json
// 配置绝地路径
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@/*": ["src/*"]
}
}
}
在 ./src/router 目录下新建 routes 文件夹,新建 films.js cinemas.js news.js center.js error.js
// 个人中心路由模块
const router = {
path: "/center",
name: "Center",
component: () => import(/* webpackChunkName: "center" */ "@/views/center"),
};
export default router;
// error 错误路由模块
export default {
path: "*",
name: "Error",
component: () => import(/* webpackChunkName: "error" */ "@/views/error"),
children: [
// 404
{
path: "/404",
name: 404,
component: () => import(/* webpackChunkName: "error_404" */ "@/views/error/404.vue"),
},
// 403
{
path: "/403",
name: 403,
component: () => import(/* webpackChunkName: "error_403" */ "@/views/error/403.vue"),
},
],
};
在 ./src/views 目录下新建 films cinemas news center error 文件夹,新建相应的 index.vue
<template lang="zh-CN">
<div>个人中心</div>
</template>
<script>
export default {};
</script>
<style lang="scss" scoped></style>
1.6 路由规划
如果项目中所有的路由都写在入口文件中,那么将不便于编写项目和后期维护,因此路由需要进行模块化处理。
可以先行添加以下几个空的路由模块:
电影模块
电影院模块
资讯模块
个人中心模块
error 模块
如果后续还有其他模块,届时再进行增加即可。
创建模块化的目录及路由文件
./src/router/index.js (路由主入口文件) 修改路由配置对象
使用全局自动化状态路由模块好处,可以避免手动导入子路由(避免写入 import 冗余),由代码自动导入
routes 等价于 ./src/router/routes 文件夹下创建的子路由模块
// 全局自动化 状态路由模块
let moduleFn = require.context("@/router/routes", false, /\.js$/);
const routes = moduleFn.keys().reduce((value, item) => {
let router = moduleFn(item).default;
if (router) {
value.push(router);
}
return value;
}, []);
npm run serve
运行效果图如下,则成功初始化项目
1.7 底部导航
在 https://www.iconfont.cn/ 下载你需要的字体图标,下载 iconFont.css 文件,放置到 ./src/assets/style 目录下
在 ./src/components 目录下新建 FooterNav.vue
<template lang="zh-CN">
<footer>
<ul>
<router-link tag="li" active-class="active" :to="{name: 'Films'}">
<i class="iconfont icon-dianying"></i>
<p>电影</p>
</router-link>
<router-link tag="li" active-class="active" :to="{name: 'Cinemas'}">
<i class="iconfont icon-yingyuan"></i>
<p>电影院</p>
</router-link>
<router-link tag="li" active-class="active" :to="{name: 'News'}">
<i class="iconfont icon-zixun"></i>
<p>资讯</p>
</router-link>
<router-link tag="li" active-class="active" :to="{name: 'Center'}">
<i class="iconfont icon-gerenzhongxin"></i>
<p>个人中心</p>
</router-link>
</ul>
</footer>
</template>
<script>
import "@/assets/style/iconFont.css";
export default {};
</script>
<style lang="scss" scoped>
footer {
width: 100%;
position: fixed;
bottom: 0;
ul {
display: flex;
li {
margin: 3px 0;
flex: 1;
&.active {
color: #fe5100;
}
p {
font-size: 15px;
}
i {
font-size: 15px;
}
}
}
}
</style>
在 https://meyerweb.com/eric/tools/css/reset/ 下载 reset.css 文件,放置到 ./src/assets/style 目录下,在 ./src/main.js 中引入
// 样式重置
import "@/assets/style/reset.css";
将组件 ./src/components/FooterNav.vue 导入到根组件 ./src/App.vue 中并使用
<template>
<div id="app">
<router-view></router-view>
<footer-nav></footer-nav>
</div>
</template>
<script>
import FooterNav from "@/components/FooterNav.vue";
export default {
components: { FooterNav },
};
</script>
运行效果图如下
1.8 移动站 rem 布局
将代码中的 px 转成 rem
rem/vw(100 份)
postcss 模块,但是 vue-cli 已经安装好了,所以就直接装它的一些扩展
postcss-pxtorem 是一款 PostCSS 插件,用于将 px 单位转化为 rem 单位
lib-flexible 用于设置 rem 基准值
# 注意版本,vue-cli 自带的支持是 5 版本
npm i -D postcss-pxtorem@5
# 阿里出一个类库,解决 html 中的 font-size 基准值
npm i -S amfe-flexible
配置 postcss.config.js
// 专门给postcss所用的配置文件
// 此文件一但修改则需要重启服务 运行在nodejs环境中,所以使用commonjs规范
module.exports = {
// postcss要使用的插件
plugins: {
// px转为rem
"postcss-pxtorem": {
// 把一个屏幕分为10等分,以iphone6为基准,ipphone的物理像素就为375px 2倍图布局
rootValue: 37.5,
// 所有的有px单位都会转为rem,除style中你所写的px不会转换
propList: ["*"],
},
},
};
在 ./src/main.js 中引入
// 引入计算基准的类加
import "amfe-flexible";
可以很明显的发现,不同终端自适应字体大小,代码中的 px 转成 rem
1.9 网络请求
安装 axios
npm i axios
在 ./src 目录下创建 utils 文件夹,新建 request.js
// 专门用来进行网络请求的封装
import axios from "axios";
// 创建一个新的 axios 对象实例
const service = axios.create({
// 环境判断
timeout: process.env.NODE_ENV === "development" ? 5000 : 10000,
baseURL: process.env.NODE_ENV === "development" ? "" : "https://api.iynn.cn/film",
});
// 请求拦截器
service.interceptors.request.use(
config => config,
err => Promise.reject(err)
);
// 响应拦截器
service.interceptors.response.use(
response => {
return response.data;
},
err => Promise.reject(err)
);
export const get = (url, config = {}) => service.get(url, config);
export const post = (url, data = {}, config = {}) => service.post(url, data, config);
在 ./src 目录下创建 config 文件夹,新建 filmConfig.js
// 电影请求 url 配置
export default {
films: "https://api.iynn.cn/film/api/v1/getCitiesInfo",
};
在 ./src 目录下创建 api 文件夹,新建 filmApi.js
import config from "@/config/filmConfig";
import { get, post } from "@/utils/request";
export const getFilmsApi = (page = 1) => get(config.films);
在 ./src/views/films/components/NowPlaying.vue 下写入以下测试代码
import { getFilmsApi } from "@/api/filmApi";
export default {
async mounted() {
let res = await getFilmsApi();
console.log(res);
},
};
很明显出现了跨域报错,使用 proxy 代理解决,在 ./src 目录下 新建 vue.config.js
// vue 给开发者暴露出来的增量去配置 webpack 有文件
module.exports = {
// 代理打包生产环境中将不存在,需要通过 nodejs 来完成
devServer: {
// 代理跨域
proxy: {
// 代理 url 关键字
"/getCitiesInfo": {
// 需要代理的地址
target: "https://api.iynn.cn/film/api/v1",
// 如果是 https 接口,需要配置这个参数
secure: true,
// 是否跨域
changeOrigin: true,
// 地址的重写,匹配地址路径和真实的路径有出入
// pathRewrite: {
// "^/getCitiesInfo": "",
// },
},
},
},
};
此时访问控制台,可以拿到数据
2.电影模块开发
vant 组件库:https://vant-contrib.gitee.io/vant/#/zh-CN/
安装 vant 组件 有赞团队开源 移动端组件库
npm i -S vant
vant 组件导入方式一: 全量导入
在 ./src/main.js 写入
// vant组件 -- 全量导入,打包时,打包的js文件体积可能过大,原因在于,此组件库中的ui组件过多,而我们用不到哪么多
import Vant from "vant";
import "vant/lib/index.css";
Vue.use(Vant);
在 ./src/views/films/components/NowPlaying.vue 下写入以下测试代码
<template lang="zh-CN">
<div>
<p>正在热映</p>
<van-button type="primary">主要按钮</van-button>
</div>
</template>
为了减小打包文件体积,我采用另外一种引入方式,也是官方推荐
vant 组件导入方式二: 自动按需引入组件 (推荐)
# 安装插件
# babel-plugin-import 是一款 babel 插件,它会在编译过程中将 import 的写法自动转换为按需引入的方式。
npm i babel-plugin-import -D
在 ./src/babel.config.js 写入
// 实现 vant 组件打包时按需加载,打包后的 js 文件就会小
plugins: [
[
"import",
{
libraryName: "vant",
libraryDirectory: "es",
style: true,
},
"vant",
],
],
在 ./src 创建 plugins 文件夹,新建 vant.js
以后需要用到的组件,直接在里面添加即可
// 专门用来加载 vant 组件
import Vue from "vue";
import { Button } from "vant";
[Button].forEach(cmp => Vue.use(cmp));
在 入口文件 ./src/main.js 写入
// 按需引入
import "@/plugins/vant";
2.1 列表顶部导航
创建电影列表顶部导航组件 ./src/components/FilmListTopNav.vue
Comments NOTHING