supermall项目开发练习

一,项目搭建

(一)项目创建

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的安装和使用

vue项目中使用swiper也可以实现轮播

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. 响应式原理-对应的代码阅读

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值