一,项目搭建
(一)项目创建
vue3
vue create supermall1
(二) github托管
1. 方式一:克隆
在github上创建supermall项目
将supermall项目克隆下来
git clone https://github.com/fullmoon37/supermall.git
报错:
输入命令:需要用https才能读到数据
git config --global url."https://github.com".insteadOf git://github.com
如果再次git clone出现报错:
git config --global --unset http.proxy
git config --global --unset https.proxy
将supermall1中的文件复制到supermall
来到supermall目录下,查看git status状态
运行,将所有文件加进去
git add .
初始化项目,提交到本地仓库
git commit -m '初始化项目'
提交到服务器远程仓库
git push
刷新github
执行npm install将node_modules 安装到supermall中
2. 方式二:远程push到Git仓库
(1)使用“git remote add origin”指令,可以轻松地将本地项目连接到远程Git仓库
git remote add origin 仓库地址
//push到远程仓库
git push -u origin main
执行这条指令之后,你的本地项目就与远程Git仓库建立了连接,你就可以开始对你的代码进行版本追踪和协作开发了。
执行git push -u origin main时,报错
解决方法:
先删除远程 Git 仓库
git remote rm origin
再添加远程 Git 仓库
git remote add origin https://github.com/fullmoon37/testmall.git
(2)git remote add origin的一些常用操作
更改默认的远程仓库
git remote set-url origin <新的远程Git仓库地址>
看当前的远程仓库
git remote -v
删除远程仓库
git remote rm origin
执行这条指令之后,Git就会将已经添加的名为“origin”的仓库删除
或在命令行上创建新的存储库:
echo "# testmall" >> README.md
git init
git add README.md
git commit -m "first commit"
git branch -M main
git remote add origin https://github.com/fullmoon37/testmall.git
git push -u origin main
或者从命令行推送现有存储库:
git remote add origin https://github.com/fullmoon37/testmall.git
git branch -M main
git push -u origin main
二,项目开发
(一)划分目录结构(vue项目)
(二)项目初始化
1. CSS文件的引入
(1)在github上找,下载引入第三方文件,对浏览器样式进行统一规范
使用npm安装
npm install --save normalize.css
main.js引入
import 'normalize.css';
(2)base.css
公共基础样式
2. 配置路径别名和代码风格规范
(1)在vue.config,js中配置(cli4中不需要手动配置别名)
const { defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({
transpileDependencies: true
configureWebpack: {
resolve: {
alias: {
'assets': '@/assets',
'common': '@/common',
'components': '@/components',
'network': '@/network',
'views': '@/views',
}
}
}
}
})
(2).editorconfig
对代码进行统一风格,缩进,缩进大小,文件结束是否插入空格
root = true
[*]
charset = utf-8
indent_style = space
indent_size = 2
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
3. 项目模块的划分 :tabbar引入和路由映射关系
4. 小图标修改以及路径问题
在index.html中
<link rel="icon" href="favicon.ico" type="image/x-icon">
(三)首页开发
1. 首页导航栏的封装和使用
(1)首页导航栏NavBar.vue
<template>
<div class="nav-bar">
<div class="left"><slot name="left"></slot></div>
<div class="center"><slot name="center"></slot></div>
<div class="right"><slot name="right"></slot></div>
</div>
</template>
<script>
export default {
name:"NavBar"
}
</script>
<style scoped>
.nav-bar {
display: flex;
line-height: 44px;
height: 44px;
text-align: center;
box-shadow: 0 1px 1px rgba(100, 100, 100, 0.1);
}
.left,
.right {
width:60px;
}
.center {
flex: 1;
}
</style>
(2)首页home.vue
<template>
<div id="home">
<nav-bar class="home-nav"><template v-slot:center><div>购物街</div></template></nav-bar>
</div>
</template>
<script>
import NavBar from 'components/common/navbar/NavBar.vue'
export default {
name :"Home",
components: {
NavBar
}
}
</script>
<style>
.home-nav {
background-color: var(--color-tint);
color: aliceblue;
}
</style>
2. 请求首页的多个数据
(1)网络模块封装
安装axios库,npm install axios --save,导入网络封装模块
import config from '@babel/core/lib/config'
import axios from 'axios'
export function request(config) {
// 创建axios的实例
const instance = axios.create({
baseURL:'http://123.207.32.32:8000',
timeout:5000
})
// 请求拦截
instance.interceptors.request.use(config => {
return config
}),err => {
}
// 响应拦截
instance.interceptors.response.use(res => {
return res.data
}),err => {
}
// 发送真正的网络请求
return instance(config)
}
(2)首页请求封装
import {request} from 'network/request.js'
// default导出不用{}
export function getHomeMulitidata() {
return request({
url:'/home/multidata',
method:'get'
})
}
(3)home.vue
<script>
import NavBar from 'components/common/navbar/NavBar.vue'
import {getHomeMulitidata} from 'network/home.js'
export default {
name :"Home",
components: {
NavBar
},
data() {
return {
banners: [],
recommends: []
}
},
created() {
// 生命周期函数,主页创建完成后发送请求
// 1. 请求多个数据
getHomeMulitidata().then(res => {
console.log(res);
// this.result = res;
this.banners = res.data.banner.list;
this.recommends = res.data.recommend.list;
})
}
}
</script>
3. 轮播图的展示
4. 推荐信息的展示
5. FeatureView的封装
6. TabControl的封装
7.保存商品的数据结构
数据模型
8. 首页数据的请求和保存
将nums1的数据保存到totalNums中
let totalNums = []
const nums1 = [20, 11, 222] //第一页数据
const nums2 = [111, 22, 333] //第二页数据
// for循环方式
// for(let n of nums1) {
// totalNums.push(n)
// }
totalNums.push(...nums1)
// ...解构,相当于将nums1,nums2数组中的元素依次解析出来(利用push函数)
9. 首页商品数据的展示
10. TabControl点击切换
11.BScroll的封装以及使用
12.BackTop组件的封装
13. BackTop的显示和隐藏
14. 完成上拉加载更多
15. 滚动区域的Bug分析
15.1 Better-Scrol在决定有多少区域可以滚动时,是根据scrollerHeight属性决定
scrollerHeight属性是根据放Better-Scroll的content中的子组件的高度
但是我们的首页中,刚开始在计算scrollerHeight属性时,是没有将图片计算在内的
所以,计算出来的告诉是错误的(1300+)
后来图片加载进来之后有了新的高度,但是scrollerHeight属性并没有进行更新
所以滚动出现了问题
15.2 如何解决这个问题了?
新版Betterscroll直接用observeDom:true observeImage: true就行了,看开发文档
监听每一张图片是否加载完成,只要有一张图片加载完成了,执行一次refresh()
如何监听图片加载完成了?
原生的js监听图片:img.οnlοad=function()
Vue中监听: @load='方法”
调用scroll的refresh()
15.3 如何将GoodsLisritem.vue中的事件传入到Home.vue中
因为涉及到非父子组件的通信,所以这里我们选择了事件总线
bus ->总线
Vue.prototype.sbus = new Vue()
this.bus.emit(事件名称',参数)
this.bus.on('事件名称,回调函数(参数))
(四) Better-Scroll的安装和使用
better-scoll框架,为了适配移动端滚动更加顺滑
1. better-scroll是什么
betterscroll是一款重点解决移动端(已支持 PC)各种滚动场景需求的插件。它的核心是借鉴的 iscroll 的实现,它的API设计基本兼容 iscroll,在 iscroll 的基础上又扩展了一些 feature 以及做了一些性能优化。
better.scroll是基于原生 JS 实现的,不依赖任何框架。它编译后的代码大小是 63kb,压缩后是 35kb,gzip 后仅有9kb,是一款非常轻量的 JS lib。
2. 起步
学习使用 better-scro 最好的方式是看它的 demo 代码,我们把代码都放在了 example 目录,由于目前最适合移动端开发的前端 mwvm 框架是 Vue,并且 better-·scrol| 可以很好的和 Vue 配合使用的,所以 demo 都用 vue 进行了重写。
better-scroll 最常见的应用场景是列表滚动,我们来看一下它的 html 结构
3. 安装和使用
npm install @better-scroll/core --save
npm install better-scroll@1.13.2
<template>
<h2>分类</h2>
<div class="wrapper">
<ul class="content">
<li>分类列表</li>
</ul>
</div>
</template>
<script>
import BScroll from 'better-scroll'
// import BScroll from '@better-scroll/core'
export default {
name:'Category',
data() {
return {
scroll: null
}
},
created() {
// new BScroll(('.content'),{
// 报错,DOM元素还没有被挂载,所以没有被better-scorll对象识别
// })
},
mounted() {
this.scroll = new BScroll(('.wrapper '),{
})
}
}
</script>
<style scoped>
.wrapper {
height: 150px;
background-color: red;
overflow: hidden;
}
</style>
注意:
new BScroll要么放mounted里面 ,要么在created里面用nexttick 包裹。因为在created里面初始化,这个时候还没有dom呢,当然获取不到了;
create生命周期是在组件创建完成后调用;
created创建完组件了,也已经渲染了,就是还没有进行挂载,所有获取不到dom;
最先能够拿到data和methods的是在created这个生命周期,最先能够操作真实dom的是在mounted这个生命周期。
4. 基本使用解析
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style>
.content {
height: 200px;
background-color: red;
/* overflow: scroll; */
overflow: hidden;
}
</style>
</head>
<body>
<div class="wrapper">
<!-- ul>li{列表数据$}*100 + Tab键 -->
<ul class="content">
<button class="btn">按钮</button>
<!-- ul>li{列表数据$}*100 + Tab键 -->
</ul>
</div>
<script src="./bscroll.js"></script>
<script>
// 默认情况下BScroll不能实时监听滚动位置
// probe 侦测
// 0,1都是不侦测实时的位置
// 2:在手指滚动过程中侦测,手指离开后的惯性滚动中不侦测
// 3:只要是滚动,都侦测
// console.log(BScroll);
const bscroll = new BScroll(document.querySelector('.wrapper'),{
probeType:2,
click:true,
pullUpLoad:true
})
bscroll.on('scroll',(position) => {
console.log(position)
})
bscroll.on('pullingup', () => {
console.log('上拉加载更多')
// 发送网络请求,请求更多页数据
// 等待数据请求完成,并且将新的数据展示出来后bscroll.finishPillUp()
setTimeout(() => {
bscroll.finishPillUp()
},2000)
})
</script>
</body>
</html>
probeType作用:决定是否派发 scroll 事件,
probeType 为 0,在任何时候都不派发 scroll 事件,
probeType 为 1,仅仅当手指按在滚动区域上,每隔 momentumLimitTime 毫秒派发一次 scroll 事件,
probeType 为 2,仅仅当手指按在滚动区域上,一直派发 scroll 事件,probeType 为 3,任何时候都派发 scroll 事件,包括调用 scrollTo 或者触发 momentum 滚动动画
5. BScroll在vue中的使用
BScroll的封装,对BScroll进行重构
可以直接拿第三方封装的组件使用
ref如果是绑定在组件中的,那么通过this.$refs.refname获取到的是一个组件对象;
ref如果是绑定在普通的元素中,那么通过this.$refs.refname获取到的是一个元素对象
(五)详情页
1. refresh函数找不到的bug处理
问题一: refresh找不到的问题
第一: 在Scroll.vue中,调用this.scroll的方法之前,判断this.scroll对象是否有值
第二:在mounted生命周期函数中使用 this.$refs.scroll而不是created中
2. 刷新频繁的防抖函数处理
防抖是多次触发取最后,节流是多次触发取最前然后忽视后面的触发
需求: 对于refresh非常频繁的问题,进行防抖操作
防抖debounce/节流throttle(课下研究一下)
防抖函数起作用的过程:
如果我们直接执行refresh,那么refresh函数会被执行30次
可以将refresh函数传入到debounce函数中,生成一个新的函数
之后在调用非常领繁的时候,就使用新生成的函数.
而新生成的函数,并不会非常频繁的调用,如果下一次执行来的非常快,那么会将上一次取消掉
debounce(func,delay){
let timer . null
return function(...args){
if(timer)clearTimeout(timer)
timer = setTimeout(()=>{
func.apply(this, args)
},delay}
}
},
3. 上拉加载更多的完成
4. tabControl的offsetTop获取分析
吸顶效果实现:
4.1 在哪里才能获取到正确的 offfsetTop?
1.created 肯定不行,压根通过 this.$refs 获取不到元素
2.mounted 也不行,数据还没有获取到
3.updated 也不行,获取到了数据 Dom 还没有渲染
4.$nextTick 也不行,因为 dom 渲染了但是图片还没有加载完毕
5.在图片都加载完毕后获取元素的 offsetTop, 这里注意防抖函数的应用
4.2 获取到tabcontrol的offsetTop
必须知道滚动到多少时,开始有吸顶效果,这个时候就需要获取tabControl的offsetTop。但是,如果直接在mounted中获取tabControl的offsetTop,那么值是不正确.
如何获取正确的值了?
监听HomeSwiper中img的加载完成.
加载完成后,发出事件,在Home.vue中,获取正确的值
补充:
”为了不让HomeSwiper多次发出事件,
可以使用isLoad的变量进行状态的记录
注意:这里不进行多次调用和debounce的区别
5. TabControl的吸顶效果完成
5.1 监听滚动,动态的改变tabcontrol的样式
问题:动态的改变tabControl的样式时,会出现两个问题:
问题一:下面的商品内容,会突然上移
问题二: tabControl虽然设置了fixed,但是也随着Better-Scroll一起滚出去了。其他方案来解决停留问题.
在最上面,多复制了一份PlaceHolderTabControl组件对象,利用它来实现停留效果,。
当用户滚动到一定位置时,PlaceHolderTablcontrol显示出来
当用户滚动没有达到一定位置时,PlaceHolderTabControl隐藏起来.
6. Home离开时记录状态和位置
6.1 让Home不要随意被销毁
keep-alive:Vue内置的一个组件,可以使被包含的组件保留状态,或避免重新渲染。
router-view:vue-router内置组件, 如果直接包含在keep-alive里面,所有路径匹配到的组件都会被缓存。
app.vue使用keep-alive组件,vue3中最新写法,keep-alive嵌套要放在router-view里面,这样就导致清除缓存存在问题,通过v-if控制时,路由会先刷新再跳转,这样就导致跳转加载闪屏,用户体验不好
6.2 Home中内容保持原来位置
离开时,保存一个位置信息saveY.
进来时,将位置设置为原来保存的位置saveY信息即可
注意: 最好回来时,进行一次refresh()
7. 跳转到详情页并且携带id
7.1 监听goods-item点击,增加一个详情页视图,详情页配置对应路由
8. 详情页-导航栏的封装
import DetailNarBar from './childComponents/DetailNarBar.vue'
9. 数据请求以及轮播图展示
9.1 数据请求
import {request} from './request.js'
export function getDetail(iid) {
return request({
url: '/detail',
params: {
iid
}
})
}
import {getDetail} from 'network/detail.js'
created() {
// 1. 保存传入的id
this.id = this.$route.params.id
// console.log(this.id)
// 2. 根据id请求详细数据
getDetail(this.id).then(res => {
console.log(res)
})
}
9.2 轮播图展示
抽离接口中想要的数据
itemInfo - topImages 图片信息
<keep-alive>
包裹动态组件时,会缓存不活动的组件实例,而不是销毁它们。和 <transition>
相似,<keep-alive>
是一个抽象组件:它自身不会渲染一个 DOM 元素,也不会出现在组件的父组件链中。
主要用于保留组件状态或避免重新渲染。
使用了 include / exclude 后,必须显式声明组件的 name !!!这样才能与缓存组件匹配、生效。
10. 店铺信息的解析和展示
sellCountFilter在methods中定义,否则会报错:
Property "xxx" was accessed during render but is not defined on instance.
意思是 ➡ 属性“xxx”在渲染期间被访问,但未在实例上定义。
说大白话就是,在你所写的组件文件中,你的“xxx”属性在html文中有被Vue文档编译器解析发现,而在setup进行实例创建时没有发现这个属性,Vue官方报错告诉你可能是没有定义的原因。
11. 商品基本信息的展示
11.1 对数据整合
把杂乱的数据封装到一个对象中
11.2 如何判断是否为空对象
const obj = {
// 如何判断是否为空对象
}
Object.keys(obj).length ===0
// 说明没有key,空值对象
11.3 让元素上浮一些: 使用相对定位即可
position: relative;
top: -8px;
12. 加入滚动的效果Scroll
12.1 如何让mainTabBar不再详情页显示
使用路由meta控制
12.2 解决首页中可滚动区域的问题
13. 商品详情数据展示
14. 商品参数信息的展示
15. 从首页跳转详情页-iid
GoodsListltem点击
点击之后获取商品的1D,跳转到详情页,并里传入!ID
16. 首页位置的保持
deactivated:记录离开时的位置
activated:通过scro11To图数,设置离开时位置
bug: Better-Scroll最新的1.15.0有scrollTo的位置。 解决方案: 进行版本的回退: 1.13.2
17. 详情页导航栏的实现
返回按钮:left
标题列表的展示:center
18. Better-Scroll的scrollto函数的Bug
19. 根据iid详情页数据的请求
接口:/detail?id=
20. 顶部轮播图的展示
Swiper/Swiperltem
21. 商品的基本信息展示
数据来自四面八方,
对数据进行汇总:一个对象当中
一个对象传入到子组件中
22. 滚动问题处理和TabBar...
23. 详情页店铺信息展示
24. 详情页商品图片信息展示
25. 商品参数信息的展示
26. 商品评论信息的展示
时间格式化->时间戳
27. 商品推荐数据的展示
28. 首页和详情页监听全局..
29. 点击标题滚到对应内容
在detail中监听标题的点击,获取index
滚动到对应的主题:
获取所有主题的offsetTopo
问题: 在哪里才能获取到正确的offsetTop
1.created肯定不行,压根不能获取元案
2.mounted也不行,数据还没有获取到
3.获取到数据的回调中也不行,DOM还没有渲染完
4.$nextTick也不行,因为图片的高度没有被计算在类
5.在图片加载完成后,获取的高度才是正确
$nextTick回调函数
根据最新的数据,对应的DOM已经是被渲染出来
但是图片依然没有加载完(目前获取的offsetTop不包含其中的图片)
或放到titleClick中
30. 滚动内容显示对应标题
在detail中监听标题的点击,获取index
滚动到对应的主题:
获取所有主题的offsetTop
问题: 在哪里才能获取到正确的offsetTop
1.created肯定不行,压根不能获职元案
2.mounted也不行,数据还没有获取到
3.获取到数据的回调中也不行,DOM还没有渲染完
4.$nextTick也不行,因为图片的高度没有被计算在类
5.在图片加载完成后,获职的高度才是正确
for in循环不适合用来遍历数组,for in 本来就是针对对象循环的 for of循环数组
for in 主要用于对象属性的遍历,这里我们可以采用ES6的for of 的方式进行对值的遍历
contentScroll(position) {
// 1.获取y值position
const positionY = -position.y
// 2.positionY和主题中的值进行对比
let length = this.themeTopYs.length
for(let i = 0; i < length ; i++) {
if(this.currentIndex !== i && ((i < length -1 && positionY >= this.themeTopYs[i] && positionY < this.themeTopYs[i+1]) || (i === length -1 && positionY >= this.themeTopYs[i])))
{
// console.log(i);
this.currentIndex = i;
console.log(this.currentIndex);
this.$refs.nav.currentIndex = this.currentIndex;
}
}
}
31. 对复杂判断条件分析和优化
this.themeTopYs.push(Number.MIN_VALUE);
用空间换时间(执行性能/写代码时间)
32. 底部工具栏的封装
DetailBottomBar
BackTop导入detail
33. 将商品添加到购物车中
安装Vuex
配置Vuex
定义mutations,将商品添加到state.cartList
重构代码:
将mutatio内s中的代码抽职actions中(定义两个mutations)。将mutations/actions单独抽职到文件中
安装VUEX
npm install vuex --save
挂载到Vue实例中
find 断言函数,一成立直接退出
addCart(state,payload) {
// payLoad一个形参的名称罢,用来接收commit里传过来的参数
// payload新添加的商品
// 1.查找之前数组中是否有该商品
let oldProduct = state.cartList.find(item=> item.id === payload.id)
// 2.判断oldProduct是否有值
if(oldProduct) {
oldProduct.count += 1
}else {
payload.count = 1
state.cartList.push(payload)
}
}
(六)购物车
1. 导航栏实现-Vuex知识点
mapGetters辅 助函数
mapGetters辅助函数仅仅是将 store 中的 getter 映射到局部计算属性:
2. 购物车商品列表展示
出现不能滚动问题:
这里的问题是没有refresh,购物车加载完,没有内容可滚动距离为0,加了内容后可滚动距离还是0,可以先加购物车,在点击购物车就可以实现滚动;手动刷新高度就好refresh
this.$refs.scroll.scroll.refresh
3. 购物车列表的ltem展示
4. ltem选中和不选中的切换
在对象模型中记录
监听CheckButton点击
5. 顶部工具的封装和应用
6. 全选按钮的状态显示
显示的状态 判断是否有一个不选中,全选就是不选中
6.1 点击全选按钮
6.2 map,filter,some,every都是原数组不受改变,而foreach是在原数组上改变
map:返回新数组,在原数组上进行数据处理,只会在原有数组上元素内容改变,数组长度不变
filter: 返回新数组,在原数组上判断是否满足条件来进行数据过滤,只会在原有数组上长度改变,元素内容不变
some: 返回布尔值(一真则真),在原数组上判断是否满足条件,只要里面元素有一个满足条件则返回true,并且停止遍历
every:返回布尔值(一假则假),在原数组上判断是否满足条件,必须里面元素全部满足条件才会返回true
find: 返回原数组中第一个满足条件的那个元素
6.3 全选按钮的点击效果
点击全选按钮
如果原来都是选中,点击一次,全部不选中
如果原来都是不选中(某些不选中),全部选中
checkClick() {
if(this.isSeletAll) { //全部选择
this.cartList.forEach(item => item.checked = false)
}else { //部分或全部不选中
this.cartList.forEach(item => item.checked = true)
}
}
8. Vuex的补充
Actions可以返回一个Promise
mapActions的映射关系
8.1 vuex-actions返回Promise-mapActions
报错的可以删掉
在actions中调用Promise
逻辑 异步操作在actions 提交操作在mutation,actions 用于 判断 和 异步操作
addCart(context,payload) {
return new Promise((resolve,reject) => {
// 1.查找之前数组中是否有该商品
let oldProduct = context.state.cartList.find(item=> item.id === payload.id)
// 2.判断oldProduct是否有值
if(oldProduct) {
context.commit('addCounter',oldProduct)
resolve('当前商品数量+1')
}else {
payload.count = 1
context.commit('addToCart',payload)
resolve('添加了新的商品')
}
})
}
8.2 辅助函数:mapState, mapGetters, mapActions, mapMutations, createNamespacedHelpers
9. Toast封装-普通方式的封装
<template>
<div class="toast">
<div v-show="show">{{message}}</div>
</div>
</template>
<script>
export default {
name: 'Toast',
props: {
message: {
type: String,
default : ''
},
show: {
type: Boolean,
default: false
}
}
}
</script>
<style scoped>
.toast {
position: fixed;
top: 50%;
left: 50%;
color: #fff;
background-color: rgba(0, 0, 0, .75);
transform: translate(-50%,-50%);
}
</style>
addToCart() {
// 2.将商品添加到购物车
this.$store.dispatch('addCart',product).then(res => {
this.show = true;
this.message = res;
setTimeout(() => {
this.show = false;
this.message = '';
},1500)
})
}
10. Toast封装-插件方式的封装
11. 解决移动端300ms延迟
fastclick插件
npm install fastclick --save
2023年,一般情况不需要安装这个插件了,如果特定的手机,可能需要
2021解决方案 直接禁止浏览器缩放就行 移动端的项目现在一般不需要缩放
可以查询使用vue3-lazy
12. 图片懒加载-vue-lazyload框架
不支持VUE3
vuelazyload,Vue3无法使用作者在vue2的时候停止更新了
13. px2vw-css单位转化插件
一般不用
postcss-pxtorem px转rem
14. nginx-项目在window下的部署
项目打包 npm run build
14.1 将自己的电脑作为服务器->window -> nginx (本机部署)
(1)服务器: 本质上是一台电脑(没有显示器,主机),24小时开着,为用户提供服务
公司有没有自己的服务主机?->租借 阿里云(流媒体)/华为云/腾讯云(配置)
(2)主机 -> 操作系统-> window(.net)/Linux -> tomcat/nginx(软件应用服务器/反向代理)
应用服务器是你的应用得服务器,提供应用服务,如你的J2EE中间件:基于jboss,weblogic等的应用,也可以是自己的网络应用服务器,接口服务器是提供给第三方调用的服务,主要是为了我们自己的应用得安全性,所以我们只把能供给第三方调用的东西封装在接口服务器。
Tomcat应用服务器,Weblogic应用服务器,Apache,Nginx
14.2 部署到Nginx
(1) 安装Nginx
①官网下载,并且解压到某个文件夹.
其中包含很多的nginx版本,大致可以分成三类:
Mainline version :Mainline 是 Nginx 目前主力在做的版本,可以说是开发版
Stable version:最新稳定版,生产环境上建议使用的版本
Legacy versions:遗留的老版本的稳定版
②选择Stable Version的最新版本
③进入下载页面,选择windows的版本
注意: 解压到的文件夹中不能包含中文,否则不能正常启动,
双击启动接口 nginx.exe
在浏览器中输入localhost,看到下面的页面说明安装成功了
(2)将打包的项目dist文件夹放到nginx文件夹html文件夹中,打开index.html
15. nginx-项目在远程linux下的部署
远程主机->linux centos->nginx=>终端命令
(还推荐另外一个软件连接终端软件filezilla/Xshell )
(1)通过终端远程登录自己的服务器
ssh远程登陆
(2)安装并启动 Nginx
yum install nginx
systemctl start nginx.service # 开启 nginx 服务
systemctl enable nginx.service #跟随系统启动
yarn/npm
yum linux安装包管理工具
(3)上传打包项目部署
(七)响应式原理
1. 响应式原理-依赖技术的分析和..
2. 响应式原理-通过图解理解过程
3. 响应式原理-对应的代码阅读