从零开始一个前端项目并将其完成需要经历一系列步骤。以下是一个常见的开发流程,可以帮助规划和管理项目:
需求分析和规划:
- 确定项目的目标和范围。
- 定义用户需求和功能要求。
- 制定项目计划和时间表。
技术选型:
- 选择适当的前端技术栈,如HTML、CSS、JavaScript框架。
- 针对项目需求选择合适的工具和库,例如React、Vue.js、Angular等。
创建项目结构:
- 设置项目文件夹和版本控制(如Git)。
- 创建初始的项目文件结构,包括HTML、CSS和JavaScript文件。
设计用户界面:
- 创建项目的用户界面原型。
- 设计UI和UX,包括页面布局、颜色、字体等。
开发前端:
- 编写HTML、CSS和JavaScript代码。
- 制作网页布局和设计,确保响应式设计。
- 添加交互性,例如表单验证、动画等。
- 集成第三方库和API(如数据获取)。
测试和调试:
- 在不同的浏览器和设备上测试项目,确保兼容性。
- 进行单元测试和集成测试。
- 调试和修复问题。
性能优化:
- 优化页面加载速度和性能。
- 压缩和缩小文件。
- 使用懒加载和CDN。
安全性考虑:
- 防止常见的安全漏洞,如跨站脚本攻击(XSS)。
- 使用HTTPS和其他安全措施。
文档和注释:
- 编写清晰的代码注释和项目文档。
- 记录项目结构、功能和用法。
版本控制:
- 使用版本控制系统(如Git)来跟踪代码更改。
- 创建分支和合并更改。
部署:
- 选择合适的托管平台(如GitHub、Netlify、Vercel等)。
- 部署项目到生产环境。
- 配置域名和DNS。
运维和维护:
- 监控网站性能和安全性。
- 定期更新依赖项和解决问题。
- 添加新功能和进行持续改进。
用户反馈和测试:
- 收集用户反馈,并根据需求进行更新。
- 迭代开发,持续改进项目。
学习和成长:
- 持续学习新的前端技术和最佳实践。
- 参与社区和讨论,获取反馈和建议。
该项目是一个商城项目,
1、短信验证码登录|注册
2、Vuex
- 地址管理
- 订单管理
- 购物车数据管理
3、Router
4、导航守卫(拦截)
5、支付
技术选型上为什么采用Vue?
1、vue合适
2、领导熟悉
- git clone :(作用是从一个**远程仓库**下载一个**副本**到本地,包括所有的文件、分支和提交。使用git clone [url]来指定你想要克隆的仓库的地址)
- git branch -r:(git branch -r是一个Git命令,它的作用是列出所有的**远程分支**¹,远程分支是指你从远程仓库克隆或者拉取的分支,它们跟踪远程仓库的状态。如果你想查看**本地分支**,你可以使用git branch命令,如果你想查看**本地和远程分支**,你可以使用git branch -a命令)
创建develop分支步骤:
创建功能分支步骤:
- git branch feature/home:创建新分支
- git checkout feature/home:切换到新分支
- git push --set-upstream origin feature/home:将本地分支提交到远程仓库
vue create <项目名称>
用vue-cli创建项目的一些选择:
进入到桌面文件夹,运行vue created vue-node.js(需要和克隆下的文件名一样,创建好才会放到它里边)图中 上下键移动到位置,按空格键即可选中 项目初始化下载中 此时文件是这样的
表示启动成功
- 全局:cnpm install express-generator -g(用于在全局安装express-generator,它是一个用于快速创建Express应用骨架的工具)【之前安装过的可直接进行下一步】
- 局部:进入到vue-node.js文件夹——>express --view=ejs <项目名称>(用于使用ejs模板引擎来生成一个Express应用的骨架。ejs是一种嵌入式JavaScript模板,可以让你在HTML中使用JavaScript代码)
- cd server
- npm install
- npm run start
- http://localhost:3000/可以访问
在前端项目创建成功的终端下:(将本地分支推送到远程develop分支下)
只有develop分支下显示初始化项目
- 进入vue-node.js目录:cd vue-node.js
- 查看当前分支:git branch
- 进入到develop分支:git checkout develop
- 跟踪所有新文件:git add .
- 提交更新:git commit -m '内容描述'
- 将本地分支推送到远程仓库:git push
以上可能是需要老板来完成的,然后需要员工把以下初始化项目全部克隆下来进行开发即可
git clone https://gitee.com/xuexiluxian/vue-tea.git(不能用这个,这个是在主分支下克隆代码)
如何解决这个问题?
首先在dev分支下看日志:git log
git config user.name '大炮'
git config user.email '[email protected]'
- dev分支下看一下日志:git log(在develop执行的命令)
记录hash:5711918637cb18c459e0ad8105198ca20ee4bdee
- 远程分支拉到本地仓库
git checkout --track origin/feature/home
然后就可以在该分支开发代码了
- 将dev分支commit对应的hash值提交的代码合并在home分支上: git cherry-pick hash码(5711918637cb18c459e0ad8105198ca20ee4bdee )
下一节就开始写项目了,项目链接:http://m.tea7.com/index.htm
SPA就是单页面应用程序,指一个Web网站,只有唯一的一个html页面,所有组件的展示与切换都在这唯一的一个页面内完成此时,不同组件之间的切换需要通过前端路由(Hash 地址(类似锚点链接) 与 组件之间的对应关系 )来实现。
SPA的优缺点
SPA( single-page application )仅在 Web 页面初始化时加载相应的 HTML、JavaScript 和 CSS。一旦页面加载完成,SPA 不会因为用户的操作而进行页面的重新加载或跳转;取而代之的是利用路由机制实现 HTML 内容的变换,UI 与用户的交互,避免页面的重新加载。
优点:
用户体验好、快,内容的改变不需要重新加载整个页面,避免了不必要的跳转和重复渲染;
基于上面一点,SPA 相对对服务器压力小;
前后端职责分离,架构清晰,前端进行交互逻辑,后端负责数据处理;
缺点:
初次加载耗时多:为实现单页 Web 应用功能及显示效果,需要在加载页面的时候将 JavaScript、CSS 统一加载,部分页面按需加载;
前进后退路由管理:由于单页应用在一个页面中显示所有的内容,所以不能使用浏览器的前进后退功能,所有的页面切换需要自己建立堆栈管理;
SEO 难度较大:由于所有的内容都在一个页面中动态替换显示,所以在 SEO 上其有着天然的弱势。
单页项目的路由怎么实现
通过hash地址(#后边的那部分)来实现
手动实现前端路由:通过onhashchange函数监听哈希地址的变化,使用动态组件渲染把当前hash地址对应的组件渲染到页面上。(location.hash可以获取到当前hash地址)
vue-router
在实际应用中不需要我们自己创建路由,在Vue项目中,vue-router(vue.js 官方给出的 路由解决方案 。它只能结合 vue 项目进行使用,能够轻松的管理 SPA 项目中组件的切换)可以帮助我们快速创建路由,只需要告诉其对应关系即可。以商城项目为例来分析vue-router的使用:(可参考vue2.0——第七天(前端路由的概念与原理、vue-router 的基本使用、vue-router 的常见用法、后台管理案例)_大炮不想学习的博客-CSDN博客)
1、 安装 vue-router 包
npm i [email protected] -S
3、导入并挂载路由模块
4、声明路由链接和占位符(声明式导航)
但是项目中用的是编程式导航(调用API方法实现导航的方法)
5、声明路由的匹配规则
该商城项目:
SPA⾸屏加载速度慢的怎么解决?
⾸屏时间(First Contentful Paint),指的是浏览器从响应⽤户输⼊⽹址地址,到⾸屏内容渲染完成的 时间,此时整个⽹⻚不⼀定要全部渲染完成,但需要展示当前视窗需要的内容 ⾸屏加载可以说是⽤户体验中最重要的环节
路由重定向
px、em、rem
路由懒加载
router——index.js
Tabbar组件中:动态渲染的实现原理
vue项目实现的过程:
安装包文件要实现的界面:
底部导航栏:Tabbar是一个公共的组件,有的页面有,有的没有,需要的引入该组件即可。
Tabbar公共组件,哪里使用直接导入、注册、使用即可SPA体现在:4个页面的切换,所以需要新建四个组件,需要用到前端路由
创建一个路由模块并向外导出 导入并挂载路由模块 声明路由的匹配规则 ,除了首页其他都是懒加载
进行一些删除操作:
布局实现:(HTML+CSS+JS)ul里边4个li分别包含一个img和span(首页、分类、购物车、我的)——>借助js进行动态渲染
- 字体图标:iconfont
- ly-tab:topbar切换插件
- 页面和页面中的组件
要实现的界面:(在component中新建一个home文件夹来存放HOME页面中的组件)
views ===》 页面
字体图标:iconfont
使用(icon-fangdajing在浏览器中的名字)
ly-tab:一个用于移动端的可触摸滑动具有回弹效果的可复用Vue组件
使用:GitHub - ScoutYin/ly-tab: A mobile touch-swappable tabs component for Vue.js 2.x
标题
插件实现Swiper插件的使用
要实现的界面:点击不同的topbar,可以切换到不同的页面,不同页面的数据是通过后端接口请求过来的
怎么判断展示的??
把首页页面从上到下布局实现(topbar、swiper.......Tabbar),把首页中推荐、红茶、大红袍...不同之间的布局实现,针对每个盒子进行v-if判断
下载:
npm install [email protected] -S
这是一个Vue.js的插件,名为"vue-awesome-swiper",用于在Vue.js应用程序中集成swiper组件来实现轮播图效果。其中"swiper"和"swiperSlide"是组件的两个子组件,分别用于设置swiper的整体样式和单个轮播项的样式。
使用:
要实现的界面
新建一个组件在Hom中使用(后续的数据需要通过接口获取)
- 逻辑实现
- 插槽使用:通常用于构建可重用和灵活的组件。插槽允许你将组件的内容动态插入到组件内部的特定位置,从而增加了组件的灵活性和可配置性。
要实现的界面
better-scroll 使用:
GitHub - ustbhuangyi/better-scroll: :scroll: inspired by iscroll, and it supports more features and has a better scroll perfermance:scroll: inspired by iscroll, and it supports more features and has a better scroll perfermance - GitHub - ustbhuangyi/better-scroll: :scroll: inspired by iscroll, and it supports more features and has a better scroll perfermancehttps://github.com/ustbhuangyi/better-scroll
这个插件是在页面加载的时候执行的,所以有DOM才可以执行,created生命周期函数中有数据但是没节点,created生命周期函数中vm.el 已完成 DOM 的挂载与渲染
绿色部分为 wrapper,也就是父容器,它会有固定的高度。黄色部分为 content,它是父容器的第一个子元素,它的高度会随着内容的大小而撑高。那么,当 content 的高度不超过父容器的高度,是不能滚动的,而它一旦超过了父容器的高度,我们就可以滚动内容区了,这就是 better-scroll 的滚动原理。
下载——>引入——>使用(注意:要分清什么时候有节点,什么时候better-scroll 必须添加在mounted中,子元素高度比父元素高度要高)
- 插槽的使用:直接把之前的Card导入使用即可
- 静态页面的布局
- 在Home中导入Like组件即可
- v-if
需要让服务器也跑起来,然后才不会报错!!!
点击不同的Topbar切换到对用的页面
点击之后可以得到对应的index,就可以判断当前点击项,后续可以通过接口获取数据然后进行渲染
后端启动
跨域
axios
async/await
Promise
前后端交互
props:父组件给子组件传值(扩展:组件之间通信)
Vue面试题:父组件传值到子组件_哔哩哔哩_bilibili
⼦组件设置 props 属性,接收⽗组件通过自定义属性传递过来的参数扩展:
$emit:子组件传值给父组件
Vue面试题:子组件传值到父组件_哔哩哔哩_bilibili
⼦组件通过 $emit触发 ⾃定义事件, $emit 第⼆个参数为传递的数值,⽗组件绑定事件获取到⼦组件传递过来的参数兄弟组件之间通信
Vue面试题:兄弟组件之间的传值_哔哩哔哩_bilibili
创建⼀个中间事件Bus,兄弟组件通过 $emit 触发⾃定义事件, $emit 第⼆个参数为传递的数值,另⼀个兄弟组件通过 $on 监听⾃定义事件
启动后端
证明后端没问题
端口不一样出现跨域问题
解决:Webpack配置中包含了一个代理服务器的设置,它将以
/api
为前缀的请求代理到http://localhost:3000
。根据你的配置,代理服务器将会把/api/index_list/0/data/1
请求代理到http://localhost:3000/api/index_list/0/data/1
。
安装axios
引入:import axios from 'axios'——>在Home中发起请求(created)——>在后端写接口
是可以拿到code的 在后端写接口
Topbar数据渲染
内容部分的渲染
之前的swiper是写死的
{{item.data}}拿到swiper数据,通过props传递
nextTick:获取更新后的DOM内容
为什么要用nextTick?
原因:仅仅进行了视图的更新,DOM是没有走的,只是改了它里边的数据,所以获取的还是原来的123,无法获取更新后的结果 使用nextTick可以解决这个问题
nextTick使用场景
一些跟DOM相关的插件,比如滑动的插件,我们的数据可能来自接口,我们需要把接口数据放到页面上,但是插件无法准确获取高度,就会出现以下的空白现象,就可以把插件放到nextTick中,等DOM更新后再执行。
ref/$refs:
在div没有渲染的时候,不知道其有多高,所以应该先把数据渲染到页面上再去加载滚动插件进行滚动,应该先放DOM再执行better-scroll,所以以下顺序需要改变
js是单线程的,
16、搜索页面布局
axios二次封装
mint-ui组件
加载页面的时候显示一个加载中 ,用到以下mint-ui组件
mint-ui documentation
问题:首页、购物车页、分类页...发请求,每个页面都要写,代码比较冗余,可以只写一次吗?——>针对axios进行二次封装
实际开发中,axios一定要进行二次封装的,后期验证用户是否是登录状态,需要把当前用户信息传到后端,每次传特别长的串是不好的,我只要穿个True/false就方便很对,可以通过二次封装来做。
代码实现
console.log(v); console.log(res);直接是返回的数据
src-common-request.js
import { Indicator } from 'mint-ui'; import axios from 'axios' export default { common: { method: 'GET', data: {}, params: {} }, // $axios是一个函数,options是形参,实参由Home那边传递过来 $axios(options = {}) { // this.common.method默认的是GET, options.method是传递过来的 // 如果不传就执行默认的 options.method = options.method || this.common.method; options.data = options.data || this.common.data; options.params = options.params || this.common.params; //请求前==》显示加载中... Indicator.open('加载中...'); return axios(options).then(v => { // console.log(v); // 直接封装了,拿到数据,后边会简单很多 let data = v.data.data; return new Promise((res, rej) => { if (!v) return rej(); //结束===》关闭加载中(有个交互,所以加了个定时器) setTimeout(() => { Indicator.close(); }, 500) res(data); }) }) } }
Home.vue
methods:{ async getData(){ // $axios是一个函数 let res = await http.$axios({ url:'/api/index_list/0/data/1', }) console.log(res); this.items = Object.freeze(res.topBar); this.newData = Object.freeze(res.data); //当dom都加载完毕了再去执行 this.$nextTick(()=>{ this.oBetterScroll = new BetterScroll(this.$refs.wrapper, { movable: true, zoom: true }) }) },
22、渲染搜索结果的数据
23、搜索商品的价格和销量排序
24、懒加载
25、分类页布局
26、分类页数据渲染
27、实现商品分类左右联动
28、进入商品详情页
29、详情页吸顶动画
30、渲染数据和keep-alive
涉及面试知识点
keep-alive:
生命周期:
31、登录布局
39、购物车页面布局
token
cookie、SessionStorage、LocalStorage
进入到商品详情页——>点击加入购物车(前端发送一个请求给后端,后端把数据加入到数据库)。然后就会出现问题:要不要告诉后端哪个用户发送的请求(前端要知道是哪一个用户,然后把这个用户传给后端)?——>就要用到token!!!
token是一个令牌,就是来验证用户信息的
token使用流程:
- 客户端使用用户名跟密码请求登录
- 服务端收到请求,去验证用户名与密码
- 验证成功后,服务端会签发一个 Token,再把这个 Token 发送给客户端
- 客户端收到 Token 以后可以把它存储起来,比如放在 Cookie 里或者 Local Storage 里
- 客户端每次向服务端请求资源的时候需要带着服务端签发的 Token
- 服务端收到请求,然后去验证客户端请求里面带着的 Token,如果验证成功,就向客户端返回请求的数据
token是后端生成的, 并且token是不能重复的
1. 下载
npm install jsonwebtoken
2. 引入
require('jsonwebtoken');
3. 生成token语法
jwt.sign( 用户信息 , 口令 , 过期时间)
4. 解析token
jwt.decode(token);
路由导航守卫:
如果是登录状态,可以进入到地址管理,如果是未登录状态,点击地址管理会报错并跳转到登录界面(是因为我们在request.js中封装了)执行力axios。我们要做的就是不能让它登录页,所以就要做导航守卫拦截了!!!
导航守卫分类:
- 全局的
- 路由独享的
- 组件内的