当前位置: 首页 > news >正文

JAVAWeb实战(前端篇)

项目实战一

0.项目结构

1.创建vue3项目,并导入所需的依赖

npm install vue-router
npm install axios
npm install pinia
npm install vue

2.定义路由,axios,pinia相关的对象 文件(.js)

2.1路由(.js)

import {createRouter,createWebHashHistory} from 'vue-router'import Login from '../components/Login.vue'
import Regist from '../components/Regist.vue'
import ShowSchedule from '../components/ShowSchedule.vue'import pinia from '../pinia.js'
import {defineUser} from '../store/userStore.js'let sysUser = defineUser(pinia)
const router= createRouter({history:createWebHashHistory(),routes:[{path:"/",redirect:"/showSchedule"},{path:"/showSchedule",component:ShowSchedule},{path:"/login",component:Login},{path:"/regist",component:Regist}]
})// 路由 的全局前置守卫 判断是否可以访问showSchedule
router.beforeEach((to,from,next)=>{if(to.path == '/showSchedule'){// 登陆过放行// 没登录 回到登录页if(sysUser.username == ''){next("/login")}else{next()}}else{next()}})export default router 

2.2axios(.js)

import axios from 'axios'//  创建instance实例
const instance = axios.create({baseURL:'http://localhost:8080/'})//  添加请求拦截
instance.interceptors.request.use(// 设置请求头配置信息config=>{//处理指定的请求头return config},// 设置请求错误处理函数error=>{return Promise.reject(error)}
)
// 添加响应拦截器
instance.interceptors.response.use(// 设置响应正确时的处理函数response=>{return response},// 设置响应异常时的处理函数error=>{return Promise.reject(error)}
)
// 默认导出
export default instance

2.3pinia

2.3.1开启pinia(.js)
// 开启pinia
import {createPinia} from 'pinia'
let pinia = createPinia()export default pinia
2.3.2根据数据库定义接收的pinia文件(.js)

数据库

schedule表

对应的pinia文件

这里用集合来接收所有数据

/* 
专门用于存储日程状态信息的pinia*/
import {defineStore} from 'pinia'export const defindSchedule= defineStore("scheduleList",{state:()=>{return {itemList:[]}},getters:{},actions:{}}

user表

对应的pinia文件

/* 
专门用于存储用户状态信息的pinia*/
import {defineStore} from 'pinia'export const defineUser= defineStore("loginUser",{state:()=>{return {uid:0,username:'' }},getters:{},actions:{}}
)

将他们挂载在main.js文件中

import { createApp } from 'vue'import App from './App.vue'import router from './router/router'import pinia from './pinia.js'const app =createApp(App)
app.use(router)
app.use(pinia)
app.mount('#app')

3.定义组件

3.1定义头组件

Header.vue

<script setup>/* 导入pinia数据 */import {defineUser} from "../store/userStore.js"import {defindSchedule} from "../store/scheduleStore.js"let sysUser = defineUser()let schedule = defindSchedule()import {useRouter} from 'vue-router'let router = useRouter()function logout(){// 清除所有pinia数据sysUser.$reset()schedule.$reset()// 跳转到登录页router.push("/login")}</script><template><div><h1 class="ht">欢迎使用日程管理系统</h1><div><div  class="optionDiv" v-if="sysUser.username == ''"><router-link to="/login"><button class="b1s">登录</button></router-link>   <router-link to="/regist"><button class="b1s">注册</button></router-link></div><div   class="optionDiv" v-else>欢迎 {{ sysUser.username }}   <button class="b1b" @click="logout()">退出登录</button> <router-link to="/showSchedule"><button class="b1b">查看我的日程</button></router-link></div><br></div></div>
</template><style scoped>.ht{text-align: center;color: cadetblue;font-family: 幼圆;}.b1s{border: 2px solid powderblue;border-radius: 4px;width:60px;background-color: antiquewhite;}.b1b{border: 2px solid powderblue;border-radius: 4px;width:100px;background-color: antiquewhite;}.optionDiv{width: 400px;float: right;}
</style>

3.2定义登入组件  Login.vue

<script setup>import {ref,reactive} from 'vue'import {useRouter} from 'vue-router'const router = useRouter()import{ defineUser}  from '../store/userStore.js'let sysUser = defineUser()import request  from '../utils/request'let loginUser =reactive({username:"",userPwd:""})let usernameMsg =ref("")let userPwdMsg =ref("")function checkUsername(){let usernameReg= /^[a-zA-Z0-9]{5,10}$/if(!usernameReg.test(loginUser.username)){usernameMsg.value="格式有误"return false}usernameMsg.value="OK"return true}function checkUserPwd(){let userPwdReg = /^[0-9]{6}$/if(!userPwdReg.test(loginUser.userPwd)){userPwdMsg.value="格式有误"return false}userPwdMsg.value="OK"return true}async function login(){// 表单数据格式都正确再提交let flag1 =checkUsername()let flag2 =checkUserPwd()if(!(flag1 && flag2)){return }let {data} = await request.post("user/login",loginUser) //发送请求if(data.code == 200 ){alert("登录成功")console.log(data)// 获得登录的用户信息,更新到pinia中sysUser.uid =data.data.loginUser.uid    //pinia获取登入信息sysUser.username = data.data.loginUser.username// 跳转到showSchedulerouter.push("/showSchedule")} else if( data.code == 503){alert("密码有误")}else if (data.code == 501 ){alert("用户名有误")}else {alert("未知错误")}}</script><template><div><h3 class="ht">请登录</h3><table class="tab" cellspacing="0px"><tr class="ltr"><td>请输入账号</td><td><input class="ipt" type="text" v-model="loginUser.username"@blur="checkUsername()"><span id="usernameMsg" v-text="usernameMsg"></span></td></tr><tr class="ltr"><td>请输入密码</td><td><input class="ipt" type="password" v-model="loginUser.userPwd"@blur="checkUserPwd()"><span id="userPwdMsg" v-text="userPwdMsg"></span></td></tr><tr class="ltr"><td colspan="2" class="buttonContainer"><input class="btn1" type="button" @click="login()" value="登录"><input class="btn1" type="button" value="重置"><router-link to="/regist"><button class="btn1">去注册</button></router-link></td></tr></table></div>
</template><style scoped>.ht{text-align: center;color: cadetblue;font-family: 幼圆;}.tab{width: 500px;border: 5px solid cadetblue;margin: 0px auto;border-radius: 5px;font-family: 幼圆;}.ltr td{border: 1px solid  powderblue;}.ipt{border: 0px;width: 50%;}.btn1{border: 2px solid powderblue;border-radius: 4px;width:60px;background-color: antiquewhite;}#usernameMsg , #userPwdMsg {color: gold;}.buttonContainer{text-align: center;}
</style>

3.3定义注册组件 Regist.vue

<script setup>import {ref,reactive} from 'vue'/* 导入发送请求的axios对象 */import request from'../utils/request'import {useRouter} from 'vue-router'const router = useRouter()let registUser = reactive({username:"",userPwd:""})let usernameMsg=ref('')let userPwdMsg=ref('')let reUserPwdMsg=ref('')let reUserPwd=ref('')async function checkUsername(){let usernameReg= /^[a-zA-Z0-9]{5,10}$/if(!usernameReg.test(registUser.username)){usernameMsg.value="格式有误"return false}// 发送异步请求   继续校验用户名是否被占用let {data} = await request.post(`user/checkUsernameUsed?username=${registUser.username}`)if(data.code != 200){usernameMsg.value="用户名占用"return false}usernameMsg.value="可用"return true}function checkUserPwd(){let userPwdReg = /^[0-9]{6}$/if(!userPwdReg.test(registUser.userPwd)){userPwdMsg.value="格式有误"return false}userPwdMsg.value="OK"return true}function checkReUserPwd(){let userPwdReg = /^[0-9]{6}$/if(!userPwdReg.test(reUserPwd.value)){reUserPwdMsg.value="格式有误"return false}if(registUser.userPwd != reUserPwd.value){reUserPwdMsg.value="两次密码不一致"return false}reUserPwdMsg.value="OK"return true}// 注册的方法async function regist(){// 校验所有的输入框是否合法let flag1 =await checkUsername()let flag2 =await checkUserPwd()let flag3 =await checkReUserPwd()if(flag1 && flag2 && flag3){let  {data}= await request.post("user/regist",registUser)//  let  {data}=  request.post("user/regist",registUser)if(data.code == 200){// 注册成功跳转 登录页alert("注册成功,快去登录吧")router.push("/login")}else{alert("抱歉,用户名被抢注了")}}else{alert("校验不通过,请求再次检查数据")}}function clearForm(){registUser.username=""registUser.userPwd=""usernameMsg.value=""userPwdMsg.value=""reUserPwd.value=""reUserPwdMsg.value=""}</script><template><div><h3 class="ht">请注册</h3><table class="tab" cellspacing="0px"><tr class="ltr"><td>请输入账号</td><td><input class="ipt" id="usernameInput" type="text" name="username" v-model="registUser.username"@blur="checkUsername()"><span id="usernameMsg" class="msg" v-text="usernameMsg"></span></td></tr><tr class="ltr"><td>请输入密码</td><td><input class="ipt" id="userPwdInput" type="password" name="userPwd" v-model="registUser.userPwd"@blur="checkUserPwd()"><span id="userPwdMsg" class="msg" v-text="userPwdMsg"></span></td></tr><tr class="ltr"><td>确认密码</td><td><input class="ipt" id="reUserPwdInput" type="password" v-model="reUserPwd"@blur="checkReUserPwd()"><span id="reUserPwdMsg" class="msg" v-text="reUserPwdMsg"></span></td></tr><tr class="ltr"><td colspan="2" class="buttonContainer"><input class="btn1" type="button" @click="regist()" value="注册"><input class="btn1" type="button" @click="clearForm()" value="重置"><router-link to="/login"><button class="btn1">去登录</button></router-link></td></tr></table></div>
</template>
<style scoped>.ht{text-align: center;color: cadetblue;font-family: 幼圆;}.tab{width: 500px;border: 5px solid cadetblue;margin: 0px auto;border-radius: 5px;font-family: 幼圆;}.ltr td{border: 1px solid  powderblue;}.ipt{border: 0px;width: 50%;}.btn1{border: 2px solid powderblue;border-radius: 4px;width:60px;background-color: antiquewhite;}.msg {color: gold;}.buttonContainer{text-align: center;}
</style>

3.4定义主体显示内容组件ShowSchedule.vue

<script setup>/* 导入pinia数据 */import {defineUser} from '../store/userStore.js'import {defindSchedule} from '../store/scheduleStore.js'let sysUser = defineUser()let schedule = defindSchedule()import {ref,reactive,onUpdated,onMounted} from 'vue'import request from '../utils/request'//挂载完毕后,立刻查询当前用户的所有日程信息,赋值给piniaonMounted(async ()=>{showSchedule()})// 查询当前用户所有日程信息 并展示到视图的方法async function showSchedule(){// 发送异步请求,获得当前用户的所有日程记录let {data} = await request.get("schedule/findAllSchedule",{params:{"uid":sysUser.uid}})schedule.itemList = data.data.itemList}// 为当前用户增加一个空的日程记录async function addItem(){let{data} = await request.get('schedule/addDefaultSchedule',{params:{"uid":sysUser.uid}})  if(data.code == 200){// 增加成功,刷新页面数据showSchedule()}else{alert("增加失败")}}async function updateItem(index){// 找到要修改的数据 发送给服务端,更新进入数据库即可let {data} =  await request.post("schedule/updateSchedule",schedule.itemList[index])   if(data.code == 200){showSchedule()alert("更新成功")}else{alert("更新失败")}}async function removeItem(index){let sid =schedule.itemList[index].sidlet {data} = await request.get(`schedule/removeSchedule`,{params:{"sid":sid}})if(data.code == 200){showSchedule()alert("删除成功")}else{alert("删除失败")}}</script><template><div><h3 class="ht">您的日程如下</h3>
<table class="tab" cellspacing="0px"><tr class="ltr"><th>编号</th><th>内容</th><th>进度</th><th>操作</th></tr><tr class="ltr" v-for="item,index in schedule.itemList" :key="index"><td v-text = "index+1"></td><td ><input type="text" v-model="item.title"></td><td ><input type="radio"  value="1" v-model="item.completed"> 已完成<input type="radio"  value="0" v-model="item.completed"> 未完成</td><td class="buttonContainer"><button class="btn1" @click="removeItem(index)">删除</button><button class="btn1" @click="updateItem(index)">保存修改</button></td></tr><tr class="ltr buttonContainer" ><td colspan="4"><button class="btn1" @click="addItem()">新增日程</button></td></tr>
</table></div>
</template><style scoped>.ht{text-align: center;color: cadetblue;font-family: 幼圆;}.tab{width: 80%;border: 5px solid cadetblue;margin: 0px auto;border-radius: 5px;font-family: 幼圆;}.ltr td{border: 1px solid  powderblue;}.ipt{border: 0px;width: 50%;}.btn1{border: 2px solid powderblue;border-radius: 4px;width:100px;background-color: antiquewhite;}#usernameMsg , #userPwdMsg {color: gold;}.buttonContainer{text-align: center;}</style>

3.5放入主组件 APP.vue

<script setup>import Header from './components/Header.vue'
</script><template><div><Header></Header><hr><router-view></router-view></div></template><style scoped>
</style>

项目实战一结束

项目实战二

项目结构

1.创建项目,导入所需依赖

这里照着dependencies里面的依赖下载就行

{"name": "my-vue3-vite-project","private": true,"version": "0.0.0","type": "module","scripts": {"dev": "vite","build": "vite build","preview": "vite preview"},"dependencies": {"axios": "^1.4.0","element-plus": "^2.2.5","less": "^4.1.3","less-loader": "^7.3.0","mitt": "^3.0.0","nprogress": "^0.2.0","pinia": "^2.0.14","vue": "^3.2.47","vue-router": "^4.1.6"},"devDependencies": {"@vitejs/plugin-vue": "^4.1.0","typescript": "^4.7.2","vite": "^4.3.2"}
}

2.定义依赖对象相关文件(.js)

2.1路由

index.js

import { createRouter, createWebHistory } from "vue-router";
import { staticRoutes } from "./routes";
import { useUserInfoStore } from '../stores/userInfo';
import pinia from '../stores';
import { getToken, removeToken } from '../utils/token-utils';
import { ElMessage } from 'element-plus';const router = createRouter({history: createWebHistory(),routes: staticRoutes,
});const userInfoStore = useUserInfoStore(pinia)//全局前置守卫
router.beforeEach(async (to, from, next) => {const token = getToken()const userInfo = !!userInfoStore.nickNameif (token) {if (to.path == "/login") {next({ path: "/" })} else {if (userInfo) {next()} else {try {await userInfoStore.getInfo()next()} catch (error) {removeToken()}}}} else {next()}
});// //使用全局后置钩子配置关闭进度条
// router.afterEach(() => {
//   NProgress.done();
// });// 导出路由
export default router;

router.js


export const staticRoutes = [{path: "/",redirect: "/headlinenews",},{// 头条path: "/headlinenews",component: () => import("../pages/HeadlineNews/index.vue"),name: "HeadlineNews",},{//头条详情path: "/detail",component: () => import("../pages/Detail/index.vue"),name: "Detail",},{// 登录path: "/login",component: () => import("../pages/Login/index.vue"),name: "Login",},{//注册path: "/register",component: () => import("../pages/Register/index.vue"),name: "Register",},{//发布新闻的页面path: "/addormodifynews",component: () => import("../pages/addOrModifyNews/index.vue"),name: "addOrModifyNews",},
];

2.2axios

import axios from "axios";
import { ElMessage } from 'element-plus';
import pinia from '../stores/index';
import { useUserInfoStore } from '../stores/userInfo';
import NProgress from "nprogress";
import "nprogress/nprogress.css";
// 配置新建一个 axios 实例
const service = axios.create({baseURL: "/app-dev/",timeout: 50000,
});// 添加请求拦截器
service.interceptors.request.use((config) => {NProgress.start()//开启进度条// 如果有token, 通过请求头携带给后台const userInfoStore = useUserInfoStore(pinia) // 如果不是在组件中调用,必须传入piniaconst token = userInfoStore.tokenif (token) {// config.headers['token'] = token  // 报错: headers对象并没有声明有token, 不能随便添加(config.headers)['token'] = token}return config;
});// 添加响应拦截器
service.interceptors.response.use((response) => {NProgress.done()//关闭进度条if(response.data.code !== 200){// 判断响应状态码if (response.data.code == 501)  return  Promise.reject(ElMessage.error("用户名有误"))else if (response.data.code == 503) return  Promise.reject(ElMessage.error("密码有误"))else if (response.data.code == 504) return  Promise.reject(ElMessage.error("登录已过期"))else if (response.data.code == 505) return  Promise.reject(ElMessage.error("用户名占用"))} else {return response.data.data; /* 返回成功响应数据中的data属性数据 */}},(error) => {NProgress.done()//关闭进度条return Promise.reject(error.message);}
);export default service;

2.3token

const TokenKey = 'vue_admin_template_token'export function getToken() {return localStorage.getItem(TokenKey)
}export function setToken(token: string) {localStorage.setItem(TokenKey, token)
}export function removeToken() {localStorage.removeItem(TokenKey)
}

2.4pinia

import { createPinia } from 'pinia';const pinia = createPinia();export default pinia;
2.4.1pinia存储

import { defineStore } from 'pinia';
import { getToken, removeToken, setToken } from '../utils/token-utils';
import { getLogin,getUserInfo } from '../api/index';/*** 用户信息* @methods setUserInfos 设置用户信息*/
export const useUserInfoStore = defineStore('userInfo', {state: () => ({token: getToken(),nickName: '',uid: '',}),actions: {// 登陆的异步actionasync login (loginForm) {// 发送登陆的请求const result = await getLogin(loginForm)// 请求成功后, 取出token保存  pinia和local中const token = result.tokenthis.token = tokensetToken(token)},async getInfo () {const result = await getUserInfo()this.nickName = result.loginUser.nickNamethis.uid = result.loginUser.uid},initUserInfo(){removeToken()this.nickName = ""this.uid = ""console.log('1111111111');}},});

2.5api

import request from "../utils/request/"// portal/findAllTypes
//获取分类列表
export const getfindAllTypes = () => {return request.get("portal/findAllTypes");
};
// 分页带条件查询所有头条
export const getfindNewsPageInfo = (info) => {return request.post("portal/findNewsPage",info);
};
// 查看头条详情
export const getshowHeadlineDetail = (id) => {return request({method: "post",url: "portal/showHeadlineDetail",headers: {"Content-Type": "application/x-www-form-urlencoded;charset=utf-8",},data:`hid=${id}`});
};//删除的回调
// headline/removeByHid
export const removeByHid = (id) => {return request({method: "post",url: "headline/removeByHid",headers: {"Content-Type": "application/x-www-form-urlencoded;charset=utf-8",},data:`hid=${id}`})
};//登录的接口
export const getLogin = (info) => {return request.post("user/login",info);
};
//获取用户信息的接口
export const getUserInfo = (info) => {return request.get("user/getUserInfo");
};//注册校验的接口  user/checkUserName
export const registerValidateApi = (username) => {return request({method: "post",url: "user/checkUserName",headers: {"Content-Type": "application/x-www-form-urlencoded;charset=utf-8",},data:`username=${username}`})
};// 注册的接口
export const registerApi = (userInfo) => {return request.post("user/regist",userInfo)
}
//判断用户登录过期的接口
export const isUserOverdue = () => {return request.get("user/checkLogin")
}// 修改头条回显的接口
export const getFindHeadlineByHid = (id) => {return request({method: "post",url: "headline/findHeadlineByHid",headers: {"Content-Type": "application/x-www-form-urlencoded;charset=utf-8",},data:`hid=${id}`});
};//点击保存修改的回调
// headline/update
export const saveOrAddNews = (news) => {return request.post("headline/update",news)
}// headline/publish
export const issueNews = (news) => {return request.post("headline/publish",news)
}

3组件

3.1头组件Header.vue

<template><div class="headerContainer"><!-- 头部左侧区域 --><div class="left"><ul><li @click="HighlightHandler(index,)"  v-for="(item,index) in findAllTypeList" :key="item.tid"><a :class="{ active: item.isHighlight }" href="javascript:;">{{item.tname}}</a></li></ul></div><!-- 头部右侧区域 --><div class="right"><div class="rightInput" style="margin-right: 50px;"><el-input v-model="keywords" placeholder="搜索最新头条"></el-input><!-- <el-button   type="primary">搜索</el-button> --></div><!-- 用户登录以后的展示 --><div class="btn-dropdown"><!-- 用户没有登录的时候的展示 --><div v-if="nickName" style="display: flex; justify-content: center; align-items: center;"><el-dropdown><el-button type="primary">您好:{{ nickName }}<el-icon class="el-icon--right"><arrow-down /></el-icon></el-button><template #dropdown><el-dropdown-menu><el-dropdown-item @click="handlerNews">发布新闻</el-dropdown-item><el-dropdown-item>个人中心</el-dropdown-item><el-dropdown-item>浏览记录</el-dropdown-item><el-dropdown-item @click="Logout">退出登录</el-dropdown-item></el-dropdown-menu></template></el-dropdown></div><div v-else class="containerButton"><el-button size="small" style="background: #212529; color: #aea7a2" @click="toLogin">登录</el-button><el-button size="small" style="background: #ffc107; color: #684802" @click="toRegister">注册</el-button></div></div></div></div>
</template><script>
import { defineComponent } from 'vue'
export default defineComponent({name: 'Header'
})
</script><script setup>
import { getfindAllTypes, isUserOverdue } from '../api/index'
import { ref, onMounted , getCurrentInstance ,watch, onUpdated} from "vue"
import { useRouter } from 'vue-router'
import { ArrowDown } from '@element-plus/icons-vue'
import { removeToken } from '../utils/token-utils' 
import pinia from '../stores/index';
import { useUserInfoStore } from '../stores/userInfo'
const userInfoStore = useUserInfoStore(pinia)
const nickName = ref("")
// 获取到 全局事件总线
const { Bus } = getCurrentInstance().appContext.config.globalProperties
const router = useRouter()
const keywords = ref("") // 收集搜索最新头条参数
//监视搜索参数的变化 ,当搜索参数变化的时候给HeadlineNews组件传递数据
watch(keywords, (newVal) => {Bus.emit('keyword', newVal)
})
const findAllTypeList = ref([])//所有头条分类
const toLogin = () => {
router.push({ name: "Login" });
}
//点击去注册页面
const toRegister = () => {router.push({ name: "Register" });
}
const getList = async () => {let result = await getfindAllTypes()// 遍历数据添加高亮标识result.forEach((item) => {item.tid = item.tiditem.tname = item.tnameitem.isHighlight = false})// 添加微头条数据result.unshift({isHighlight: true,tid: 0,tname: "微头条"})findAllTypeList.value = result
}
// 页面挂载的生命周期回调
onUpdated(() => {nickName.value = userInfoStore.nickName
})
onMounted(() => {getList()
})//点击切换高亮的回调(排他思想)
const HighlightHandler = (index) => {findAllTypeList.value.forEach((item) => {item.isHighlight = false})// 切换高亮的时候把tid传给HeadlineNews组件findAllTypeList.value[index].isHighlight = trueBus.emit('tid', findAllTypeList.value[index].tid)
}// 点击退出登录的回调
const Logout = () => {removeToken()userInfoStore.initUserInfo()nickName.value = ""router.go({ name: "HeadlineNews" });
}//点击发布新闻的回调
const handlerNews = async () => {//发送请求判断用户是否token过期await isUserOverdue()router.push({ name: "addOrModifyNews" });
}
</script><style>
.el-dropdown {vertical-align: top;width: 100px;
}.el-dropdown+.el-dropdown {margin-left: 15px;
}.el-icon-arrow-down {font-size: 12px;
}
</style><style lang="less" scoped>
.headerContainer {width: 100%;height: 60px;background: #212529;display: flex;justify-content: space-around;.left {ul {display: flex;li {list-style: none;margin-left: 20px;a:-webkit-any-link {text-decoration: none;color: #59646b;&.active {color: #c0adab;}}}}}.right {.containerButton {display: flex;align-items: center;}line-height: 60px;display: flex;flex-wrap: nowrap;.rightInput {display: flex;align-items: center;:deep(.el-input__inner) {height: 30px;width: 150px;}}.btn-dropdown{display: flex;align-items: center;}:deep(.el-button) {margin: 0 0 0 10px;display: flex;justify-content: center;align-items: center;}}
}.example-showcase .el-dropdown + .el-dropdown {margin-left: 15px;
}
.example-showcase .el-dropdown-link {cursor: pointer;color: var(--el-color-primary);display: flex;align-items: center;
}
</style>

3.2安装上面顺序第一个

<template><el-card class="box-card AddNewsContainer"><el-form :rules="newsRules" :model="formData" ref="formRef" size="default"><el-form-item label="文章标题" prop="title"><el-input v-model="formData.title" placeholder="请输入标题"></el-input></el-form-item><el-form-item style="margin: 50px 0;" label="文章内容" prop="article"><el-input v-model="formData.article" type="textarea" rows="8"></el-input></el-form-item><el-form-item label="文章内容"  prop="type"><el-select v-model="formData.type" placeholder="请选择文章类别"><el-option v-for="item in article" :label="item.name" :value="item.type"></el-option></el-select></el-form-item></el-form><el-form-item><el-button   @click="handlerCancel">取消</el-button><el-button type="primary"  @click="handlerSave">保存</el-button></el-form-item></el-card>
</template><script>
import { defineComponent } from 'vue'
import { isUserOverdue } from '../../api/index'
export default defineComponent({name: 'AddNews'
})
</script>
<script  setup>
import { getFindHeadlineByHid , saveOrAddNews, issueNews } from "../../api/index"
import { ref, onMounted } from "vue"
import { useRoute } from 'vue-router'
import { useRouter } from 'vue-router'
import { ElMessage } from 'element-plus'
const router = useRouter() 
const route = useRoute() const formRef = ref()
// 校验规则
const validateType = (rule, value, callback) => {if (value.length) {callback()} else {callback(new Error('文章标题是必须的'))}
}
// 校验规则
const validateArticle = (rule, value, callback) => {if (value.length) {callback()} else {callback(new Error('文章内容是必须的'))}
}
// 校验规则
const validateTitle = (rule, value, callback) => {if (value.length) {callback()} else {callback(new Error('文章类别是必须的'))
}
}
// 校验规则
const newsRules = {title: [{ required: true, trigger: 'blur', validator: validateTitle }],article: [{ required: true, trigger: 'blur', validator: validateArticle }],type: [{ required: true, validator: validateType }],
}const formData = ref({hid:null,title: "",   // 文章标题article: "", // 文章内容type: ""     // 文章类别
})
//初始化文章类别数据
const article = [{type: "1",name: "新闻"},{type: "2",name: "体育"},{type: "3",name: "娱乐"},{type: "4",name: "科技"},{type: "5",name: "其他"}
]
// 如果是点击修改的话 路由就会携带hid参数  就要发送请求 获取数据回显
const clickModifyEcho = async () => {if (!route.query.hid)  returnlet result = await getFindHeadlineByHid(route.query.hid)formData.value.title = result.headline.titleformData.value.article = result.headline.articleformData.value.type = result.headline.type === 1 ? "新闻" : result.headline.type === 2 ? "体育" : result.headline.type === 3 ? "娱乐" : result.headline.type === 4 ? "科技" : "其他" 
}
//页面挂载生命周期
onMounted(() => {clickModifyEcho()
})
//点击取消的回调
const handlerCancel = () => {router.back()
}
//点击保存的回调
const handlerSave = async () => {await formRef.value?.validate()//发送请求判断用户是否token过期await isUserOverdue()
const Obj = {...formData.value}//整理请求参数
//  Obj.hid = userInfoStore.uid.toString()  //添加用户id 让后端知道谁添加的Obj.hid = route.query.hid  //添加用户id 让后端知道谁添加的
// 判断type类型if(Obj.type == "新闻" ) Obj.type = "1"if(Obj.type == "体育" ) Obj.type = "2"if(Obj.type == "娱乐" ) Obj.type = "3"if(Obj.type == "科技" ) Obj.type = "4"if (Obj.type == "其他") Obj.type = "5"//发送请求if (route.query.hid) {await saveOrAddNews(Obj)ElMessage.success("修改成功")}else {await issueNews(formData.value)ElMessage.success("添加成功")}router.push({ name: "HeadlineNews" });
}</script><style lang="less" scoped>
.AddNewsContainer {width: 600px;margin: 150px auto;
}
</style>

3.3第二个

<template><div class="seeDetails"><div><h4>{{ detailList.title }}</h4></div><div style="margin-right: 250px"><span>{{ detailList.typeName }}</span><span>{{ detailList.pageViews }}浏览</span><span>{{ detailList.pastHours }}小时前</span></div><div style="width: 500px; margin: 20px 0px 0px 70px"><p>{{ detailList.article }}</p></div></div>
</template><script >import { defineComponent } from 'vue'export default  defineComponent({name:'Detail'})
</script>
<script  setup>
import { getshowHeadlineDetail } from "../../api/index"
import { ref , onMounted } from "vue"
import { useRoute } from 'vue-router'
const route = useRoute() // 路由信息对象const detailList = ref({}) //详情数据
//获取详情初始化数据
const getDetailList = async () => {let result = await getshowHeadlineDetail(route.query.hid)detailList.value = result.headline
}
// 页面初始化钩子
onMounted(() => {getDetailList()
})</script><style lang="less" scoped>
.seeDetails {width: 1200px;margin: 0 auto;display: flex;flex-direction: column;align-items: center;div {span {padding-right: 15px;font-size: 14px;color: #8d91aa;}p {font-size: 14px;color: #2b2e30;}}
}
</style>

3.4第三个

<template><div class="container"><div class="listItem"><!-- 每一项头条列表 --><div class="containerItem" v-for="item in pageData" :key="item.hid"><div><span class="text">{{ item.title }}</span></div><div class="detail"><span>{{ item.type == 1 ? "新闻":item.type == 2 ? "体育": item.type == 3 ? "娱乐": item.type == 4 ? "科技" : "其他" }}</span><span>{{item.pageViews}}浏览</span><span>{{item.pastHours}}小时前</span></div><div><el-button @click="toDetail(item.hid)" size="small"style="background: #198754; margin-left: 15px; color: #bbd3dc">查看全文</el-button><el-popconfirm v-if="item.publisher == type" @confirm="handlerDelete(item.hid)" :title="`您确定要删除${item.title}吗?`"><template #reference><el-button    size="small" style="background: #dc3545; color: #bbd3dc">删除</el-button></template></el-popconfirm><el-button @click="Modify(item.hid)" v-if="item.publisher == type"  size="small" style="background: #212529; color: #bbd3dc">修改</el-button></div></div><!-- 分页器 --><div style="margin-top: 20px"><el-pagination v-model:current-page="findNewsPageInfo.pageNum"v-model:page-size="findNewsPageInfo.pageSize" @size-change="getPageList"@current-change="getPageList":page-sizes="[5,7,10]" backgroundlayout="prev, pager, next , ->, sizes, total" :total="totalSize" /></div></div></div>
</template><script >
import { getfindNewsPageInfo , removeByHid } from "../../api/index"import { defineComponent } from 'vue'export default  defineComponent({name:'HeadlineNews'})
</script>
<script  setup>
import { ref, onMounted, getCurrentInstance, watch } from "vue"
import { useRouter } from 'vue-router'
import { ElMessage } from 'element-plus'
import pinia from '../../stores/index';
import { useUserInfoStore } from '../../stores/userInfo'
const  { Bus } = getCurrentInstance().appContext.config.globalProperties
const userInfoStore = useUserInfoStore(pinia)
const router = useRouter()
const type = userInfoStore.uid
const findNewsPageInfo = ref({keyWords: "", // 搜索标题关键字type: 0,           // 新闻类型pageNum: 1,        // 页码数pageSize: 5,     // 页大小}
)
const totalSize = ref(0) //分页总数量
// 初始化列表数据
const pageData = ref([{hid: null,pageViews: null,pastHours: null,publisher: null,title: "",type: null
}])//接收header组件用户搜索的数据
Bus.on('keyword', (keywords) => {findNewsPageInfo.value.keyWords = keywords
})
// header点击切换高亮的时候传递过来的tid
Bus.on('tid', (type) => {findNewsPageInfo.value.type = type
})
// 监视初始化参数type的变化,当type发生改变的时候重新发送请求获取列表数据
watch(() => findNewsPageInfo.value, () => {getPageList()
}, {deep: true,
})
// 初始化请求分页列表数据
const getPageList = async () => {let result = await getfindNewsPageInfo(findNewsPageInfo.value)pageData.value = result.pageInfo.pageDatafindNewsPageInfo.value.pageNum = result.pageInfo.pageNumfindNewsPageInfo.value.pageSize = result.pageInfo.pageSizetotalSize.value = +result.pageInfo.totalSize
}
// 组件挂载的生命周期钩子
onMounted(() => {getPageList()
})
// 点击查看全文的回调
const toDetail = (hid) => {router.push({ name: "Detail" ,query:{ hid }});
}// 点击删除的回调
const handlerDelete = async (id) => {await removeByHid(id)ElMessage.success('删除成功!')//重新获取列表请求getPageList()
}
//点击修改的回调
const Modify = (hid) => {router.push({ name: "addOrModifyNews", query: { hid } });
}
</script><style lang="less" scoped>
.container {width: 1200px;margin: 0 auto;display: flex;flex-direction: column;align-items: center;// 列表样式.listItem {.containerItem {margin-top: 20px;border-radius: 10px;border: 2px solid #ebebeb;width: 600px;height: 120px;div {margin-top: 10px;}.text {margin-left: 15px;color: #353a3f;}.detail {span {margin-left: 15px;color: #8b778a;font-size: 14px;}}}}
}
</style>

3.5第四个

<template><div class="login-container"><el-form:model="loginForm"ref="formRef"label-width="80px"class="login-form":rules="loginRules" ><h2>用户登录</h2><el-form-item label="用户名" prop="username"><el-inputv-model="loginForm.username"ref="username"name="username"autocomplete="off"placeholder="请输入用户名"></el-input></el-form-item><el-form-item label="密码" prop="userPwd"><el-inputtype="password"v-model="loginForm.userPwd"autocomplete="off"placeholder="请输入密码"></el-input></el-form-item><el-form-item><el-button type="success" @click.native.prevent="login">登录</el-button><el-button type="primary" @click="toRegister">注册</el-button></el-form-item></el-form></div>
</template><script lang="ts">import { defineComponent } from 'vue'export default  defineComponent({name:'Login'})
</script>
<script lang="ts" setup>
import { ref } from "vue"
import { useUserInfoStore } from '../../stores/userInfo';import type { FormInstance } from 'element-plus';
import { useRouter } from 'vue-router'
const userInfoStore = useUserInfoStore()
const router = useRouter()
const formRef = ref<FormInstance>()
const loading = ref(false)
//账号密码参数
const loginForm = ref({username: "zhangsan",userPwd: "123456",
})
// 校验规则
const validateUsername = (rule: any, value: any, callback: any) => {if (value.length < 4) {callback(new Error('用户名长度不能小于4位'))} else {callback()}
}
// 校验规则
const validatePassword = (rule: any, value: any, callback: any) => {if (value.length < 6) {callback(new Error('密码长度不能小于6位'))} else {callback()}
}
// 校验规则
const loginRules = {username: [{ required: true, validator: validateUsername }],userPwd: [{ required: true, trigger: 'blur', validator: validatePassword }]
}
//点击登录的回调
const login = async () => {// console.log('点击登录');await formRef.value?.validate()loading.value = truetry {// await getUserInfo(loginForm.value)await userInfoStore.login(loginForm.value)router.push({ name: "HeadlineNews" });} finally {loading.value = false}// loading.value = true// const { username, userPwd } = loginForm.value// try {//   await userInfoStore.login(username, userPwd)//   router.push({ path: redirect.value || '/' })// } finally {//   loading.value = false// }
}const toRegister = ()=> {router.push({ name: "Register" });
}
</script><style scoped>
.login-container {display: flex;justify-content: center;align-items: center;height: 100vh;
}
.login-form {width: 400px;text-align: center;
}
</style>

3.6第五个

<template><div class="register-container"><el-form:model="registerForm"ref="formRef"label-width="80px"class="register-form":rules="registerRules"><h2>用户注册</h2><el-form-item label="姓名" prop="nickName"><el-inputv-model="registerForm.nickName"autocomplete="off"ref="nickName"name="nickName"placeholder="请输入姓名"></el-input></el-form-item><el-form-item label="用户名" prop="username"><el-inputv-model="registerForm.username"autocomplete="off"ref="username"name="username"placeholder="请输入用户名"></el-input></el-form-item><el-form-item label="密码" prop="userPwd"><el-inputtype="password"v-model="registerForm.userPwd"ref="userPwd"name="userPwd"autocomplete="off"placeholder="请输入密码"></el-input></el-form-item><!-- prop="confirmPassword" --><el-form-item label="确认密码"  prop="confirmPassword"><el-inputtype="password"v-model="registerForm.confirmPassword"autocomplete="off"ref="confirmPassword"name="confirmPassword"placeholder="请确认密码"></el-input></el-form-item><el-form-item><el-button type="primary" @click="register">注册</el-button><el-button type="danger" @click="resetForm">重置</el-button><el-button type="success" @click="goLogin">去登录</el-button></el-form-item></el-form></div>
</template><script lang="ts">import { defineComponent } from 'vue'export default  defineComponent({name:'Register'})
</script>
<script lang="ts" setup>
import { ref } from "vue"
import { useRouter } from 'vue-router'
import { ElMessage, FormInstance } from 'element-plus';
import { registerValidateApi, registerApi } from "../../api/index"
const router = useRouter()
// 初始化注册参数
const registerForm = ref({username: "",userPwd: "",confirmPassword: "",nickName:''
})
const formRef = ref<FormInstance>()// 校验规则
const validateUsername = (rule: any, value: any, callback: any) => {if (value.length < 4) {callback(new Error('用户名长度不能小于4位'))} else {callback()}
}
// 校验规则
const validatePassword = (rule: any, value: any, callback: any) => {if (value.length < 6) {callback(new Error('密码长度不能小于6位'))} else {callback()}
}
// 校验规则
const validateConfirmPassword = (rule: any, value: any, callback: any) => {if (value.length < 6) {callback(new Error('密码长度不能小于6位'))} else {callback()}
}
// 校验规则
const validateNickName = (rule: any, value: any, callback: any) => {if (value.length >= 2  && value.length  <= 6  ) {callback()} else {callback(new Error('姓名必须在2-6位'))
}
}
// 校验规则
const registerRules = {nickName: [{ required: true, trigger: 'blur', validator: validateNickName }],username: [{ required: true, validator: validateUsername }],userPwd: [{ required: true, trigger: 'blur', validator: validatePassword }],confirmPassword: [{ required: true, trigger: 'blur', validator: validateConfirmPassword }]
}//点击注册的回调
const register = async () => {await formRef.value?.validate()if (registerForm.value.userPwd == registerForm.value.confirmPassword) {// 调用用户名校验接口await registerValidateApi(registerForm.value.username)//  整理参数const obj = {username: "",userPwd: "",nickName: ''}obj.username = registerForm.value.usernameobj.userPwd = registerForm.value.userPwdobj.nickName = registerForm.value.nickName//  调用注册接口await registerApi(obj)formRef.value?.resetFields()ElMessage.success("注册成功")} else {return ElMessage.error("密码和确定密码必须一致")}}
//点击去登录的回调
const goLogin = () => {router.push({path:"/login"})
}//点击重置的回调
const resetForm = () => {//重置表单formRef.value?.resetFields()
}</script><style scoped>
.register-container {display: flex;justify-content: center;align-items: center;height: 100vh;
}
.register-form {width: 400px;text-align: center;
}
</style>

3.7一起加入主题组件App.vue

<template><div ><Header v-show="isHeader"></Header><router-view></router-view></div>
</template><script >
import Header from './components/Header.vue'import { defineComponent } from 'vue'export default  defineComponent({name:'App'})
</script>
<script  setup>
import { computed } from "vue"
import { useRoute } from 'vue-router'
const route = useRoute() // 路由信息对象
// 判断是否显示header组件const isHeader =  computed(() => {return route.name !== "Login" && route.name !== "Register" && route.name !== "addNews";
})</script><style lang="less" scoped></style>

项目实战二结束

相关文章:

JAVAWeb实战(前端篇)

项目实战一 0.项目结构 1.创建vue3项目&#xff0c;并导入所需的依赖 npm install vue-router npm install axios npm install pinia npm install vue 2.定义路由&#xff0c;axios&#xff0c;pinia相关的对象 文件&#xff08;.js&#xff09; 2.1路由(.js) import {cre…...

axios请求大全

本文讲解axios封装方式以及针对各种后台接口的请求方式 axios的介绍和基础配置可以看这个文档: 起步 | Axios中文文档 | Axios中文网 axios的封装 axios封装的重点有三个&#xff0c;一是设置全局config,比如请求的基础路径&#xff0c;超时时间等&#xff0c;第二点是在每次…...

C# 简单的单元测试

文章目录 前言参考文档新建控制台项目新建测试项目添加引用添加测试方法测试结果(有错误)测试结果&#xff0c;通过正规的方法抛出异常 总结 前言 听说复杂的项目最好都要单元测试一下。我这里也试试单元测试这个功能。到时候调试起来也方便。 参考文档 C# 单元测试&#xf…...

Linux中Mysql5.7主从架构(一主多从)配置教程

&#x1f3e1;作者主页&#xff1a;点击&#xff01; &#x1f427;Linux基础知识(初学)&#xff1a;点击&#xff01; &#x1f427;Linux高级管理防护和群集专栏&#xff1a;点击&#xff01; &#x1f510;Linux中firewalld防火墙&#xff1a;点击&#xff01; ⏰️创作…...

BACnet物联网关BL103:Modbus协议转BACnet/MSTP

随着物联网技术在楼宇自动化与暖通控制系统中的迅猛发展&#xff0c;构建一种既经济高效又高度可靠的协议转换物联网关成为了不可或缺的核心硬件组件。在此背景下&#xff0c;我们钡铼特别推荐一款主流的BAS&#xff08;楼宇自动化系统&#xff09;与BACnet物联网关——BL103&a…...

Go 语言条件变量 Cond

1.Cond 的使用方法 Go 标准库提供 Cond 同步原语的目的是为等待/通知场景下的并发操作提供支持。Cond 通常用于等待某个条件的一组 goroutine,当条件变为 true 时,其中一个或者所有的 goroutine 会被唤醒执行。 Cond 与某个条件相关,这个条件需要一组 goroutine 协作达到。当这…...

PostgreSQL 中如何重置序列值:将自增 ID 设定为特定值开始

我是从excel中将数据导入&#xff0c;然后再通过sql插入数据&#xff0c;就报错。 需要设置自增ID开始值 1、确定序列名称&#xff1a; 首先&#xff0c;需要找到与的增字段相关的序列名称。假设表名是 my_table 和自增字段是 id&#xff0c;可以使用以下查询来获取序列名称…...

Unity 之 【Android Unity 共享纹理】之 Android 共享图片给 Unity 显示

Unity 之 【Android Unity 共享纹理】之 Android 共享图片给 Unity 显示 目录 Unity 之 【Android Unity 共享纹理】之 Android 共享图片给 Unity 显示 一、简单介绍 二、共享纹理 1、共享纹理的原理 2、共享纹理涉及到的关键知识点 3、什么可以实现共享 不能实现共享…...

Go语言的数据结构

数据结构 数组 支持多维数组&#xff0c;属于值类型&#xff0c;支持range遍历 例子&#xff1a;随机生成长度为10整数数组 package main import ("fmt""math/rand" ) // 赋值 随机获取100以内的整数 func RandomArrays() {var array [10]int //声明var…...

python_在sqlite中创建表并写入表头

python_在sqlite中创建表并写入表头 import sqlite3def write_title_to_sqlite(tableName,titleList,dataTypeGroupsList,database_path):conn sqlite3.connect(database_path)# 创建游标cursor conn.cursor()#MEMO 长文本#create_table_bodycreate_table_body "序号 …...

1.c#(winform)编程环境安装

目录 安装vs创建应用帮助查看器安装与使用&#xff08; msdn&#xff09; 安装vs 安装什么版本看个人心情&#xff0c;或者公司开发需求需要 而本栏全程使用vs2022进行开发c#&#xff0c;着重讲解winform桌面应用开发 使用***.net framework***开发 那先去官网安装企业版的vs…...

图中的最短环

2608. 图中的最短环 现有一个含 n 个顶点的 双向 图&#xff0c;每个顶点按从 0 到 n - 1 标记。图中的边由二维整数数组 edges 表示&#xff0c;其中 edges[i] [ui, vi] 表示顶点 ui 和 vi 之间存在一条边。每对顶点最多通过一条边连接&#xff0c;并且不存在与自身相连的顶…...

安装依赖 npm install idealTree:lib: sill idealTree buildDeps 卡着不动

我一直怀疑是网络问题&#xff0c;因为等了很久也能安装成功&#xff0c;就是时间比较长&#xff0c;直到现在完全受不了了&#xff0c;决定好好整治下这个问题&#xff01; 1、执行命令 npm config get userconfig 查看配置文件所在位置&#xff0c;将其删除。 2、执行 n…...

LLMs之Llama 3.1:Llama 3.1的简介、安装和使用方法、案例应用之详细攻略

LLMs之Llama 3.1&#xff1a;Llama 3.1的简介、安装和使用方法、案例应用之详细攻略 导读&#xff1a;2024年7月23日&#xff0c;Meta重磅推出Llama 3.1。本篇文章主要提到了Meta推出的Llama 3.1自然语言生成模型。 背景和痛点 >> 过去开源的大型语言模型在能力和性能上一…...

如何实现一个大模型在回答问题时同时提供相关内容链接

通义生成 为了让大模型在回答问题时能够提供相关内容链接&#xff0c;通常采用的方法是结合检索增强生成&#xff08;Retrieval-Augmented Generation, RAG&#xff09;的技术。这种方法可以让大模型在生成答案的同时&#xff0c;从外部知识源中检索相关信息&#xff0c;并将这…...

<数据集>玉米地杂草识别数据集<目标检测>

数据集格式&#xff1a;VOCYOLO格式 图片数量&#xff1a;9900张 标注数量(xml文件个数)&#xff1a;9900 标注数量(txt文件个数)&#xff1a;9900 标注类别数&#xff1a;2 标注类别名称&#xff1a;[Maize, Weed] 序号类别名称图片数框数1Maize8439125142Weed959231048…...

vue3中动态添加form表单校验

<template><div><div v-for"(formData, index) in forms" :key"index"><u-form :model"formData" :rules"rules" ref"formRefs"><u-form-item label"用户名" prop"username"…...

Java面试八股之什么是声明式事务管理,spring怎么实现声明式事务管理?

什么是声明式事务管理&#xff0c;spring怎么实现声明式事务管理&#xff1f; 声明式事务管理是一种编程范式&#xff0c;它允许开发人员通过声明性的配置或注解&#xff0c;而不是硬编码事务处理逻辑&#xff0c;来指定哪些方法或类应该在其上下文中执行事务。这种方法将事务…...

springboot 缓存预热的几种方案

缓存预热是指在 Spring Boot 项目启动时&#xff0c;预先将数据加载到缓存系统&#xff08;如 Redis&#xff09;中的一种机制。 这里我给大家总结几个缓存预热的方案。 方案1&#xff1a;使用启动监听事件实现缓存预热 可以使用 ApplicationListener 监听 ContextRefreshed…...

谷粒商城实战笔记-62-商品服务-API-品牌管理-OSS整合测试

文章目录 一&#xff0c;Java中上传文件到阿里云OSS1&#xff0c;整合阿里云OSS2&#xff0c;测试上传文件 二&#xff0c;Java中整合阿里云OSS服务指南引言准备工作1. 注册阿里云账号2. 获取Access Key3. 添加依赖 实现OSS客户端1. 初始化OSSClient2. 创建Bucket3. 上传文件4.…...

linux c 递归锁的介绍

递归锁的递归特性确实只是对于持有锁的线程。当一个线程获取了递归锁后&#xff0c;它可以多次重复获取该锁&#xff0c;而不会导致自身阻塞或死锁。这是递归锁的重要特点&#xff0c;它允许同一个线程在已经持有锁的情况下&#xff0c;再次获取相同的锁。 然而&#xff0c;对…...

React好用的组件库有哪些

React好用的组件库有很多&#xff0c;它们各自具有不同的特点和优势&#xff0c;适用于不同的开发场景和需求。以下是一些受欢迎的React组件库及其特点&#xff1a; Material-UI&#xff08;现更名为MUI&#xff09; 特点&#xff1a;这是一个开源的React组件库&#xff0c;实…...

简单快捷!Yarn的安装与使用指南

Yarn 是由 Facebook (现 Meta) 开发的包管理工具。 今天&#xff0c;我将介绍如何使用 Yarn。 目录 Yarn 的官方网站 关于安装 版本确认 开始一个新项目&#xff08;创建 package.json 文件&#xff09; 安装软件包 升级包 运行脚本 执行包的命令 卸载包 总结 Yarn 的…...

【Django】前端技术-网页样式表CSS

文章目录 一、申明规则CSS的导入方式行内样式内部样式外部样式 二、CSS的选择器1. 基本选择器标签选择器&#xff1a; 选择一类标签 标签{}类选择器 class&#xff1a; 选择所有class属性一致的表情&#xff0c;跨标签.类名{}ID选择器&#xff1a;全局唯一 #id名{} 2.层次选择器…...

openssl req 详解

一、openssl req 该命令用于创建和处理PKCS#10格式的证书请求&#xff08;certificate requests CSRs&#xff09;&#xff0c;也可以用来创建自签名证书&#xff08; self-signed certificates&#xff09;来当作根证书&#xff08;root CAs&#xff09;使用 -new 该选项用来…...

mysql各种锁总结

mysql全局锁 读锁&#xff08;共享锁&#xff09; 阻止其他用户更新&#xff0c;但允许他们读取数据。 写锁&#xff08;排他锁&#xff09; 阻止其他用户读取和更新数据。 全局锁场景&#xff1a;进行数据库备份 数据库备份 背景&#xff1a;备份数据肯定要保证数据一致…...

SpringSecurity--DelegatingFilterProxy工作流程

什么是 DelegatingFilterProxy&#xff1f; DelegatingFilterProxy 是 Spring 提供的一个特殊的过滤器&#xff0c;它起到了桥梁的作用&#xff0c;可以让你在 Spring 容器中管理 Servlet 容器中的过滤器。 为什么需要 DelegatingFilterProxy&#xff1f; 通常情况下&#x…...

GitHub每日最火火火项目(7.27)

1. 项目名称&#xff1a;meta - llama / llama3 项目介绍&#xff1a;这是 Meta Llama 3 的官方 GitHub 站点。目前尚不清楚该项目的具体功能和特点&#xff0c;但从名称推测&#xff0c;可能与 Llama 3 模型相关&#xff0c;或许涉及到模型的开发、训练或应用等方面。 项目地…...

git 学习总结

文章目录 一、 git 基础操作1、工作区2、暂存区3、本地仓库4、远程仓库 二、git 的本质三、分支git 命令总结 作者: baron 一、 git 基础操作 如图所示 git 总共有几个区域 工作区, 暂存区, 本地仓库, 远程仓库. 1、工作区 存放项目代码的地方&#xff0c;他有两种状态 Unm…...

《如何找到自己想做的事》

Arouse Enthusiasm, Give Scope to Skill, Explore The Essence *摘其两纸 我喜欢打篮球&#xff0c;并不是我真的喜欢这项运动&#xff0c;而是我喜欢团队竞技。我喜欢看书&#xff0c;并不是我真喜欢阅读&#xff0c;而是我想要了解世界运行逻辑。寻找热爱&#xff0c;探寻本…...

Vue中el的两种写法

大家好我是前端寄术区博主PleaSure乐事。今天了解到了Vue当中有关el的两种写法&#xff0c;记录下来与大家分享&#xff0c;希望对大家有所帮助。 方法一 解释 第一种方法我们直接用new创建并初始化一个新的 Vue 实例&#xff0c;并定义了 Vue 实例的数据对象&#xff0c;在给…...

ELK安装(Elasticsearch+Logstash+Kibana+Filebeat)

一、简介 1.1、软件简介 ELK其实是Elasticsearch&#xff0c;Logstash 和 Kibana三个产品的首字母缩写&#xff0c;这三款都是开源产品。 1.1.1、Elasticsearch简介 Elasticsearch 是一个分布式、高扩展、高实时的搜索与数据分析引擎。它能很方便的使大量数据具有搜索、分析…...

VScode使用Github Copilot插件时出现read ECONNREST问题的解决方法

文章目录 read ECONNREST查看是否仍是 Copilot 会员查看控制台输出网络连接问题浏览器设置问题笔者的话 read ECONNREST 最近使用 Copilot 时一直出现 read ECONNREST 问题&#xff0c;这个表示连接被对方重置了&#xff0c;就是说在读取数据时连接被关闭。 我首先怀疑是不是…...

充电桩浪涌保护方案—保障充电设施安全稳定运行的关键

在当今新能源汽车蓬勃发展的时代&#xff0c;充电桩作为电动汽车的“加油站”&#xff0c;其重要性不言而喻。然而&#xff0c;由于其复杂的电气环境和暴露于户外的特点&#xff0c;充电桩容易受到浪涌的影响。浪涌可能来自雷电、电网故障、大功率设备的启停等&#xff0c;对充…...

Python包管理工具pip

1、安装pip cmd管理员模式打开控制台 python -m pip install --upgrade pip 2、添加pip环境变量 pip 路径 C:\Users\1\AppData\Local\Programs\Python\Python312\Scripts...

最全国内13家DNS分享 解决网页被恶意跳转或无法打开问题

腾讯 DNS (DNSPod) 腾讯 DNS 是由 DNSPod 提供的公共免费 DNS 服务。DNSPod 已被腾讯收购&#xff0c;现在属于腾讯公司所有。该 DNS 服务稳定性和连通性良好&#xff0c;经测试在海外也可以使用。 DNSPod 提供了 IPv4、IPv6 DNS 和 DoT/DoH 服务。 IPv4 地址: 119.29.29.29…...

最新站长工具箱源码,拥有几百个功能,安装教程

最新站长工具箱源码&#xff0c;拥有几百个功能&#xff0c;安装教程 在 Docker 上运行 docker run -e LAFREGIONCN -e APPLANGzh_CN --name my-miaoda -v ~/.miaoda-docker:/root/.miaoda -d -p 0.0.0.0:39899:39899 codegentoolbox/laftools-linux-x64:latestNOTE: 默认端…...

【算法/训练】:动态规划(线性DP)

一、路径类 1. 字母收集 思路&#xff1a; 1、预处理 对输入的字符矩阵我们按照要求将其转换为数字分数&#xff0c;由于只能往下和往右走&#xff0c;因此走到&#xff08;i&#xff0c;j&#xff09;的位置要就是从&#xff08;i - 1&#xff0c; j&#xff09;往下走&#…...

计算巨头 Azure、AWS 和 GCP 的比较

云计算领域由三大主要参与者主导&#xff1a;Microsoft Azure、Amazon Web Services (AWS) 和 Google Cloud Platform (GCP)。每个平台都为希望利用云提供基础设施、平台服务等的企业提供强大的功能。在本文中&#xff0c;我们将深入探讨这些平台之间的差异&#xff0c;重点关注…...

Thinkphp5跨域问题常见的处理方法

在ThinkPHP5中&#xff0c;处理跨域问题通常涉及配置中间件或直接在控制器中设置响应头。以下是几种常见的解决跨域问题的方法&#xff1a; 1. 使用中间件处理跨域 你可以创建一个中间件来专门处理跨域请求。这个中间件会检查请求的来源&#xff0c;并设置相应的响应头来允许…...

Matlab编程资源库(9)数据插值与曲线拟合

一、一维数据插值 在MATLAB中&#xff0c;实现这些插值的函数是interp1&#xff0c;其调用格式为&#xff1a; Y1interp1(X,Y,X1,method) 函数根据X,Y的值&#xff0c;计算函数在X1处的值。X,Y是两个等长的已知向量&#xff0c;分别描述采样点和样本值&#xff0c;X1是一个向量…...

matplotlib的科研绘图辅助

matplotlib的科研绘图辅助 趁着暑假&#xff0c;与和鲸科技合作了一个python绘图的教程&#xff0c;作为暑期夏令营的一小部分&#xff0c;主要内容是介绍如何使用matplotlib、pandas、seaborn和plotnine进行医学科研绘图&#xff0c;感兴趣的可以通过如下地址进行访问&#x…...

C++内存管理(候捷)第五讲 笔记

GNU C对allocators的描述 new_allocator 和malloc_allocator&#xff0c;它们都没有特别的动作&#xff0c;无非底部调用operator new和malloc。它们没有用内存池 区别&#xff1a;::operator new是可重载的 智能型的allocator&#xff0c;使用内存池&#xff0c;分一大块然后…...

谷粒商城实战笔记-63-商品服务-API-品牌管理-OSS获取服务端签名

文章目录 一&#xff0c;创建第三方服务模块thrid-party1&#xff0c;创建一个名为gulimall-third-party的模块2&#xff0c;nacos上创建third-party命名空间&#xff0c;用来管理这个服务的所有配置3&#xff0c;配置pom文件4&#xff0c;配置文件5&#xff0c;单元测试6&…...

详细介绍BIO、NIO、IO多路复用(select、poll、epoll)

BIO、NIO、IO多路复用 BIO(Blocking IO)NIO(Non-blocking IO) 同步非阻塞IOIO多路复用selectpollepoll Redis的IO多路复用 BIO(Blocking IO) 最基础的IO模型&#xff0c;当进行IO操作时&#xff0c;线程会被阻塞&#xff0c;直到操作完成。 比如read和write&#xff0c;通常IO…...

昇思25天学习打卡营第11天|xiaoyushao

今天分享ResNet50迁移学习。 在实际应用场景中&#xff0c;由于训练数据集不足&#xff0c;所以很少有人会从头开始训练整个网络。普遍的做法是&#xff0c;在一个非常大的基础数据集上训练得到一个预训练模型&#xff0c;然后使用该模型来初始化网络的权重参数或作为固定特征提…...

为什么样本方差(sample variance)的分母是 n-1?

样本均值与样本方差的定义 首先来看一下均值&#xff0c;方差&#xff0c;样本均值与样本方差的定义 总体均值的定义&#xff1a; μ 1 n ∑ i 1 n X i \mu\frac{1}{n}\sum_{i1}^{n} X_i μn1​i1∑n​Xi​ 也就是将总体中所有的样本值加总除以个数&#xff0c;也可以叫做总…...

编解码器架构

一、定义 0、机器翻译是序列转换模型的一个核心问题&#xff0c; 其输入和输出都是长度可变的序列。 为了处理这种类型的输入和输出&#xff0c; 我们设计一个包含两个主要组件的架构&#xff1a; 第一个组件是一个编码器&#xff08;encoder&#xff09;&#xff1a; 它接受一…...

追问试面试系列:JVM运行时数据区

hi 欢迎来到追问试面试系列之JVM运行时数据区,在面试中出现频率非常高,并且其中还存在一些误导性的面试,一定要注意。 什么误导性呢?面试中,有的面试官本来是想问JVM运行时数据区,不过提问时难免有些让你觉得很不爽。比如:你说说java内存模型,还比如说说JVM内存模型,…...

React Native在移动端落地实践

在移动互联网产品迅猛发展的今天&#xff0c;技术的不断创新使得企业越来越注重降低成本、提升效率。为了在有限的开发资源下迅速推出高质量、用户体验好的产品&#xff0c;以实现公司发展&#xff0c;业界催生了许多移动端跨平台解决方案。这些方案不仅简化了开发流程&#xf…...