本篇文章学习记录于: bilibili-黑马程序♞ 104-139集 》》🎯目标:冲击前后端全栈🔥,分享一下学过程:
Java.慈祥的博客
——个人前端技术栈blog记录:、感谢黑马官方分享的课程,ありがとうございました 🦀🦀🦀
项目名: 智慧商城项目
——shop-project
接口文档: https://apifox.com/apidoc/shared-12ab6b18-adc2-444c-ad11-0e60f5693f66/doc-2221080
链接不稳定,可能会消失
基于Vue-cli 自定义创建项目:
#npm安装脚手架:
npm i @vue/cli -g #以及安装,请忽略;
#使用: vue-cli 创建项目:
vue create shop-project #选择Vue2版本、依赖配置:es6-es3、路由、less/css、eslint校验格式 感觉没啥用)
#Use history mode for router! ==> 是否使用history模式;
#Pick a CSS pre-processor ==> 选择css预处理;
#Pick a linter/formatter config ==> 选择eslint的风格;
#Pick a additional lint features ==> 选择校验的时机: Lint a save 开启保存即校验;
#Where do you prefer placing config for Babel ESlint etc? 配置文件的生成方式>In dedicated config files
#Save this as a preset for future projects? 是否保存预设,下次直接使用> 不保存,输入 N
🆗,上述使用Vue-cli简单的构建了项目结构,但还单单不满足一个项目的需求,让我们稍稍的修改⚒️:
删除一些不需要的初始化目录、修改没删除的文件、新增需要的目录结构 实际开发按需求而自定义;
新增目录结构: src/api 存储接口模块,定义ajax请求接口的模块)
、src/utils 定义公共工具模块)
因为本人也是刚开始接触前端,早就听说组件库的强大; 让新手也可以轻松的制作出,非常Nice的页面;
后端宝宝,还在酷酷加班写: 数据库Sql、涉及接口、梳理业务、前端宝宝已经在泡咖啡、打王者了🎮;
什么是组件库: 组件库是一套预先设计和实现好的UI组件集合
,这些组件是构建用户界面的基本单元;
在实际开发中: 组件库如:
Vant 是由有赞前端团队开发的,专为移动应用设计的Vue.js组件库:
Vant有很多版本,Vue2、Vue3、小程序,都有兼容:Vue2==>Vant2
、Vue3==>Vant4
使用;
Vant是一个成熟、高效且功能丰富的Vue.js组件库,拥有活跃的社区支持,不断更新的组件和文档;
Vant的官网已经介绍的很完美了,此处简单介绍一下: 首先,通过 npm
、yarn
安装Vant
,官网安装方式也有很多;
#Vue 2项目安装 Vant2
npm i vant@latest-v2 -S
yarn add vant@latest-v2 #省略...脚手架、CDN安装;
安装完之后就可以在项目中导入组件: Vant支持全部导入、按需导入,注意:这并不是Vue组件的全局导入、局部导入;
全部导入: 通常采用全局导入
形式,在main.JS
中定义,这样就可以在项目的任意位置,直接使用;
//mainJS中引入Vant全部组件,注册至全局使用;
import 'vant/lib/index.css';
import Vant from 'vant';
Vue.use(Vant)
按需导入: 虽然没有全部导入方便,但节省资源推荐使用;
首先安装依赖: yarn add babel-plugin-import -D
,在babel.config.js
中配置:
//它会在编译过程中将 import 的写法自动转换为按需引入的方式
module.exports = {
presets: [
'@vue/cli-plugin-babel/preset'
],
plugins: [
['import', {
libraryName: 'vant',
libraryDirectory: 'es',
style: true
}, 'vant']
]
}
最后,为了方便在全局使用,在main.JS
中全局注册需要的组件模块: import { 组件1, 组件2, ... } from 'vant'
//mainJS中按需引入Vant组件,注册至全局使用;
import { Button,Slider } from 'vant';
Vue.use(Button);
Vue.use(Slider);
伴随着项目越来越大,按需导入的组件模块: 越来越多,导致main.JS
不方便维护,
实际情况可以将:导入组件的代码单独抽离出一个新的配置文件中进行管理,utils/vant-ui.JS
import Vue from 'vue'
import { Button, Icon } from 'vant'
Vue.use(Button)
Vue.use(Icon)
main文件中引入:utils/vant-ui.JS
: import '@/utils/vant-ui'
因为:本项目针对移动应用📱,而不同厂商的设备会有大小区别,所以存在不同设备显示效果不同🚫
当然,这个在属于前端领域常见的问题: 也是最开始学习前端,最让我头疼的问题;
于是:诞生了——>PostCSS VW
插件: 实现的CSS单位转换技术,
px
,自动转换为,视口宽度==>单位vw
vw (Viewport Width)
视口单位是一种响应式设计的工具,其中vw
代表视口宽度的百分比:1vw = 视口宽度的1%
安装插件: 首先,需要在项目中安装PostCSS
及其对应的vw
转换插件,GitHub项目地址 🪜🪄
npm install postcss-px-to-viewport --save-dev #npm 安装、或
yarn add postcss-px-to-viewport --dev #yarn 安装
配置PostCSS: 在项目的构建配置文件中:webpack
、vue.config.js
、postcss.config.js
)
项目根目录创建: postcss.config.js
配置文件📄
module.exports = {
plugins: {
//适配的标准屏的宽度 iphoneX:375
'postcss-px-to-viewport': {
viewportWidth: 375,
/** 更多配置
viewportHeight: 1334, // 可选,设计稿高度
unitPrecision: 5, // 转换后的vw单位的小数位数
viewportUnit: 'vw', // 转换的目标单位
selectorBlackList: [], // 不转换选择器列表
minPixelValue: 1, // 小于1px的值不转换
mediaQuery: true, // 是否转换媒体查询中的px
replace: true, // 是否直接替换px单位
exclude: [/node_modules/], // 排除某些文件夹下的文件 */
},
},
};
对于字体大小等,可能需要更细致的控制,避免在极小或极大屏幕上出现阅读困难;
使用vw
时,需要考虑最小设备的兼容性,确保在小屏幕设备上元素不会变得过小而难以阅读或操作;
在某些特定场景下,如需要精确像素对齐时,直接使用vw可能不是最佳选择,需要结合其他单位使用;
路由设计: 但凡是单个页面,独立展示的,都是一级路由,为了方便管理:一级路由,定义为文件夹、index.vue主页面
二级路由: 定义在所属的一级路由目录下;——————创建文件
my-app/
│
├── src/
│ ├── router/ # 定义路由组件配置
│ │ ├── index.js
│ ├── views/ # 定义路由模块页面
│ │ ├── login/ #登录模块
│ │ │ │ ├── index.vue
│ │ └── layout/ #首页模块——内涵多个二级子模块;
│ │ │ │ ├── index.vue
│ │ │ │ ├── 首页.vue
│ │ │ │ ├── 我的.vue
│ │ │ │ ├── 购物车.vue
│ │ │ │ ├── 分类页.vue
│ │ └── pay/ #支付模块
│ │ │ │ ├── index.vue
│ │ └── sarch/ #搜索模块--内有搜索页、搜索列表页一级目录
│ │ │ │ ├── index.vue
│ │ │ │ ├── list.vue
│ │ └── myorder/ #订单模块
│ │ │ │ ├── index.vue
│ │ └── prodetail/ #商品模块——商品详情页,描述固定商品所以需要传递ID
│ │ │ │ ├── index.vue
│ ├── App.vue # 主页面
│ ├── main.js # 主配置文件
配置src/router/index.js
//省略导入路由配置:
const router = new VueRouter({
routes: [
// '/' 表示默认页
{ path: '/', component: Layout },
{ path: '/login', component: Login },
{ path: '/search', component: Search },
{ path: '/searchlist', component: SearchList },
// 动态路由传参,确认将来是哪个商品,路由参数中携带 id
{ path: '/prodetail/:id', component: ProDetail },
{ path: '/myorder', component: MyOrder },
{ path: '/pay', component: Pay }
]
})
Vant 组件神通广大的集成了:底部导航、并支持路由配置: 🙏感谢开发者,伟大的组件之神~
Vant导航-组件:Tabbar: Vant 2 - 轻量、可靠的移动端组件库 (vant-ui.github.io) vant-ui.js
引入组件;
import Vue from 'vue'
import { Button,Slider,Tabbar,TabbarItem } from 'vant';
Vue.use(Button);
Vue.use(Slider);
Vue.use(Tabbar);
Vue.use(TabbarItem);
定义layout
首页: 定义二级组件文件、配置二级路由…省略…),并定义首页结构:使用Vant导航组合组件;
<template>
<div>
<!-- 二级路由的位置 -->
<router-view></router-view>
<!-- active-color 选中标签的颜色\inactive-color 未选中标签的颜色 -->
<van-tabbar route active-color="#ee0a24" inactive-color="#000">
<!-- 通过 icon 插槽自定义图标 -->
<!-- 标签栏支持路由模式,用于搭配 vue-router 使用
路由模式下会匹配页面路径和标签的 to 属性,并自动选中对应的标签 -->
<van-tabbar-item to="/home" icon="wap-home-o">首页</van-tabbar-item>
<van-tabbar-item to="/category" icon="apps-o">分类页</van-tabbar-item>
<van-tabbar-item to="/cart" icon="shopping-cart-o">购物车</van-tabbar-item>
<van-tabbar-item to="/user" icon="user-o">我的</van-tabbar-item>
</van-tabbar>
</div>
</template>
<script>
export default { name: 'LayoutIndex' }
</script>
<style></style>
🆗,上述架子搭建的差不多了,下面开始进行页面填充开发——为了节省时间,下面开始CV战士了🗂️——Copy代码了:
既然要开发页面,难免会存在公共的样式配置: 每个页面都会有头部导航,方便进行页面返回、标题提醒;
当然,Vant组件也提供了: NavBar 导航栏
:引入组件、页面中导入;且几乎所有页面都会有头部导航;
此时,如果需要对头部样式进行调整,迫切需要一个全局的样式,进行统一配置管理;
src/styles/common.less
公共样式文件;main.JS
文件:import '@/styles/common.less'
//src/styles/common.less 项目全局样式配置
//去除内外边距、盒子样式
* { margin: 0; padding: 0; box-sizing: border-box; }
//文字溢出省略号样式
.text-ellipsis-2 {
overflow: hidden; -webkit-line-clamp: 2;
text-overflow: ellipsis; display: -webkit-box; -webkit-box-orient: vertical;
}
//Vant导航通用样式
.van-nav-bar {
//设置头部导航 < 颜色;
.van-nav-bar__arrow { color: #333; }
}
Copy登录页面代码、导入项目所需图片、请求查看页面: http://localhost:8080/#/login
实际开发过程中,我们通常会将: axios
进行封装成一个模块进行使用,主要出于以下几个关键原因:
axios
实现多数据源;
开发
、测试
、生产
,基础URL和其他配置可能不同,封装可以轻松地环境变量切换;
首先,安装axios依赖: npm install axios
或 yarn add axios
新建 src/utils/request.js
封装 axios 模块: 利用 axios.create
创建一个自定义的 axios
来使用;
/** 封装axios
* 后端基地址: https://smart-shop.itheima.net/index.php?s=/api */
import axios from 'axios'
// 创建 axios 实例,将来对创建出来的实例,进行自定义配置
// 好处:不会污染原始的 axios 实例
const instance = axios.create({
baseURL: 'https://smart-shop.itheima.net/index.php?s=/api/',
timeout: 5000
})
// 自定义配置 - 请求/响应 拦截器
// 添加请求拦截器
instance.interceptors.request.use(function (config) {
// 在发送请求之前做些什么
return config
}, function (error) {
// 对请求错误做些什么
return Promise.reject(error)
})
// 添加响应拦截器
instance.interceptors.response.use(function (response) {
// 2xx 范围内的状态码都会触发该函数。
// 对响应数据做点什么 (默认axios会多包装一层data,需要响应拦截器中处理一下)
return response.data;
}, function (error) {
// 超出 2xx 范围的状态码都会触发该函数
return Promise.reject(error);
})
// 导出配置好的实例
export default instance
src/views/login/index.vue: 登录页面,导入模块、发送获取验证码图片请求;
<template>
<div class="login">
<!-- ..省略部分代码.. -->
<div class="form-item">
<input class="inp" maxlength="5" placeholder="请输入图形验证码" type="text">
<img v-if="picUrl" :src="picUrl" @click="getPicCode">
</div>
<!-- ..省略部分代码.. -->
</div>
</div>
</template>
<script>
//导入request封装的axios模块;
import request from '@/utils/request'
export default {
name: 'LoginPage',
//钩子函数页面初始化,获取验证码图片;
async created () { this.getPicCode() },
data(){ return { picUrl: '', picKey: '' } },
methods: {
//获取验证码图片;
async getPicCode () {
const { data:{ base64,key }} = await request.get('/captcha/image'); //解构赋值获取图片信息;
this.picUrl = base64
this.picKey = key
},
}
}
</script>
基于请求回来的 base64 图片,实现图形验证码功能:
图形验证码,本质就是一个请求回来的图片,用户将来输入图形验证码,用于强制人机交互,可以抵御机器自动化攻击;
动态将请求回来的 base64
图片,解析渲染出来,base64 图片base64编码、可以直接给img src使用
、key图片唯一标识
;
使用:api
接口 - 封装图片验证码接口: 实际开发过程中,经常会遇到一个接口很多模块都会使用,
且频繁,在页面中定义请求接口,页面中充斥着请求代码,可阅读性不高;
所以: 优化,将请求封装成方法,统一存放到 api
模块,与页面分离;
具体实现: 新建 api/login.js
提供获取图形验证码 ``API`函数;
import request from '@/utils/request'
// 获取图形验证码
export const getPicCode = () => {
return request.get('/captcha/image')
}
src/views/login/index.vue
页面中调用测试:
//导入api/login.js 登录接口模块,并选择需要的函数对象引入
import { getPicCode } from '@/api/login'
//获取验证码图片;
async getPicCode () {
const { data:{ base64,key }} = await getPicCode(); //调用登录接口模块接口函数;
this.picUrl = base64
this.picKey = key
},
📲短信认证,大家都不陌生吧: 用户输入手机号进行、后端服务器——调用第三方短信服务,给手机发送验证短信;
用户输入短信——提交后端验证请求——通过,登录成功!!如此:简单一个功能,其实在前后端要经历一番不小的折腾;
246810
确认输入框手机号码正确: 如果不正确通过,Vant—Toast
组件消息提醒;
点击:获取验证码==> 开始验证倒计时、并发送短信获取验证码;
api/login.js
封装短信请求接口: 需要三个参数:图形唯一Key
、图形验证码
、手机号码
后端也要进行图形验证码校验;
export const getMsgCode = (captchaCode, captchaKey, mobile) => {
return request.post('/captcha/sendSmsCaptcha', {
form: { captchaCode, captchaKey, mobile }
})
}
页面中:login/index.vue: 引入接口模块,并调用请求接口,测试环境验证码始终为: 246810
//导入api/login.js 登录接口模块,并选择需要的函数对象引入
import { getPicCode,getMsgCode } from '@/api/login'
//省略部分代码....
export default {
//省略部分代码....
methods: {
//点击:获取验证码
async getCode () {
//验证手机号码合法性
if (!this.validFn()) { return }
//避免重复倒计时,发送请求:
//判断当前目前没有定时器开 且 totalSecond 和 second 一致秒数归位)
if (!this.timer && this.second === this.totalSecond) {
//发送请求...开启倒计时1000毫秒触发1次;
await getMsgCode(this.picCode, this.picKey, this.mobile)
this.$toast('短信发送成功,注意查收')
//每秒-1 秒到至≤0 清理定时器,重置数据;
this.timer = setInterval(() => {
this.second--
if (this.second <= 0) {
clearInterval(this.timer);
this.timer = null // 重置定时器 id
this.second = this.totalSecond // 归位
}
}, 1000)
}
},
}
}
🆗,终于来到了登录请求: 点击登录
按钮🕹️,验证手机号、图形码、短信—>携带参数发送请求,后端验证通过、成功登录!
export const codeLogin = (mobile, smsCode) => {
return request.post('/passport/login', {
form: {
isParty: false, //是否存在第三方用户信息
partyData: {}, //三方登录信息
smsCode, //短信验证码
mobile, //手机号
}
})
}
页面中:login/index.vue: 引入接口模块,并调用请求接口;
//<input class="inp" placeholder="请输入短信验证码" type="text" v-model="msgCode" >
//<div class="login-btn" @click="login" >登录</div>
//省略.... v-model表单元素、登录按钮注入函数;
//导入api/login.js 登录接口模块,并选择需要的函数对象引入
import { getPicCode,getMsgCode,login } from '@/api/login'
//省略部分代码....
export default {
//省略部分代码....
methods: {
//点击:登录
async login(){
if (!this.validFn()) { return } //校验手机\图形验证码;
if (!/^\d{6}$/.test(this.msgCode)) { //校验短信;
this.$toast('请输入正确的手机验证码')
return
}
await codeLogin(this.mobile, this.msgCode); //登录请求;
this.$toast('登录成功');
this.$router.push('/'); //路由首页;
}
}
}
🎉🎉 完成了登录、But有没有发现有一个🐞:好像,无论登录接口请求:成功\失败,都会成功跳转❗❗
查看代码,因为:我们并没有对接口返回结果进行处理; 解决方案: 登录函数添加
const res = await codeLogin(this.mobile, this.msgCode); //登录请求;
if( res.status!=200 ){ return this.$toast('接口异常、登录失败'); }
可实际开发中,有非常多的接口、每个接口都要进行处理… 有没有更好的解决
❓
还记得上面,封装Axios模块吗? 我们可以对模块进行统一的:请求\响应拦截处理
🧱
loading
效果、告知用户,加载中—请耐心等待;loading
// 自定义配置 - 请求/响应 拦截器
// 添加请求拦截器: 添加 loading 效果
instance.interceptors.request.use(function (config) {
Toast.loading({
message: '加载中...',
forbidClick: true, // 禁止背景点击
duration: 0, // 不会自动消失
loadingType: 'spinner', // 配置loading图标
})
return config
}, function (error) {
// 对请求错误做些什么
return Promise.reject(error)
})
// 添加响应拦截器: 处理接口异常情况\关闭 loading
instance.interceptors.response.use(function (response) {
// 2xx 范围内的状态码都会触发该函数
// 对响应数据做点什么 (默认axios会多包装一层data,需要响应拦截器中处理一下)
const res = response.data;
if (res.status !== 200) {
Toast(res.message); //Toast给错误提示
return Promise.reject(res.message); //抛出一个错误的promise
} else {
// 正确情况,直接走业务核心逻辑,清除loading效果
Toast.clear()
}
return res;
}, function (error) {
//超出 2xx 范围的状态码都会触发该函数,对响应错误做点什么;
return Promise.reject(error)
})
注意: 实际开发,接口异常提示消息,请与前后端协调处理…
登录\权限\认证: 行外人:简单的业务、行内人:后端?前端?交互校验???
登录—是开发过程中最让人头疼的事情了, 因为看似非常简单一个业务逻辑,内部有非常多的规则控制;
一体式项目、前后端分离项目、分布式、微服务、非常混乱: 虽然逻辑类似,处理起来却又有很多细小的控制;
此处介绍,前端登录的处理规则=> 关于后端,这里有一个Node+Express的简单业务流程:Express进阶升级=>会话控制;
无法区分用户...
BiliBili📺
A喜欢看鬼畜👻、B喜欢看番剧🍅【都收藏了很多视频…】所以: 在用户登录,服务器会返回给我们一个:token令牌🛡︎
,之后的每次请求,都携带这个令牌🛡︎
;
服务器,根据令牌🛡︎: 验证用户信息,判断用户状态,🆗,大致如此,接下来就来康康这个令牌🛡︎吧;
我们都知道:Vuex: 集中存储组件的数据,相当于一个数据共享的容器,由此:非常适合用来存储,登录成功的Token
新建 vuex user模块 store/modules/user.js: 挂载到 vuex 上、代码省略…)
export default {
namespaced: true,
state () {
return {
// 个人权证相关
userInfo: { token: '', userId: '' }
}
},
mutations: {
//用于组件修改userInfo信息;
setUserInfo (state, obj) { state.userInfo = obj }
},
actions: {},
getters: {}
}
页面中:login/index.vue: 用户登录成功,获取用户信息调用Vuex组件函数保存信息;
const res = await codeLogin(this.mobile, this.msgCode); //登录请求;
// if( res.status!=200 ){ return this.$toast('接口异常、登录失败'); } //由响应拦截器统一处理;
this.$store.commit('user/setUserInfo',res.data); //调用Vuex模块函数,保存用户信息;
如此,Vuex支持在项目的任何组件获取数据; 但,还有一个问题,Vuex会被浏览器刷新丢失!!
解决: Vuex会被浏览器刷新丢失!!,将Vuex数据保存至:浏览器—的localStorage
,以达到数据持久化的目的;
为什么要封装:localStorage==> 为了方便操作,传统的localStorage
使用,根据Key进行读取,不便于操作\管理;
新建 utils/storage.js
封装方法:
//定义用户信息key
const USERINFO_KEY = 'UserinfoKey'
// 设置个人信息
export const setInfo = (info) => { localStorage.setItem(USERINFO_KEY, JSON.stringify(info)) }
// 获取个人信息
export const getInfo = () => {
//从localStorage获取用户信息,没有则返回空对象;
const result = localStorage.getItem(USERINFO_KEY);
return result ? JSON.parse(result) : { token: '', userId: '' } //三元运算符判断是否存在个人信息返回;
}
// 注销:移除个人信息
export const removeInfo = () => { localStorage.removeItem(USERINFO_KEY) }
修改:store/modules/user.js
模块存|取调用storage:
import { getInfo, setInfo } from '@/utils/storage';
export default {
namespaced: true,
state () {
return {
// 个人权证相关
userInfo: getInfo(), //从localStorage中获取用户信息;
}
},
mutations: {
//用于组件修改userInfo信息;
setUserInfo (state, obj) { //登录成功保存用户信息、保存localStorage
state.userInfo = obj;
setInfo(obj)
}
},
actions: {},
getters: {}
}
🎉🎉 成功使用:LocalStorage
持久化保存,Vuex;
智慧商城项目,大部分页面,游客都可以直接访问: 但,并不是所有业务场景,都支持游客模式;
对于支付页,订单页等,必须是登录的用户才能访问的,游客不能进入该页面,需要做拦截处理;
目标: 如:遇到需要登录才能进行的操作,提示并跳转到登录;
设置项目:路由导航守卫 VueRouter进阶内容;
router.beforeEach((to, from, next) => {
// 1. to 往哪里去, 到哪去的路由信息对象
// 2. from 从哪里来, 从哪来的路由信息对象
// 3. next() 是否放行
// 如果next()调用,就是放行
// next(路径) 拦截到某个路径页面
})
优化:router/index.js: 配置全局守卫:访问权限页面时,拦截判断→ 用户是否有登录权证 token
//引入Vuex数据对象;
import store from '@/store'
// 所有的路由在真正被访问到之前(解析渲染对应组件页面前),都会先经过全局前置守卫;
// 只有全局前置守卫next()放行了,才会到达对应的页面;
// 定义数组: 专门存放所有需要权限访问的页面;
const authUrls = ['/pay', '/myorder']
router.beforeEach((to, from, next) => {
//校验 to.path 是否在 authUrls 中出现过,非权限页面,直接放行;
if (!authUrls.includes(to.path)) { return next(); }
// 是权限页面,判断token是否存在
const token = store.getters.token;
if (token) {
next()
}
else {
next('/login'); //跳转首页;
}
})
完结撒花,终于搞定了登录模块、下一篇文章结束这个小Demo项目
本代码已经使用Git进行管理: 公众号回复:Vue项目工程化
关于Git 版本管理切换可能出现的问题: 代码管理,有时候在操作过程误操作,可能会导致:找不到分支、代码丢失...
git fsck --lost-found
git show be7792e60920d944b772d2154423e958e3a3a646
git reset --hard 1aa0cc91e883597b0769bf36499491b480c7bcb5
#上述命令应该可以解决大部分,分支、代码丢失问题: 2-3命令中索引编码需要根据需求变动)
git fsck --lost-found
: 命令用来检查Git数据库完整性,并找出任何悬挂
、丢失
对象,
比如:那些因为提交被重置、删除而不再被引用的文件版本,并返回对应的版本索引:xxxxxxxxxxx
通常是一串长字符;
git show xxxxxxxxxxxxxxxx
: 显示指定哈希值的提交详情,包括提交信息、作者、日期以及该提交影响的文件的差异;
git reset --hard xxxxxxxxxxxxxxxx
: 命令将你的工作树、索引(暂存区)以及HEAD指针都重置到指定的提交状态;
删除丢失版本或悬空对象: 通过 git fsck --lost-found
找到的丢失版本或悬空对象,
这些丢失
的对象实际上是未被引用的对象,它们在 .git/lost-found
目录下被暂时存放,
以便于恢复误操作删除的数据,如果你确定要删除这些对象,意味着你不再需要它们,可以通过以下步骤:
#首先运行 git fsck --lost-found,这会列出所有悬空的对象
#进入 .git/lost-found 目录,它分为两个子目录: other 和 commit;
cd .git/lost-found #在尝试删除之前,确保你已经检查过这些文件,确认没有需要恢复的数据;
#删除other和commit目录下的所有文件
rm -rf commit/*
rm -rf other/*
#清理Git数据库: 虽然上述步骤已经删除了文件,但Git的对象数据库中可能还保留着引用计数为0的对象;
git gc --prune=now #彻底清理这些不再被引用的对象,这一步会压缩并清理Git仓库