vue3后台管理系统 vue3+vite+pinia+element-plus+axios上
前言
项目安装与启动
使用vite作为项目脚手架
# pnpm
pnpm create vite my-vue-app --template vue
安装相应依赖
# sass
pnpm i sass
# vue-router
pnpm i vue-router
# element-plus
pnpm i element-plus
# element-plus/icon
pnpm i @element-plus/icons-vue
安装element-plus按需自动引入插件
pnpm install -D unplugin-vue-components unplugin-auto-import
并在vite.config.js中配置
import { defineConfig } from 'vite'import vue from '@vitejs/plugin-vue'import AutoImport from 'unplugin-auto-import/vite'import Components from 'unplugin-vue-components/vite'import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'export default defineConfig({plugins: [vue(),AutoImport({resolvers: [ElementPlusResolver()],}),Components({resolvers: [ElementPlusResolver()],}),],resolve:{alias: {'@': '/src'}}})
注册elementplus的icon库
import * as ElementPlusIconsVue from '@element-plus/icons-vue'const app = createApp(App)app.use(router).mount('#app')for (const [key, component] of Object.entries(ElementPlusIconsVue)) {app.component(key, component)}
删除helloworld组件和style.css 删除App.vue相应代码
在src目录下创建router文件夹在其中创建index.js 并配置基本内容
import {createRouter,createWebHashHistory} from 'vue-router'
const routes = [
{
path:'/',name:'main',
redirect:"/home",
component:()=>import("@/views/main.vue"),
children:[path:"/home",name:"Home",component:()=>import("@/views/Home.vue")
]}]const router = createRouter({history:createWebHashHistory() ,routes})export default router
并在main.js中注册和在App.vue中使用
//main.js
app.use(router).mount('#app')
//App.vue
<template><router-view></router-view></template>
创建views文件夹,创建Main.vue文件
使用element-plus组件库container布局容器
<template><div class="commom-layout"><el-container class="lay-container"><common-aside></common-aside><el-container><el-header class="el-header"><commonHeader></commonHeader></el-header><common-tab></common-tab><el-main class="right-main"><RouterView></RouterView></el-main></el-container></el-container></div></template><script setup>import commonAside from '../components/commonAside.vue';import commonHeader from '../components/commonHeader.vue';import commonTab from '../components/commonTab.vue';</script><style scoped lang="scss">.commom-layout, .lay-container{height:100%;}.el-header{background-color: #333;}</style>
布局已经搭好 让我们完成里面的组件
创建component文件夹创建common-aside.vue文件,也就是el-aside中套了一个el-menu,并使用vue-router中跳转路由,并用pinia
状态管理工具 来控制兄弟组件中的通信
所以需要先引入pinia,并创建store文件夹与index.js文件
pnpm i pinia
//在main.js
const pinia = createPinia()app.use(pinia)
// store/index.js
import { defineStore } from 'pinia'state:() => {return {isCollapse: true,
menuList:[],
}},
<template><el-aside :width="MenuWidth"><el-menubackground-color="#545c64"text-color="#fff":collapse="isCollapse":collapse-transition="false":default-active="activeMenu"><h3 v-show="!isCollapse">通用后台管理系统</h3><h3 v-show="isCollapse">后台</h3><el-menu-item v-for="item in noChildren" :index="item.path" :key="item.path"@click="handleMenu(item)"><component class="icons" :is="item.icon"></component><span>{{ item.label }}</span></el-menu-item><el-sub-menu v-for="item in hasChildren" :index="item.path" :key="item.path"><template #title><component class="icons" :is="item.icon"></component><span>{{ item.label }}</span></template><el-menu-item-group><el-menu-itemv-for="(subItem,subIndex) in item.children":key="subItem.path":subIndex="subItem.path"@click="handleMenu(subItem)"><component class="icons" :is="subItem.icon"></component><span>{{ subItem.label }}</span></el-menu-item></el-menu-item-group></el-sub-menu></el-menu></el-aside></template><script setup>import { ref, computed } from 'vue'import { useRouter ,useRoute} from 'vue-router';import { useAllDataStore } from '../stores/index.js'// const list = ref([// { path: '/home', name: 'home', label: '首页', icon: 'house', url: 'Home' },// { path: '/mall', name: 'mall', label: '商品管理', icon: 'video-play', url: 'Mall' },// { path: '/user', name: 'user', label: '用户管理', icon: 'user', url: 'User' },// {// path: 'other', label: '其他', icon: 'location', children: [{ path: '/page1', name: 'page1', label: '页面1', icon: 'setting', url: 'Page1' },// { path: '/page2', name: 'page2', label: '页面2', icon: 'setting', url: 'Page2' }]// }])const AllDataStore = useAllDataStore()const list = computed(()=>AllDataStore.$state.menuList)const noChildren = computed(() => list.value.filter(item => !item.children))const hasChildren = computed(() => list.value.filter(item => item.children))const clickMenu = (item) => { router.push(item.path) }const isCollapse = computed(() => AllDataStore.$state.isCollapse)const MenuWidth= computed(() => AllDataStore.$state.isCollapse ? '64px' : '180px')const router = useRouter()const route = useRoute()const activeMenu = computed(()=>route.path)const handleMenu= (item) => {router.push(item.path)AllDataStore.selectMenu(item)}</script>
<style lang="scss" scoped>
// var asideColor: #545c64;
.icons{
height:18px;
width:18px;
margin-right:5px;
}
.el-menu{
border-right:none;
h3{
line-height:48px;
color:#fff;
text-align:center;
}
}
.el-aside{
height:100%;
background-color: #545c64;
}
</style>
comonheader组件搭建 使用下拉框el-dropdown和面包屑el-breadcrumb
<template><div class="header"><div class="l-content"><el-button size="small" @click="handleCollapse"><component class="icons" is="menu"></component></el-button><el-breadcrumb separator="/" class="bread"><el-breadcrumb-item :to="{ path: '/' }">首页</el-breadcrumb-item></el-breadcrumb></div><div class="r-content"><el-dropdown><span class="el-dropdown-link"><span><img :src="getImageUrl('user')" class="user"></span></span><template #dropdown><el-dropdown-menu><el-dropdown-item>个人中心</el-dropdown-item><el-dropdown-item @click="handleLoginOut">退出</el-dropdown-item></el-dropdown-menu></template></el-dropdown></div></div></template><script setup>import {useAllDataStore}from '../stores/index.js'import {useRouter}from 'vue-router'import {computed} from 'vue'const AllData = useAllDataStore()const getImageUrl = (user) => {return new URL(`../assets/images/${user}.png`,import.meta.url).href}const handleCollapse = () => {AllData.$state.isCollapse = !AllData.$state.isCollapse}</script><style lang="scss" scoped>.header {display:flex;justify-content: space-between;align-items: center;height:100%;width:100%;background-color: #333;}.icons{height:20px;width:20px;}.l-content{display: flex;align-items: center;.el-button{margin-right:20px;}}.r-content{.user{width:40px;height:40px;border-radius: 50%;outline: none;}}//样式穿透:deep(.bread span){color:#fff !important;cursor:pointer !important;}</style>
接下来实现首页剩余内容
使用elementplus中的layout布局 通过基础的 24 分栏,迅速简便地创建布局,在使用el-card卡片来分隔不同内容
<template><el-row class="home" :gutter="20"><el-col :span="8" style="margin-top:20px"><el-card shadow="hover"><div class="user"><img :src="getImageUrl('user')" class="user"/><div class="user-info"><p class="user-info-admin">Admin</p><p class="user-info-p">超级管理员</p></div></div><div class="login_info"><p>上次登陆时间:<span>2024-07-24</span></p><p>上次登陆地点:<span>北京</span></p></div></el-card><el-card shadow="hover" class="user-table"><el-table :data="tableData"><el-table-columnv-for="(val,key) in tableLabel":key = "key":prop = "key":label = "val"></el-table-column></el-table></el-card></el-col><el-col :span="16" style="margin-top:20px"><div class="num"><el-card :body-style="{display:'flex', padding:0}"v-for="item in countData":key="item.name"><component :is="item.icon" class="icons" :style="{background:item.color}"></component><div class="detail"><p class="num">${{ item.value }}</p><p class="txt">${{ item.name }}</p></div></el-card></div><el-card class="top-echart"><div ref="echart" style="height:230px"></div></el-card><div class="graph"><el-card><div ref="userEchart" style="height:240px"></div></el-card><el-card><div ref="videoEchart" style="height:240px"></div></el-card></div></el-col></el-row></template><script setup>import {ref,getCurrentInstance,onMounted,reactive} from 'vue'import * as echarts from 'echarts'const {proxy} = getCurrentInstance()const getImageUrl = (user) => {return new URL(`../assets/images/${user}.png`,import.meta.url).href}const observer =ref(null)const tableData = ref([])const countData = ref([])const chartData = ref([])const tableLabel = ref({name: "课程",todayBuy: "今日购买",monthBuy: "本月购买",totalBuy: "总购买",})const getTableData = async () => {const data = await proxy.$api.getTableData()tableData.value = data.tableData}const getCountData = async () => {const data = await proxy.$api.getCountData()countData.value = data}const xOptions = reactive({// 图例文字颜色textStyle: {color: "#333",},legend: {},grid: {left: "20%",},// 提示框tooltip: {trigger: "axis",},xAxis: {type: "category", // 类目轴data: [],axisLine: {lineStyle: {color: "#17b3a3",},},axisLabel: {interval: 0,color: "#333",},},yAxis: [{type: "value",axisLine: {lineStyle: {color: "#17b3a3",},},},],color: ["#2ec7c9", "#b6a2de", "#5ab1ef", "#ffb980", "#d87a80", "#8d98b3"],series: [],})const pieOptions = reactive({tooltip: {trigger: "item",},legend: {},color: ["#0f78f4","#dd536b","#9462e5","#a6a6a6","#e1bb22","#39c362","#3ed1cf",],series: []})const getChartData = async () => {const {orderData,userData,videoData}= await proxy.$api.getChartData()xOptions.xAxis.data = orderData.date;xOptions.series = Object.keys(orderData.data[0]).map(val=>({name:val,data:orderData.data.map(item => item[val]),type:'line'}))const oneEchart = echarts.init(proxy.$refs['echart'])oneEchart.setOption(xOptions)xOptions.xAxis.data = userData.map(item => item.date)xOptions.series=[{name:'新增用户',data:userData.map(item=>item.new),type:'bar'},{name:'活跃用户',data:userData.map(item=>item.active),type:'bar'}]const twoEchart = echarts.init(proxy.$refs['userEchart'])twoEchart.setOption(xOptions)pieOptions.series = [{data:videoData,type:'pie',}]const threeEchart = echarts.init(proxy.$refs['videoEchart'])threeEchart.setOption(pieOptions)//监听页面的变化observer.value = new ResizeObserver(() => {oneEchart.resize()twoEchart.resize()threeEchart.resize()})if(proxy.$refs['echart']){observer.value.observe(proxy.$refs["echart"])}}onMounted(() => {getTableData()getCountData()getChartData()})</script><style lang="scss" scoped>.home{height:150vh;overflow:hidden;.user{display:flex;align-items:center;border-bottom:1px solid #ccc;margin-bottom:20px;img{width:150px;height:150px;border-radius: 50%;margin-right: 40px;}.user-info{p{line-height:40px;}.user-info-p{color:#999;}.user-info-admin{font-size:35px;}}}.login_info{p{line-height:30px;font-size:14px;color:#990;}span{color:#666;margin-left:60px;}}.user-table{margin-top:20px;}.num {display: flex;flex-wrap: wrap;justify-content: space-between;.el-card {width: 32%;margin-bottom: 20px;}.icons {width: 80px;height: 80px;font-size: 30px;text-align: center;line-height: 80px;color: #fff;}.detail {margin-left: 15px;display: flex;flex-direction: column;justify-content: center;.num {font-size: 30px;margin-bottom: 10px;}.txt {font-size: 14px;text-align: center;color: #999;}}}.graph {margin-top: 20px;display: flex;justify-content: space-between;.el-card {width: 48%;height: 260px;}}}</style>
没有后端 我们用mock来模拟网络请求 使用axios来处理网络请求
pnpm i axios
pnpm i mockjs
创建api文件夹 创建request.js 文件 二次封装下axios
import axios from "axios";import config from '../config/index'const service = axios.create({baseURL:config.baseApi,});const NETWORK_ERROR = '网络错误...'service.interceptors.request.use((config) => {return config},(error) => {return Promise.reject(error)})service.interceptors.response.use((res) => {const {code,data,msg} = res.dataif(code===200){return data}else{return Promise.reject(msg || NETWORK_ERROR)}})function request(options){// console.log(config.env)options.method = options.method || "get"if(options.method.toLowerCase() === "get"){options.params = options.data}//对mock的开关做一个处理let isMock = config.mockif(config.env !== "undefined"){isMock = config.env}//针对环境作处理if(config.env === "prod"){service.defaults.baseURL = config.baseAPi;}else{// console.log('isMock',isMock)service.defaults.baseURL = isMock ? config.mockApi : config.baseApi;}return service(options)}export default request
在api文件下创建api.js
import request from './request.js'export default {getTableData(){return request({url:"/home/getTable",method:'get',})},getCountData(){return request({url:"/home/getCountData",method:'get',})},getChartData(){return request({url:"/home/getChartData",method:'get',})},}
使用mock模拟请求 在api文件下创建mockData下创建home.js 并在api目录下创建mock.js作为出口
//mock.js
import Mock from "mockjs"
import homeApi from "./mockData/home.js"
Mock.mock(/api\/home\/getTableData/,"get",homeApi.getTableData)Mock.mock(/api\/home\/getCountData/,"get",homeApi.getCountData)Mock.mock(/api\/home\/getChartData/,"get",homeApi.getChartData)
// mockData/home.js
export default {getTableData: () => {return {code: 200,data: {tableData: [{name: "oppo",todayBuy: 500,monthBuy: 3500,totalBuy: 22000,},{name: "vivo",todayBuy: 300,monthBuy: 2200,totalBuy: 24000,},{name: "苹果",todayBuy: 800,monthBuy: 4500,totalBuy: 65000,},{name: "小米",todayBuy: 1200,monthBuy: 6500,totalBuy: 45000,},{name: "三星",todayBuy: 300,monthBuy: 2000,totalBuy: 34000,},{name: "魅族",todayBuy: 350,monthBuy: 3000,totalBuy: 22000,},],},}},getCountData: () => {return {code: 200,data: [{name: "今日支付订单",value: 1234,icon: "SuccessFilled",color: "#2ec7c9",},{name: "今日收藏订单",value: 210,icon: "StarFilled",color: "#ffb980",},{name: "今日未支付订单",value: 1234,icon: "GoodsFilled",color: "#5ab1ef",},{name: "本月支付订单",value: 1234,icon: "SuccessFilled",color: "#2ec7c9",},{name: "本月收藏订单",value: 210,icon: "StarFilled",color: "#ffb980",},{name: "本月未支付订单",value: 1234,icon: "GoodsFilled",color: "#5ab1ef",},],};},getChartData: () => {return {code: 200,data: {orderData: {date: ["2019-10-01","2019-10-02","2019-10-03","2019-10-04","2019-10-05","2019-10-06","2019-10-07",],data: [{苹果: 3839,小米: 1423,华为: 4965,oppo: 3334,vivo: 2820,一加: 4751,},{苹果: 3560,小米: 2099,华为: 3192,oppo: 4210,vivo: 1283,一加: 1613,},{苹果: 1864,小米: 4598,华为: 4202,oppo: 4377,vivo: 4123,一加: 4750,},{苹果: 2634,小米: 1458,华为: 4155,oppo: 2847,vivo: 2551,一加: 1733,},{苹果: 3622,小米: 3990,华为: 2860,oppo: 3870,vivo: 1852,一加: 1712,},{苹果: 2004,小米: 1864,华为: 1395,oppo: 1315,vivo: 4051,一加: 2293,},{苹果: 3797,小米: 3936,华为: 3642,oppo: 4408,vivo: 3374,一加: 3874,},],},videoData: [{ name: "小米", value: 2999 },{ name: "苹果", value: 5999 },{ name: "vivo", value: 1500 },{ name: "oppo", value: 1999 },{ name: "魅族", value: 2200 },{ name: "三星", value: 4500 },],userData: [{ date: "周一", new: 5, active: 200 },{ date: "周二", new: 10, active: 500 },{ date: "周三", new: 12, active: 550 },{ date: "周四", new: 60, active: 800 },{ date: "周五", new: 65, active: 550 },{ date: "周六", new: 53, active: 770 },{ date: "周日", new: 33, active: 170 },],},};}}
最终效果
如果对你有所帮助就点个关注吧
本文是这篇文章的笔记
https://www.bilibili.com/video/BV1LS421d7cY?p=5&vd_source=e73709c9a1618b4c6dfd58c6c40d8986
相关文章:

vue3后台管理系统 vue3+vite+pinia+element-plus+axios上
前言 项目安装与启动 使用vite作为项目脚手架 # pnpm pnpm create vite my-vue-app --template vue安装相应依赖 # sass pnpm i sass # vue-router pnpm i vue-router # element-plus pnpm i element-plus # element-plus/icon pnpm i element-plus/icons-vue安装element-…...

Mysql的事务隔离级别实现原理
一、事务隔离级别 mysql支持四种事务隔离级别: 读未提交:一个事务可以读取到另一个事务还未提交的数据;读已提交:一个事务可以读取到另一个事务已经提交的数据;可重复读:同一个事务中,无论读取…...

计算机体系结构:缓存一致性ESI
集中式缓存处理器结构(SMP) 不同核访问存储器时间相同。 分布式缓存处理器结构(NUMA) 共享存储器按模块分散在各处理器附近,处理器访问本地存储器和远程存储器的延迟不同,共享数据可进入处理器私有高速缓存…...

log4j2漏洞练习(未完成)
log4j2 是Apache的一个java日志框架,我们借助它进行日志相关操作管理,然而在2021年末log4j2爆出了远程代码执行漏洞,属于严重等级的漏洞。apache log4j通过定义每一条日志信息的级别能够更加细致地控制日志生成地过程,受影响的版本…...
常见网络攻击方法原理、应用场景和防御方法(一)
目录 1、SQL注入(SQL Injection)原理应用场景防御方法 2、跨站脚本攻击(XSS,Cross-Site Scripting)原理应用场景防御方法 3、跨站请求伪造(CSRF,Cross-Site Request Forgery)原理应用场景防御方法 4、文件上传漏洞原理应用场景防御方法 5、远程代码执行(…...

【leetcode十分钟】覆盖所有点的最少矩形数目(C++思路详解)
思路详解: 0. 题目情境并未限制矩形高度,故矩形数目的判断只和点的横坐标有关 1. 为了不重不漏地考虑到所有点,故笔者选择首先将二维数组中的点按横坐标的大小排序 //说明:本来笔者以为需要自定义sort排序,后来发现…...

【Vue3】默认插槽
【Vue3】默认插槽 背景简介开发环境开发步骤及源码 背景 随着年龄的增长,很多曾经烂熟于心的技术原理已被岁月摩擦得愈发模糊起来,技术出身的人总是很难放下一些执念,遂将这些知识整理成文,以纪念曾经努力学习奋斗的日子。本文内…...

华清day4 24-7-31
1> 使用父子进程完成两个文件的拷贝 父进程拷贝前一半内容,子进程拷贝后一半内容 子进程结束后退出,父进程回收子进程的资源 /* 使用父子进程完成两个文件的拷贝父进程拷贝前一半内容,子进程拷贝后一半内容 子进程结束后退出ÿ…...

搜维尔科技:Manus VR数据手套-适用于机器人、人工智能和机器学习解决方案
在劳动力短缺和工作环境日益严峻的今天,机器人技术正成为解决这些复杂问题的关键。MANUS™ 手指捕捉技术,结合先进的量子追踪技术,为机器人的精确操作和远程控制提供了准确且先进的解决方案。 技术亮点 实时数据捕捉:通过Quantum…...

知识文库杂志知识文库杂志社知识文库编辑部2024年第12期目录
文艺理论 现代高校书院对中国传统书院学术精神的汲取与转化 李奥楠;时新洁; 1-4 个案工作介入高中美术艺考生及家长心理调适的应用研究 魏星; 5-8《知识文库》投稿:cn7kantougao163.com 中华优秀传统文化视角下高校美育课程实践教学 李丛丛; 9-12 基…...

【Linux网络编程】套接字Socket
网络编程基础概念: ip地址和端口号 ip地址是网络协议地址(4字节32位,形式:xxx.xxx.xxx.xxx xxx在范围[0, 255]内),是IP协议提供的一种统一的地址格式,每台主机的ip地址不同,一个…...
es之must、filter、must_not、should
文章目录 概述mustfiltermust_notshouldmust和filter的区别 概述 在Elasticsearch中,布尔查询(bool query)是构建复杂查询的基本工具。它允许你组合多个查询子句,每个子句可以使用不同的逻辑操作符。常见的逻辑操作符包括 must、…...

RocketMQ消息发送基本示例(推送消费者)
消息生产者通过三种方式发送消息 1.同步发送:等待消息返回后再继续进行下面的操作 同步发送保证了消息的可靠性,适用于关键业务场景。 2.异步发送:不等待消息返回直接进入后续流程.broker将结果返回后调用callback函数,并使用 CountDownLatch计数 3.单向发送:只…...
23 MySQL基本函数、分组查询、多列排序(3)
上一篇「22 B端产品经理与MySQL基本查询、排序(2)」了解了基本的常识和基本查询以及单列排序。下面介绍常见的基本函数、分组查询以及多列排序: 基本函数 user表 (注:以下SQL语句示例全部基于下面「user表」) uidunamedepiduag…...

PHP与SEO,应用curl库获取百度下拉关键词案例!
编程语言从来都是工具,编程逻辑思维才是最重要的,在限定的规则内,实现自己的想法,正如人生一样! 不管是python还是php只要掌握了基础语法规则,明确了实现过程,都能达到想要实现的结果࿰…...

MySQL:子查询
MySQL 子查询 MySQL中的子查询是一个强大的功能,子查询是指在一个查询语句中嵌套另一个查询语句的情况。嵌套查询中的内部查询语句可以使用外部查询语句的结果来进行过滤、联接或作为子查询的值,它允许我们在一个查询内部嵌套另一个查询。通过子查询可以…...

C++—— IO流
一、C语言的输入与输出 C语言中我们用到的最频繁的输入输出方式就是scanf()和printf()。 scanf():从标准输入设备(键盘)中读取数据,并将值存放在变量中。 printf():将指定的文字/字符串输出到标准输出设备(…...
vue+node后台处理大文件切片上传--前端部分
本文主要介绍,在vue3vite项目下,如何进行有效的大文件上传,本文章主要讲大文件切片上传方式,并提供简单的demo代码供参考 首先,请确保已经创建好项目,这一步跳过。 1、为了选择合适的文件,我们…...

【通俗理解】艺术与数学交融
【通俗理解】艺术与数学交融 艺术与数学的奇妙交融 你可以把艺术比作一个“梦幻花园”,它充满了无限的可能性和美感。而数学则是一把“精密钥匙”,它能够解开花园中的秘密,揭示美的内在结构。 艺术与数学交融的核心作用 组件/步骤描述艺术表…...

深入探讨 Docker 容器文件系统
引言 随着云计算和微服务架构的兴起,Docker 容器技术迅速成为开发和运维人员的首选工具。Docker 容器不仅提供了一种轻量级的虚拟化方式,还简化了应用程序的部署和管理。在众多的技术细节中,Docker 容器文件系统是一个至关重要的组成部分。本…...
Java - Mysql数据类型对应
Mysql数据类型java数据类型备注整型INT/INTEGERint / java.lang.Integer–BIGINTlong/java.lang.Long–––浮点型FLOATfloat/java.lang.FloatDOUBLEdouble/java.lang.Double–DECIMAL/NUMERICjava.math.BigDecimal字符串型CHARjava.lang.String固定长度字符串VARCHARjava.lang…...

C# 求圆面积的程序(Program to find area of a circle)
给定半径r,求圆的面积。圆的面积应精确到小数点后5位。 例子: 输入:r 5 输出:78.53982 解释:由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982,因为我们只保留小数点后 5 位数字。 输…...
高效线程安全的单例模式:Python 中的懒加载与自定义初始化参数
高效线程安全的单例模式:Python 中的懒加载与自定义初始化参数 在软件开发中,单例模式(Singleton Pattern)是一种常见的设计模式,确保一个类仅有一个实例,并提供一个全局访问点。在多线程环境下,实现单例模式时需要注意线程安全问题,以防止多个线程同时创建实例,导致…...

视觉slam十四讲实践部分记录——ch2、ch3
ch2 一、使用g++编译.cpp为可执行文件并运行(P30) g++ helloSLAM.cpp ./a.out运行 二、使用cmake编译 mkdir build cd build cmake .. makeCMakeCache.txt 文件仍然指向旧的目录。这表明在源代码目录中可能还存在旧的 CMakeCache.txt 文件,或者在构建过程中仍然引用了旧的路…...

使用Spring AI和MCP协议构建图片搜索服务
目录 使用Spring AI和MCP协议构建图片搜索服务 引言 技术栈概览 项目架构设计 架构图 服务端开发 1. 创建Spring Boot项目 2. 实现图片搜索工具 3. 配置传输模式 Stdio模式(本地调用) SSE模式(远程调用) 4. 注册工具提…...

[ACTF2020 新生赛]Include 1(php://filter伪协议)
题目 做法 启动靶机,点进去 点进去 查看URL,有 ?fileflag.php说明存在文件包含,原理是php://filter 协议 当它与包含函数结合时,php://filter流会被当作php文件执行。 用php://filter加编码,能让PHP把文件内容…...
Java求职者面试指南:Spring、Spring Boot、Spring MVC与MyBatis技术解析
Java求职者面试指南:Spring、Spring Boot、Spring MVC与MyBatis技术解析 一、第一轮基础概念问题 1. Spring框架的核心容器是什么?它的作用是什么? Spring框架的核心容器是IoC(控制反转)容器。它的主要作用是管理对…...

macOS 终端智能代理检测
🧠 终端智能代理检测:自动判断是否需要设置代理访问 GitHub 在开发中,使用 GitHub 是非常常见的需求。但有时候我们会发现某些命令失败、插件无法更新,例如: fatal: unable to access https://github.com/ohmyzsh/oh…...

Xcode 16 集成 cocoapods 报错
基于 Xcode 16 新建工程项目,集成 cocoapods 执行 pod init 报错 ### Error RuntimeError - PBXGroup attempted to initialize an object with unknown ISA PBXFileSystemSynchronizedRootGroup from attributes: {"isa">"PBXFileSystemSynchro…...
如何通过git命令查看项目连接的仓库地址?
要通过 Git 命令查看项目连接的仓库地址,您可以使用以下几种方法: 1. 查看所有远程仓库地址 使用 git remote -v 命令,它会显示项目中配置的所有远程仓库及其对应的 URL: git remote -v输出示例: origin https://…...