vue3+vite+vant4手機端項目實戰(zhàn)記錄
一、項目介紹
一款在線招聘App,有四個模塊分別為登錄注冊模塊、用戶端模塊、企業(yè)端模塊、管理員模塊
二、項目的搭建
1.vite的安裝
# npm 6.x npm init vite@latest my-vue-app --template vue # npm 7+, 需要額外的雙橫線: npm init vite@latest my-vue-app -- --template vue
2.啟動vite項目
指令:npm run dev
3.vant4的引入與使用
vant4是輕量、可定制的移動端 Vue 組件庫
3.1安裝指令
npm i vant
3.2引入vant4
main.js
import { createApp } from 'vue' import './style.css' import App from './App.vue' import vant from 'vant'; import { Icon } from 'vant'; import 'vant/lib/index.css'; // 導入router配置文件 import router from "./router" // 導入阿里圖標 import './assets/font/iconfont.css' // 導入vuex import store from './store' createApp(App).use(router).use(vant).use(Icon).use(store).mount('#app')
4.路由router的引入
4.1安裝指令
npm install vue-router@4
4.2路由配置
router/index.js
//1. 導入vue-router相關(guān)函數(shù) import { createRouter, createWebHashHistory } from "vue-router" // 2.路由規(guī)則 const routes = [ { path:"路由地址", name:"路由名稱", component:組件名稱 } ] // 3.路由對象實例化 const router = createRouter({ history: createWebHashHistory(), routes }) // 暴露導出 export default router
main.js
import { createApp } from 'vue' import './style.css' import App from './App.vue' import vant from 'vant'; import { Icon } from 'vant'; import 'vant/lib/index.css'; // 導入router配置文件 import router from "./router" // 導入阿里圖標 import './assets/font/iconfont.css' // 導入vuex import store from './store' createApp(App).use(router).use(vant).use(Icon).use(store).mount('#app')
5.路徑別名設(shè)置
vite.config.js 文件
import vue from '@vitejs/plugin-vue' import { defineConfig } from 'vite' import WindiCSS from 'vite-plugin-windicss' // 1.導入node的path路徑模塊 import path from "path" // https://vitejs.dev/config/ export default defineConfig({ resolve: { alias: { // 配置別名 "~": path.resolve(__dirname, "src") } } })
6.json-server
6.1json-server安裝
npm install json-server
6.2json-server啟動項配置
在src的同級目錄先創(chuàng)建文件夾mock,并創(chuàng)建mock/db.json文件,添加數(shù)據(jù)
{ "infomation": [ { "id": 1, "title": "json-server 的第1條數(shù)據(jù)", "desc": "奧特曼不想打小怪獸,明明可以做好朋友的", "author": "被奧特曼打了很久的怪獸" }, { "id": 2, "title": "json-server 的第2條數(shù)據(jù)", "desc": "葫蘆娃不想去救爺爺,一個一個的去送不好", "author": "種出七個葫蘆的爺爺" }, { "id": 1, "title": "json-server 的第一條數(shù)據(jù)", "desc": "王者榮耀其實不是很好玩,這并不是我內(nèi)心的真話", "author": "想玩游戲的我" } ], "infomation2": [ { "id": 11, "title": "json-server 的第11條數(shù)據(jù)", "desc": "奧特曼不想打小怪獸,明明可以做好朋友的", "author": "被奧特曼打了很久的怪獸" }, { "id": 12, "title": "json-server 的第12條數(shù)據(jù)", "desc": "葫蘆娃不想去救爺爺,一個一個的去送不好", "author": "種出七個葫蘆的爺爺" }, { "id": 12, "title": "json-server 的第13條數(shù)據(jù)", "desc": "王者榮耀其實不是很好玩,這并不是我內(nèi)心的真話", "author": "想玩游戲的我" } ] }
(舉例數(shù)據(jù))
6.3啟動命令
npm run mock
7.axios請求數(shù)據(jù)
7.1安裝axios依賴
npm install axios
7.2簡單封裝axios
在src文件在下創(chuàng)建utils文件夾,在utils里創(chuàng)建 http.js文件
//引入安裝好的axios插件 import axios from "axios"; // 查詢數(shù)據(jù) const get = (url) => { return axios.get(url); }; // 添加數(shù)據(jù) const post = (url, data) => { return axios.post(url, data); }; // 修改數(shù)據(jù) const put = (url, data) => { return axios.put(url, data); }; // 局部修改 const patch = (url, data) => { return axios.patch(url, data); }; // 刪除數(shù)據(jù) const del = (url) => { return axios.delete(url); }; //將二次封裝好的axios導出 export { get, post, put, del, patch };
7.3項目使用axios
項目的端口為8080,然后json文件的端口為3000,這樣就會涉及到跨域,解決跨域的方式很多種,此處講解一下配置proxy代理 在根目錄下創(chuàng)建文件vue.config.js,覆蓋webpack的一些內(nèi)容。
vite.config.js
server: { proxy: { '/api': { target: 'http://localhost:3000', changeOrigin: true, rewrite: (path) => path.replace(/^\/api/, '') } } }
三、登錄注冊模塊
1.登錄頁面
代碼:
<template> <van-nav-bar title="登錄" left-text="返回" left-arrow @click-left="onClickLeft" /> <div class="login"> <img :src="img" alt="" /> <van-form @submit="onSubmit"> <van-cell-group inset> <van-field v-model="username" left-icon="phone-o" name="username" placeholder="手機號碼" :rules="[{ required: true, message: '請?zhí)顚懹脩裘? }]" /> <van-field v-model="password" left-icon="manager-o" type="password" name="password" placeholder="密碼" :rules="[{ required: true, message: '請?zhí)顚懨艽a' }]" /> </van-cell-group> <div style="margin: 16px"> <van-button round block type="primary" native-type="submit"> 提交 </van-button> </div> </van-form> </div> <div class="find"> <router-link to="/enroll"><span>注冊新用戶</span></router-link> <router-link to="/verify"><span>找回密碼</span></router-link> </div> <div class="ways"> <span>其他登錄方式</span> <div> <span class="iconfont"></span> <span class="iconfont"></span> <span class="iconfont"></span> </div> </div> </template> <!-- 邏輯層 --> <script setup> import { reactive, ref } from "vue"; import { get, post, put, del } from "~/axios/http"; import { showDialog } from "vant"; // 本地圖片引入 import img from "../../assets/images/avatar.svg"; // 導入useRouter方法 import { useRouter } from "vue-router"; const router = useRouter(); // 返回上一頁 const onClickLeft = () => { router.go(-1); }; // 表單 const username = ref(""); const password = ref(""); //點擊登錄按鈕事件 async function onSubmit(values) { console.log(values); //axios調(diào)用json-server數(shù)據(jù) let res = await get("/api/infomation"); //foreach循環(huán)判斷填入的手機號和密碼是否正確 res.data.forEach((element) => { if ( element.iphone == values.username && element.password == values.password ) { //本地存儲數(shù)據(jù)的id值 localStorage.setItem("key", JSON.stringify(element.id)); router.push("/start"); throw new Error(); } else { username.value = ""; password.value = ""; } }); } </script> <!-- 樣式層 --> <style scoped> .login { width: 100%; margin-top: 22.6667vw; } .login img { margin-left: 50vw; transform: translate(-50%, 0); } .find { display: flex; width: 70%; margin: 0 auto; justify-content: space-between; } .find span { color: #0079fe; } .ways { width: 80%; margin: 7.6667vw auto; text-align: center; } .ways > span { display: block; margin-bottom: 5.3333vw; color: #999999; } .ways div { display: flex; width: 80%; margin: 0 auto; justify-content: space-around; } .ways div span { font-size: 8.3333vw; } </style>
效果圖:
登錄模塊靜態(tài)頁面主要使用vant4組件庫中的組件,主要實現(xiàn)了通過vant表單的數(shù)據(jù)提交和axios方法獲取本地數(shù)據(jù)來判斷手機號與密碼是否正確。同時成功就通過路由跳轉(zhuǎn)
2.注冊頁面
代碼:
<!-- * @Author: wu07 1732042133@qq.com * @Date: 2023-01-12 10:03:12 * @LastEditors: wu07 1732042133@qq.com * @LastEditTime: 2023-02-03 14:08:54 * @FilePath: \recruitAPP\recruitApp\recruitApp\src\pages\login\Login.vue * @Description: 這是默認設(shè)置,請設(shè)置`customMade`, 打開koroFileHeader查看配置 進行設(shè)置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE --> <!-- 視圖層 --> <template> <van-nav-bar title="注冊" left-text="返回" left-arrow @click-left="onClickLeft" /> <div class="login"> <img :src="img" alt="" /> <van-form @submit="onSubmit"> <van-cell-group inset> <van-field v-model="username" left-icon="phone-o" name="username" placeholder="請輸入手機號碼" :rules="[{ required: true, message: '請?zhí)顚懯謾C號碼' }]" /> <van-field v-model="captcha" center left-icon="sign" name="captcha" placeholder="請輸入驗證碼" :rules="[{ required: true, message: '請?zhí)顚戲炞C碼' }]" > <template #button> <van-button size="small" type="primary">發(fā)送驗證碼</van-button> </template> </van-field> <van-field v-model="password" left-icon="manager-o" type="password" name="password" placeholder="請設(shè)計6-20位登錄密碼" :rules="[{ required: true, message: '請?zhí)顚懨艽a' }]" /> <van-field v-model="passwordT" left-icon="manager-o" type="password" name="passwordT" placeholder="請再次確認密碼" :rules="[{ required: true, message: '請?zhí)顚懨艽a' }]" /> <van-field name="checkbox"> <template #input> <van-checkbox v-model="checked" shape="round" >同意《<router-link to="protocol"><a>用戶服務協(xié)議</a></router-link >》</van-checkbox > </template> </van-field> </van-cell-group> <div style="margin: 16px"> <van-button round block type="primary" native-type="submit"> 注冊 </van-button> </div> </van-form> </div> <div class="find"> <router-link to="/login"><span>已有賬號,立即登錄</span></router-link> </div> </template> <!-- 邏輯層 --> <script setup> import { reactive, ref } from "vue"; import { get, post, put, del } from "~/axios/http"; import { showDialog } from "vant"; // 本地圖片引入 import img from "../../assets/images/avatar.svg"; // 導入useRouter方法 import { useRouter } from "vue-router"; const router = useRouter(); // 返回上一頁 const onClickLeft = () => { router.go(-1); }; // 表單 const username = ref(""); const captcha = ref(""); const password = ref(""); const passwordT = ref(""); const checked = ref(true); async function onSubmit(values) { //兩次輸入密碼一致 if (values.password == values.passwordT) { let res = await get("/api/infomation"); console.log(res); res.data.some((element) => { if (element.iphone == values.username) { showDialog({ title: "提示", message: "手機號已被注冊", }); } else if (values.password.length < 6 && values.passwordT.length < 6) { showDialog({ title: "提示", message: "密碼不低于六位", }); } else { //增加數(shù)據(jù) let res3 = post("/api/infomation", { iphone: values.username, password: values.password, name: "", gender: "", state: "", degree: "", num1: [], num2: [], num3: [], num4: [], num5:[], num6:[], num7:[], img:"" }); router.push("/login"); throw new Error(); } }); } else { showDialog({ title: "提示", message: "確定密碼跟密碼不一致", }); } } </script> <!-- 樣式層 --> <style scoped> .login { width: 100%; margin-top: 12.6667vw; } .login img { margin-left: 50vw; transform: translate(-50%, 0); } .find { width: 70%; margin: 0 auto; } .find span { display: block; width: 100%; color: #0079fe; text-align: center; } .ways { width: 80%; margin: 7.6667vw auto; text-align: center; } .ways > span { display: block; margin-bottom: 5.3333vw; color: #999999; } .ways div { display: flex; width: 80%; margin: 0 auto; justify-content: space-around; } .ways div span { font-size: 8.3333vw; } a { color: #0079fe; } </style><!-- * @Author: wu07 1732042133@qq.com * @Date: 2023-01-12 10:03:12 * @LastEditors: wu07 1732042133@qq.com * @LastEditTime: 2023-02-03 14:08:54 * @FilePath: \recruitAPP\recruitApp\recruitApp\src\pages\login\Login.vue * @Description: 這是默認設(shè)置,請設(shè)置`customMade`, 打開koroFileHeader查看配置 進行設(shè)置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE --> <!-- 視圖層 --> <template> <van-nav-bar title="注冊" left-text="返回" left-arrow @click-left="onClickLeft" /> <div class="login"> <img :src="img" alt="" /> <van-form @submit="onSubmit"> <van-cell-group inset> <van-field v-model="username" left-icon="phone-o" name="username" placeholder="請輸入手機號碼" :rules="[{ required: true, message: '請?zhí)顚懯謾C號碼' }]" /> <van-field v-model="captcha" center left-icon="sign" name="captcha" placeholder="請輸入驗證碼" :rules="[{ required: true, message: '請?zhí)顚戲炞C碼' }]" > <template #button> <van-button size="small" type="primary">發(fā)送驗證碼</van-button> </template> </van-field> <van-field v-model="password" left-icon="manager-o" type="password" name="password" placeholder="請設(shè)計6-20位登錄密碼" :rules="[{ required: true, message: '請?zhí)顚懨艽a' }]" /> <van-field v-model="passwordT" left-icon="manager-o" type="password" name="passwordT" placeholder="請再次確認密碼" :rules="[{ required: true, message: '請?zhí)顚懨艽a' }]" /> <van-field name="checkbox"> <template #input> <van-checkbox v-model="checked" shape="round" >同意《<router-link to="protocol"><a>用戶服務協(xié)議</a></router-link >》</van-checkbox > </template> </van-field> </van-cell-group> <div style="margin: 16px"> <van-button round block type="primary" native-type="submit"> 注冊 </van-button> </div> </van-form> </div> <div class="find"> <router-link to="/login"><span>已有賬號,立即登錄</span></router-link> </div> </template> <!-- 邏輯層 --> <script setup> import { reactive, ref } from "vue"; import { get, post, put, del } from "~/axios/http"; import { showDialog } from "vant"; // 本地圖片引入 import img from "../../assets/images/avatar.svg"; // 導入useRouter方法 import { useRouter } from "vue-router"; const router = useRouter(); // 返回上一頁 const onClickLeft = () => { router.go(-1); }; // 表單 const username = ref(""); const captcha = ref(""); const password = ref(""); const passwordT = ref(""); const checked = ref(true); async function onSubmit(values) { //兩次輸入密碼一致 if (values.password == values.passwordT) { let res = await get("/api/infomation"); console.log(res); res.data.some((element) => { if (element.iphone == values.username) { showDialog({ title: "提示", message: "手機號已被注冊", }); } else if (values.password.length < 6 && values.passwordT.length < 6) { showDialog({ title: "提示", message: "密碼不低于六位", }); } else { //增加數(shù)據(jù) let res3 = post("/api/infomation", { iphone: values.username, password: values.password, name: "", gender: "", state: "", degree: "", num1: [], num2: [], num3: [], num4: [], num5:[], num6:[], num7:[], img:"" }); router.push("/login"); throw new Error(); } }); } else { showDialog({ title: "提示", message: "確定密碼跟密碼不一致", }); } } </script> <!-- 樣式層 --> <style scoped> .login { width: 100%; margin-top: 12.6667vw; } .login img { margin-left: 50vw; transform: translate(-50%, 0); } .find { width: 70%; margin: 0 auto; } .find span { display: block; width: 100%; color: #0079fe; text-align: center; } .ways { width: 80%; margin: 7.6667vw auto; text-align: center; } .ways > span { display: block; margin-bottom: 5.3333vw; color: #999999; } .ways div { display: flex; width: 80%; margin: 0 auto; justify-content: space-around; } .ways div span { font-size: 8.3333vw; } a { color: #0079fe; } </style>
效果圖:
注冊模塊靜態(tài)頁面主要使用vant4組件庫中的組件,主要實現(xiàn)了通過vant表單的數(shù)據(jù)提交和axios方法獲取本地數(shù)據(jù)來判斷兩次密碼是否一致,一致就通過axios增加本地數(shù)據(jù)。驗證碼功能未實現(xiàn)
3.修改密碼
代碼:
<!-- * @Author: wu07 1732042133@qq.com * @Date: 2023-01-14 15:25:58 * @LastEditors: wu07 1732042133@qq.com * @LastEditTime: 2023-02-05 22:52:02 * @FilePath: \recruitAPP\recruitApp\recruitApp\src\pages\login\Verify.vue * @Description: 這是默認設(shè)置,請設(shè)置`customMade`, 打開koroFileHeader查看配置 進行設(shè)置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE --> <!-- 視圖層 --> <template> <van-nav-bar title="驗證" left-text="返回" left-arrow @click-left="onClickLeft" /> <van-tabs v-model:active="active" title-active-color="#0079FE" color="#fff"> <van-tab title="1.驗證手機號碼"> <van-form @submit="onSubmit"> <van-cell-group inset> <van-field v-model="username" left-icon="phone-o" name="username" placeholder="請輸入注冊手機號碼" :rules="[{ required: true, message: '請?zhí)顚懯謾C號碼' }]" /> <van-field v-model="password" center left-icon="sign" name="password" placeholder="請輸入驗證碼" :rules="[{ required: true, message: '請?zhí)顚戲炞C碼' }]" > <template #button> <van-button size="small" type="primary">發(fā)送驗證碼</van-button> </template> </van-field> </van-cell-group> <div style="margin: 16px"> <van-button round block type="primary" native-type="submit"> 下一步 </van-button> </div> </van-form> </van-tab> <van-tab title="2.設(shè)置新密碼" disabled></van-tab> </van-tabs> </template> <!-- 邏輯層 --> <script setup> import { get, post, put, del } from "~/axios/http"; import { showDialog } from "vant"; import { ref } from "vue"; // 導入useRouter方法 import { useRouter } from "vue-router"; const router = useRouter(); // 返回上一頁 const onClickLeft = () => { router.go(-1); }; // 表單 const username = ref(""); const password = ref(""); async function onSubmit(values) { let res = await get("/api/infomation"); res.data.forEach((element) => { if (element.iphone == values.username) { //傳出id值 router.push({ path: "/revise", query: { id: element.id, }, }); throw new Error(); } else { username.value = ""; password.value = ""; } }); } </script> <!-- 樣式層 --> <style scoped> </style>
<!-- * @Author: wu07 1732042133@qq.com * @Date: 2023-01-14 15:25:58 * @LastEditors: wu07 1732042133@qq.com * @LastEditTime: 2023-02-02 10:43:38 * @FilePath: \recruitAPP\recruitApp\recruitApp\src\pages\login\Verify.vue * @Description: 這是默認設(shè)置,請設(shè)置`customMade`, 打開koroFileHeader查看配置 進行設(shè)置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE --> <!-- 視圖層 --> <template> <van-nav-bar title="設(shè)置密碼" left-text="返回" left-arrow @click-left="onClickLeft" /> <van-tabs v-model:active="active" title-active-color="#0079FE" color="#fff"> <van-tab title="1.驗證手機號碼" disabled> </van-tab> <van-tab title="2.設(shè)置新密碼"> <van-form @submit="onSubmit"> <van-cell-group inset> <van-field v-model="password" left-icon="manager-o" name="password" type="password" placeholder="請設(shè)置6-20位新的登錄密碼" :rules="[{ required: true, message: '請?zhí)顚懶旅艽a' }]" /> <van-field v-model="passwordT" type="password" left-icon="manager-o" name="passwordT" placeholder="請再次輸入新的登錄密碼" :rules="[{ required: true, message: '請?zhí)顚懶旅艽a' }]" > </van-field> </van-cell-group> <div style="margin: 16px"> <van-button round block type="primary" native-type="submit"> 提交 </van-button> </div> </van-form> </van-tab> </van-tabs> </template> <!-- 邏輯層 --> <script setup> import { get, post, put, del,patch } from "~/axios/http"; import { showDialog } from "vant"; import { ref, reactive } from "vue"; // 導入useRouter方法 import { useRouter, useRoute } from "vue-router"; const router = useRouter(); const route = useRoute(); // 返回上一頁 const onClickLeft = () => { router.go(-1); }; // 表單 const password = ref(""); const passwordT = ref(""); async function onSubmit(values) { //route方法傳入id值 let data = reactive({ id: route.query.id, }); if (values.password.length < 6 && values.passwordT.length < 6) { showDialog({ title: "提示", message: "密碼不低于六位", }); } else if (values.password == values.passwordT) { let res2 = await get(`/api/infomation/${data.id}`); let res = await patch(`/api/infomation/${data.id}`, { password: values.password, }); showDialog({ title: "提示", message: "修改成功", }); router.push("/login"); } else { showDialog({ title: "提示", message: "兩次密碼不一致", }); } } </script> <!-- 樣式層 --> <style scoped> </style>
效果圖:
修改密碼由兩個頁面組成,通過輸入手機號用axios得到本地數(shù)據(jù)才能進入修改密碼頁面,同時通過router方法傳進一個id值同時用route方法接受id值,修改指定賬號的密碼
4.開始頁面
代碼:
<!-- * @Author: wu07 1732042133@qq.com * @Date: 2023-01-14 18:55:58 * @LastEditors: wu07 1732042133@qq.com * @LastEditTime: 2023-02-01 09:59:13 * @FilePath: \recruitAPP\recruitApp\recruitApp\src\pages\login\Start.vue * @Description: 這是默認設(shè)置,請設(shè)置`customMade`, 打開koroFileHeader查看配置 進行設(shè)置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE --> <!-- 視圖層 --> <template> <van-nav-bar title="注冊" left-text="返回" left-arrow @click-left="onClickLeft" /> <div class="user" @click="runUser">我是求職者</div> <div class="enterprise" @click="runEnterprise">我是招聘者</div> <div class="admin">我是管理員</div> <div></div> </template> <!-- 邏輯層 --> <script setup> // 導入useRouter方法 import { useRouter } from "vue-router"; const router = useRouter(); // 返回上一頁 const onClickLeft = () => { router.go(-1); }; // 跳轉(zhuǎn)用戶端 const runUser = () => { router.push("/user"); }; //跳轉(zhuǎn)企業(yè)端 const runEnterprise = () => { router.push("/tabber"); }; </script> <!-- 樣式層 --> <style scoped> .user { background-color: rgba(0, 121, 254, 1); width: 80%; height: 18.6667vw; border-radius: 1.3333vw; color: #fff; text-align: center; line-height: 18.6667vw; margin: 10.3333vw auto; margin-top: 23.3333vw; } .enterprise { background-color: rgba(75, 216, 99, 1); width: 80%; height: 18.6667vw; border-radius: 1.3333vw; color: #fff; text-align: center; line-height: 18.6667vw; margin: 10.3333vw auto; } .admin { background-color: rgba(254, 148, 0, 1); width: 80%; height: 18.6667vw; border-radius: 1.3333vw; color: #fff; text-align: center; line-height: 18.6667vw; margin: 10.3333vw auto; } </style>
效果圖:
該頁面主要進行三個端口的跳轉(zhuǎn),通過router路由的push方法進行路由跳轉(zhuǎn)
四、用戶端模塊
分為職位、求職申請、我的三個主頁面
1.職位模塊
代碼:
<!-- * @Author: wu07 1732042133@qq.com * @Date: 2023-01-14 19:31:55 * @LastEditors: wu07 1732042133@qq.com * @LastEditTime: 2023-02-02 15:58:50 * @FilePath: \recruitAPP\recruitApp\recruitApp\src\pages\user\Posts.vue * @Description: 這是默認設(shè)置,請設(shè)置`customMade`, 打開koroFileHeader查看配置 進行設(shè)置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE --> <!-- 視圖層 --> <template> <div class="body"> <van-nav-bar title="崗位" left-text="返回" left-arrow @click-left="onClickLeft" /> <van-search v-model="value" placeholder="請輸入搜索關(guān)鍵詞" @search="onSearch" /> <div class="classify"> <div> <span v-for="(item, index) in arr" :key="index" @click="change(index)" :class="{ active: index == nowIndex }" >{{ item }}</span > </div> <van-button type="default">篩選</van-button> </div> <div class="mainstay"> <div class="main" v-for="(item, index) in arr1" :key="index" v-if="nowIndex == 0" @click="runDetail(item.id)" v-show="item.fell == 'recommend'" > <div> <span>{{ item.name }}</span> <span>{{ item.money }}</span> </div> <div> {{ item.city }}<span>|</span>{{ item.time }}<span>|</span >{{ item.degree }} </div> <div> <span>{{ item.company }}</span> <span>{{ item.people }}</span> </div> </div> <div class="main" v-for="(item, index) in arr1" :key="index" v-if="nowIndex == 1" v-show="item.fell == 'hot'" @click="runDetail(item.id)" > <div> <span>{{ item.name }}</span> <span>{{ item.money }}</span> </div> <div> {{ item.city }}<span>|</span>{{ item.time }}<span>|</span >{{ item.degree }} </div> <div> <span>{{ item.company }}</span> <span>{{ item.people }}</span> </div> </div> </div> </div> </template> <!-- 邏輯層 --> <script setup> import { get, post, put, del } from "~/axios/http"; import { reactive, ref, computed } from "vue"; import { useRouter, useRoute } from "vue-router"; const router = useRouter(); const route = useRoute(); const value = ref(""); const arr = ref(["推薦", "熱門職位"]); const nowIndex = ref(0); const change = (index) => { nowIndex.value = index; }; const arr1 = ref([]); async function sendRequest() { let res = await get("/api/infomation2"); arr1.value = res.data; } sendRequest(); async function onSearch(val) { console.log(val); //模糊搜索 let res2 = await get(`/api/infomation2?name_like=${val}`); console.log(res2.data); arr1.value = res2.data; } const runDetail = (value) => { router.push({ path: "/postsDetail", query: { id: value, }, }); }; </script> <!-- 樣式層 --> <style scoped> .body { background-color: #f2f2f2; } .classify { display: flex; width: 100%; align-items: center; margin: 0 auto; justify-content: space-around; background-color: #fff; } .classify div { width: 70%; } .classify div span:nth-child(1) { margin-right: 5.3333vw; } .active { color: #0079fe; } .mainstay { padding-bottom: 13.3333vw; } .main { background-color: #fff; overflow: hidden; margin-bottom: 2.6667vw; } .main div:nth-child(1) { display: flex; width: 90%; margin: 0 auto; justify-content: space-between; margin-top: 2.6667vw; } .main div:nth-child(1) span:nth-child(2) { font-size: 5.3333vw; color: #0079fe; } .main div:nth-child(2) { margin: 1.6667vw 0; margin-left: 4.8333vw; } .main div:nth-child(2) span { margin: 0 0.8vw; color: #e4e4e4; } .main div:nth-child(3) { margin-left: 4.8333vw; margin-top: 1.6667vw; margin-bottom: 4vw; } .main div:nth-child(3) span:nth-child(1) { margin-right: 5.3333vw; } </style>
效果圖:
該頁面主要通過v-for進行數(shù)據(jù)遍歷,axios.get方法進行數(shù)據(jù)引用、搜索欄靜態(tài)效果主要用vant4組件,模糊搜索用了await get(`/api/infomation2?name_like=${val}`)的方法。
1.1職位詳情頁面
代碼:
<!-- * @Author: wu07 1732042133@qq.com * @Date: 2023-01-15 18:07:48 * @LastEditors: wu07 1732042133@qq.com * @LastEditTime: 2023-02-03 11:29:04 * @FilePath: \recruitAPP\recruitApp\recruitApp\src\pages\user\PostsDetail.vue * @Description: 這是默認設(shè)置,請設(shè)置`customMade`, 打開koroFileHeader查看配置 進行設(shè)置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE --> <!-- 視圖層 --> <template> <van-nav-bar title="職位詳情" left-text="返回" left-arrow @click-left="onClickLeft" /> <div class="name"> <span>{{ arr.name }}</span> <span>{{ arr.money }}</span> <div> <span>{{ arr.city }}</span ><span>|</span><span>{{ arr.time }}</span ><span>|</span><span>{{ arr.degree }}</span> </div> </div> <div class="introduce"> <span>職位描述</span> <p>{{ arr.introduce }}</p> </div> <div class="company"> <span>公司簡介</span> <div> <span>{{ arr.company }}</span ><span>{{ arr.people }}</span> <p>{{ arr.description }}</p> </div> </div> <div class="bt"> <van-button square type="default" @click="change">{{ a }}</van-button> <van-button square type="primary" @click="td">投遞簡歷</van-button> </div> </template> <!-- 邏輯層 --> <script setup> import { get, post, put, del, patch } from "~/axios/http"; import { showDialog } from "vant"; import { ref, reactive } from "vue"; // 導入useRouter方法 import { useRouter, useRoute } from "vue-router"; const router = useRouter(); const route = useRoute(); // 返回上一頁 const onClickLeft = () => { router.go(-1); }; const arr = ref({}); const a = ref(""); async function find() { let data = reactive({ id: route.query.id, }); let res2 = await get(`/api/infomation2/${data.id}`); arr.value = res2.data; a.value = res2.data.interest; } find(); const flag = ref(true); async function change() { flag.value = !flag.value; if (flag.value == true) { a.value = "感興趣"; let data = reactive({ id: route.query.id, }); let res7 = await patch(`/api/infomation2/${data.id}`, { like: "0", interest: "感興趣", }); let id = ref(localStorage.getItem("key")); let res10 = await get(`/api/infomation/${id.value}`); res10.data.num3.pop(Number(data.id)); let res11 = await patch(`/api/infomation/${id.value}`, { num3: res10.data.num3, }); } else { a.value = "取消感興趣"; let data = reactive({ id: route.query.id, }); let res5 = await patch(`/api/infomation2/${data.id}`, { like: "1", interest: "取消感興趣", }); let id = ref(localStorage.getItem("key")); let res12 = await get(`/api/infomation/${id.value}`); res12.data.num3.push(Number(data.id)); let res13 = await patch(`/api/infomation/${id.value}`, { num3: res12.data.num3, }); } } async function td() { let data = reactive({ id: route.query.id, }); let res3 = await patch(`/api/infomation2/${data.id}`, { state: "投遞成功", }); let id = ref(localStorage.getItem("key")); let res8 = await get(`/api/infomation/${id.value}`); res8.data.num1.push(Number(data.id)); let res9 = await patch(`/api/infomation/${id.value}`, { num1: res8.data.num1, }); } </script> <!-- 樣式層 --> <style scoped> .name { width: 90%; margin: 0 auto; display: flex; flex-direction: column; border-bottom: 2px solid #e4e4e4; border-top: 2px solid #e4e4e4; padding-bottom: 2.6667vw; } .name > span:nth-child(1) { font-weight: bold; margin: 2.6667vw 0; } .name > span:nth-child(2) { font-size: 5.3333vw; color: #09ba72; margin-bottom: 2.6667vw; } .name > div span { margin-right: 1.3333vw; } .introduce { width: 90%; margin: 0 auto; padding-top: 2.6667vw; border-bottom: 2px solid #e4e4e4; } .introduce span { font-weight: bold; } .company { width: 90%; margin: 0 auto; padding-top: 2.6667vw; border-bottom: 2px solid #e4e4e4; display: flex; flex-direction: column; margin-bottom: 10.3333vw; } .company > span:nth-child(1) { font-weight: bold; margin: 2.6667vw 0; } .company div span:nth-child(1) { margin-right: 5.3333vw; } .bt { width: 80%; display: flex; margin: 0 auto; justify-content: space-between; } .bt .van-button { width: 35vw !important; } </style>
效果圖:
該頁面通過職位頁面router路由query傳值方法接收不同id值,再通過axios方法獲取json-server不同id值的數(shù)據(jù)從而實現(xiàn)數(shù)據(jù)動態(tài)交互。同時頁面數(shù)據(jù)同樣通過axios.get方式獲取數(shù)據(jù)渲染頁面。按鈕感興趣與投遞簡歷都能實現(xiàn)數(shù)據(jù)的傳遞
2.求職申請頁面
代碼:
<!-- * @Author: wu07 1732042133@qq.com * @Date: 2023-01-14 19:32:47 * @LastEditors: wu07 1732042133@qq.com * @LastEditTime: 2023-02-03 10:47:57 * @FilePath: \recruitAPP\recruitApp\recruitApp\src\pages\user\Request.vue * @Description: 這是默認設(shè)置,請設(shè)置`customMade`, 打開koroFileHeader查看配置 進行設(shè)置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE --> <!-- 視圖層 --> <template> <div class="all"> <van-nav-bar title="求職反饋" left-text="返回" left-arrow @click-left="onClickLeft" /> <van-tabs v-model:active="active"> <van-tab v-for="(value, index) in nav" :title="value" ><div v-for="(item, i) in arr" v-show="value == item.state" @click="runDetail(item.id)" > <div class="body"> <div class="name"> <span> {{ item.name }}</span ><span> {{ item.state }}</span> </div> <div class="money">{{ item.money }}</div> <div class="introduce">{{ item.introduce }}</div> </div> </div></van-tab > </van-tabs> </div> </template> <!-- 邏輯層 --> <script setup> import { get, post, put, del, patch } from "~/axios/http"; import { ref, reactive } from "vue"; import { useRouter, useRoute } from "vue-router"; const router = useRouter(); const route = useRoute(); const nav = ref([ "投遞成功", "被查看", "面試待確認", "已約面試", "不合適", "有意向", "已錄用", ]); const arr = ref([]); const arr1 = ref([]); async function sendRequest() { let id = ref(localStorage.getItem("key")); let res1 = await get(`/api/infomation?id=${id.value}`); res1.data[0].num1.forEach(async function (element) { let res3 = patch(`/api/infomation2/${element}`, { state: "投遞成功", }); }); res1.data[0].num2.forEach(async function (element) { let res3 = patch(`/api/infomation2/${element}`, { state: "已約面試", }); }); let res = await get("/api/infomation2"); arr.value = res.data; } sendRequest(); const runDetail = (value) => { router.push({ path: "/requestDetail", query: { id: value, }, }); }; </script> <!-- 樣式層 --> <style scoped> .all { background-color: #f2f2f2; margin-bottom: 12vw; } .body { width: 100%; margin-bottom: 2.6667vw; background-color: #fff; overflow: hidden; } .name { display: flex; justify-content: space-between; width: 90%; margin: 1.6vw auto; } .name span:nth-child(2) { color: #ff9933; } .money { width: 90%; margin: 0 auto; } .introduce { width: 90%; margin: 1.6vw auto; } </style>
效果圖
該頁面通過json-server數(shù)據(jù)對崗位狀態(tài)進行分別展示,通過v-show進行不同狀態(tài)的不同崗位展示
同時不同用戶顯示自己的參與的崗位狀態(tài)實現(xiàn)數(shù)據(jù)的動態(tài)顯示。
2.1求職申請詳情頁
<!-- * @Author: wu07 1732042133@qq.com * @Date: 2023-01-15 18:07:48 * @LastEditors: wu07 1732042133@qq.com * @LastEditTime: 2023-02-02 16:04:00 * @FilePath: \recruitAPP\recruitApp\recruitApp\src\pages\user\PostsDetail.vue * @Description: 這是默認設(shè)置,請設(shè)置`customMade`, 打開koroFileHeader查看配置 進行設(shè)置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE --> <!-- 視圖層 --> <template> <van-nav-bar title="職位詳情" left-text="返回" left-arrow @click-left="onClickLeft" /> <div class="name"> <span>{{ arr.name }}</span> <span>{{ arr.money }}</span> <div> <span>{{ arr.city }}</span ><span>|</span><span>{{ arr.time }}</span ><span>|</span><span>{{ arr.degree }}</span> </div> </div> <div class="introduce"> <span>職位描述</span> <p>{{ arr.introduce }}</p> </div> <div class="company"> <span>公司簡介</span> <div> <span>{{ arr.company }}</span ><span>{{ arr.people }}</span> <p>{{ arr.description }}</p> </div> </div> </template> <!-- 邏輯層 --> <script setup> import { get, post, put, del } from "~/axios/http"; import { showDialog } from "vant"; import { ref, reactive } from "vue"; // 導入useRouter方法 import { useRouter, useRoute } from "vue-router"; const router = useRouter(); const route = useRoute(); // 返回上一頁 const onClickLeft = () => { router.go(-1); }; const arr = ref({}); async function find() { let data = reactive({ id: route.query.id, }); let res2 = await get(`/api/infomation2/${data.id}`); arr.value = res2.data; console.log(arr.value); } find(); </script> <!-- 樣式層 --> <style scoped> .name { width: 90%; margin: 0 auto; display: flex; flex-direction: column; border-bottom: 2px solid #e4e4e4; border-top: 2px solid #e4e4e4; padding-bottom: 2.6667vw; } .name > span:nth-child(1) { font-weight: bold; margin: 2.6667vw 0; } .name > span:nth-child(2) { font-size: 5.3333vw; color: #09ba72; margin-bottom: 2.6667vw; } .name > div span { margin-right: 1.3333vw; } .introduce { width: 90%; margin: 0 auto; padding-top: 2.6667vw; border-bottom: 2px solid #e4e4e4; } .introduce span { font-weight: bold; } .company { width: 90%; margin: 0 auto; padding-top: 2.6667vw; border-bottom: 2px solid #e4e4e4; display: flex; flex-direction: column; margin-bottom: 10.3333vw; } .company > span:nth-child(1) { font-weight: bold; margin: 2.6667vw 0; } .company div span:nth-child(1) { margin-right: 5.3333vw; } </style>
效果圖:
該頁面通過職位頁面router路由query傳值方法接收不同id值,再通過axios方法獲取json-server不同id值的數(shù)據(jù)從而實現(xiàn)數(shù)據(jù)動態(tài)交互。同時頁面數(shù)據(jù)同樣通過axios.get方式獲取數(shù)據(jù)渲染頁面。
3.我的頁面
代碼:
<!-- * @Author: wu07 1732042133@qq.com * @Date: 2023-01-14 19:33:31 * @LastEditors: wu07 1732042133@qq.com * @LastEditTime: 2023-02-03 17:41:18 * @FilePath: \recruitAPP\recruitApp\recruitApp\src\pages\user\Me.vue * @Description: 這是默認設(shè)置,請設(shè)置`customMade`, 打開koroFileHeader查看配置 進行設(shè)置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE --> <!-- 視圖層 --> <template> <div class="body"> <van-nav-bar title="我的" left-text="返回" left-arrow @click-left="onClickLeft" /> <div class="before" v-show="num4 == 0" @click="write"> <span>請?zhí)顚憘€人信息</span> </div> <div class="name" v-show="num4 == 1" v-for="(item, idex) in me" :key="index" > <div class="message"> <span>{{ item.name }} <van-icon name="edit" @click="revise" /></span> <img :src="item.url" /> </div> <div class="number"> <div v-for="(item, idex) in number" :key="index"> <span>{{ item.name }}</span> <span>{{ item.number }}</span> </div> </div> </div> <div class="function"> <div v-for="(item, index) in fc" :key="index" @click="run(item.path)"> <span>{{ item.name }}</span> <div> <van-badge :content="item.num" position="center-right" v-show="item.num >= 1" /> <van-icon name="arrow" /> </div> </div> </div> <van-button type="primary" block @click="exit">退出登錄</van-button> </div> </template> <!-- 邏輯層 --> <script setup> // 本地圖片引入 import img from "../../../assets/images/u616.png"; import { get, post, put, del, patch } from "~/axios/http"; import { ref } from "vue"; // 導入useRouter方法 import { useRouter } from "vue-router"; const router = useRouter(); // 返回上一頁 const onClickLeft = () => { router.go(-1); }; // 跳轉(zhuǎn)個人信息修改 const revise = () => { router.push("/information"); }; // 跳轉(zhuǎn)詳情頁 const run = (val) => { router.push(val); }; const me = ref([ { name: "", url: img, }, ]); const num1 = ref(); const num2 = ref(); const num3 = ref([]); const num4 = ref(); async function num() { let res1 = await get("/api/infomation2?state=投遞成功"); let res2 = await get("/api/infomation2?state=已約面試"); let res3 = await get("/api/infomation2?like=1"); let id = ref(localStorage.getItem("key")); let res4 = await get(`/api/infomation/${id.value}`); console.log(res4.data.iphone); if (res4.data.name == "") { num4.value = 0; } else { num4.value = 1; } me.value[0].name = res4.data.name; me.value[0].url = res4.data.img; console.log(num4); num1.value = res1.data.length; num2.value = res2.data.length; num3.value = res3.data.length; } num(); const number = ref([ { name: "已投遞", number: num1 }, { name: "已面試", number: num2 }, { name: "感興趣", number: num3 }, ]); const fc = ref([ { name: "在線簡歷", num: "0", path: "/resume" }, { name: "修改密碼", num: "0", path: "/verify" }, { name: "意見反饋", num: "2", path: "/opinion" }, { name: "消息", num: "10" }, ]); const write = () => { router.push("/information"); }; async function exit() { let res5 = await get("/api/infomation2"); res5.data.forEach(async function (element) { if (element.state == "投遞成功") { let res6 = await patch(`/api/infomation2/${element.id}`, { state: "", }); } else if (element.state == "已約面試") { let res7 = await patch(`/api/infomation2/${element.id}`, { state: "", }); } else if (element.like == "1") { let res8 = await patch(`/api/infomation2/${element.id}`, { like: "0", }); } router.push("/login"); }); } </script> <!-- 樣式層 --> <style scoped> .body { background-color: #f2f2f2; height: 100vh; } .name { background-color: #f59a23; width: 100%; } .before { width: 100%; height: 26.6667vw; background-color: cornflowerblue; text-align: center; font-size: 4.3333vw; line-height: 26.6667vw; color: #775a34; } .message { display: flex; justify-content: space-between; align-content: center; width: 90%; margin: 0 auto; padding-top: 2.6667vw; } .message img { height: 18.6667vw; } .message span { line-height: 21.3333vw; color: #fce6c8; font-size: 4.2667vw; } .number { display: flex; width: 90%; margin: 5.3333vw auto; justify-content: space-around; } .number div { display: flex; flex-direction: column; align-items: center; color: #fce6c8; margin-bottom: 5.3333vw; } .number div span:nth-child(1) { margin-bottom: 2.6667vw; } .function { width: 100%; } .function > div { width: 100%; display: flex; justify-content: space-between; height: 13.3333vw; background-color: #fff; margin-bottom: 2.6667vw; align-items: center; } .function > div span { margin-left: 2.6667vw; } .function > div div { margin-right: 2.6667vw; } img { border-radius: 50%; width: 18.3333vw; } </style>
效果圖:
該頁面名字頭像實現(xiàn)動態(tài)改變同時已投遞、已面試、感興趣都能通過職位的狀態(tài)改變發(fā)生改變,功能模塊通過router.push跳轉(zhuǎn)。
3.1我的頁面信息修改
代碼:
<!-- * @Author: wu07 1732042133@qq.com * @Date: 2023-01-31 14:54:13 * @LastEditors: wu07 1732042133@qq.com * @LastEditTime: 2023-02-03 17:39:47 * @FilePath: \recruitApp\recruitApp\src\pages\user\Me\Information.vue * @Description: 這是默認設(shè)置,請設(shè)置`customMade`, 打開koroFileHeader查看配置 進行設(shè)置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE --> <!-- 視圖層 --> <template> <div> <van-nav-bar title="個人信息" left-text="返回" left-arrow @click-left="onClickLeft" /> <van-form @submit="onSubmit"> <van-cell-group inset> <van-field name="uploader" label="頭像上傳"> <template #input> <van-uploader v-model="imgUrl" multiple :max-count="1" :after-read="afterRead" /> </template> </van-field> <van-field v-model="name" label="姓名" name="name" placeholder="請輸入姓名" :rules="[{ required: true, message: '請?zhí)顚懶彰? }]" /> <van-field v-model="fieldValue" is-link readonly name="fieldValue" label="性別" placeholder="選擇性別" @click="showPicker = true" /> <van-popup v-model:show="showPicker" round position="bottom"> <van-picker :columns="columns" @cancel="showPicker = false" @confirm="onConfirm" /> </van-popup> <van-field v-model="fieldValueTwo" name="fieldValueTwo" is-link readonly label="求職狀態(tài)" placeholder="求職狀態(tài)" @click="showPickerTwo = true" /> <van-popup v-model:show="showPickerTwo" round position="bottom"> <van-picker :columns="columnsTwo" @cancel="showPickerTwo = false" @confirm="onConfirmTwo" /> </van-popup> <van-field v-model="fieldValueThree" name="fieldValueThree" is-link readonly label="學歷" placeholder="選擇學歷" @click="showPickerThree = true" /> <van-popup v-model:show="showPickerThree" round position="bottom"> <van-picker :columns="columnsThree" @cancel="showPickerThree = false" @confirm="onConfirmThree" /> </van-popup> <van-field v-model="emile" name="emile" label="郵箱" placeholder="請輸入郵箱" :rules="[{ required: true, message: '請?zhí)顚戉]箱' }]" /> </van-cell-group> <div style="margin: 16px"> <van-button round block type="primary" native-type="submit"> 提交 </van-button> </div> </van-form> </div> </template> <!-- 邏輯層 --> <script setup> // 導入useRouter方法 import { useRouter } from "vue-router"; const router = useRouter(); // 返回上一頁 const onClickLeft = () => { router.go(-1); }; import { ref } from "vue"; import { get, post, put, del, patch } from "~/axios/http"; const imgUrl = ref([{ url: "" }]); const emile = ref(""); const name = ref(""); async function onSubmit(values) { console.log("submit", values); console.log(values.uploader[0].content); let id = ref(localStorage.getItem("key")); let res = await patch(`/api/infomation/${id.value}`, { img: values.uploader[0].content, name: values.name, gender: values.fieldValue, state: values.fieldValueTwo, degree: values.fieldValueThree, }); router.push("/Me/me"); } const afterRead = (file) => { // 此時可以自行將文件上傳至服務器 console.log(file); }; const columns = [ { text: "男", value: "Boy" }, { text: "女", value: "Girl" }, ]; const fieldValue = ref(""); const showPicker = ref(false); const onConfirm = ({ selectedOptions }) => { showPicker.value = false; fieldValue.value = selectedOptions[0].text; }; const columnsTwo = [ { text: "在職", value: "in" }, { text: "離職", value: "out" }, ]; const fieldValueTwo = ref(""); const showPickerTwo = ref(false); const onConfirmTwo = ({ selectedOptions }) => { showPickerTwo.value = false; fieldValueTwo.value = selectedOptions[0].text; }; const columnsThree = [ { text: "初中", value: "secondary" }, { text: "高中", value: "high" }, { text: "中專", value: "technical" }, { text: "大專", value: "junior" }, { text: "本科", value: "undergraduate" }, { text: "碩士", value: "msc" }, { text: "博士", value: "dr" }, ]; const fieldValueThree = ref(""); const showPickerThree = ref(false); const onConfirmThree = ({ selectedOptions }) => { showPickerThree.value = false; fieldValueThree.value = selectedOptions[0].text; }; </script> <!-- 樣式層 --> <style scoped> </style>
效果圖:
該頁面通過vant4組件獲取表單值,通過axios.patch修改數(shù)據(jù)
3.2我的在線簡歷頁面
代碼:
<!-- * @Author: wu07 1732042133@qq.com * @Date: 2023-01-31 16:35:52 * @LastEditors: wu07 1732042133@qq.com * @LastEditTime: 2023-02-03 15:59:07 * @FilePath: \recruitApp\recruitApp\src\pages\user\Me\Resume.vue * @Description: 這是默認設(shè)置,請設(shè)置`customMade`, 打開koroFileHeader查看配置 進行設(shè)置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%Az --> <!-- 視圖層 --> <template> <div class="body"> <van-nav-bar title="在線簡歷" left-text="返回" left-arrow @click-left="onClickLeft" /> <div class="message"> <span>基礎(chǔ)信息</span> <div> <span>{{ arr.name }}</span> <div><img :src="img" /><van-icon name="arrow" /></div> </div> <div> <span>{{ arr.gender }}</span> <span>|</span> <span>{{ arr.degree }}</span> <span>|</span> <span>{{ arr.iphone }}</span> </div> </div> <div class="job"> <div class="intention"> <span>求職意向</span><van-icon name="add-o" @click="addIntention" /> </div> <div v-for="(value, index) in arr1" :key="index" class="functions"> <div class="left"> <div> <span>職能:{{ value.name }}</span ><span>{{ value.money }}</span> </div> <span>工作地點:{{ value.place }}</span> </div> <van-icon name="arrow" @click="runTwo(index)" /> </div> </div> <div class="experience"> <div class="history"> <span>工作經(jīng)驗(實習經(jīng)驗)</span ><van-icon name="add-o" @click="addExperience" /> </div> <div class="content" v-for="(item, index) in arr2" :key="index"> <div class="firm"> <span>{{ item.firm }}</span> <van-icon name="arrow" /> </div> <span>{{ item.posts }}</span> <span>{{ item.time }}</span> <div class="part"> <p>內(nèi)容:{{ item.content }}</p> </div> </div> </div> <div class="educated"> <div class="qualifications"> <span>教育經(jīng)歷</span><van-icon name="add-o" @click="addEducated" /> </div> <div class="content" v-for="(item, index) in arr3" :key="index"> <div class="school"> <span>{{ item.school }}</span> <van-icon name="arrow" /> </div> <span>{{ item.time }}</span> <div class="degree"> <span>{{ item.subject }}</span> <span>{{ item.degree }}</span> </div> </div> </div> </div> </template> <!-- 邏輯層 --> <script setup> import { get, post, put, del, patch } from "~/axios/http"; import { ref } from "vue"; import img from "../../../assets/images/u616.png"; // 導入useRouter方法 import { useRouter, useRoute } from "vue-router"; const router = useRouter(); // 返回上一頁 const onClickLeft = () => { router.go(-1); }; const arr = ref([]); const arr1 = ref([]); const arr2 = ref([]); const arr3 = ref([]); async function message() { let id = ref(localStorage.getItem("key")); let res = await get(`/api/infomation/${id.value}`); arr.value = res.data; arr1.value = res.data.num4; console.log(res.data.num5); arr2.value = res.data.num5; arr3.value = res.data.num6; } message(); const addIntention = () => { router.push("/intent"); }; const addExperience = () => { router.push("/experience"); }; const addEducated = () => { router.push("/degree"); }; const runTwo = (val) => { console.log(val); router.push({ path: "/intentTwo", query: { index: val, }, }); }; </script> <!-- 樣式層 --> <style scoped> .body { background-color: #f2f2f2; } .message { width: 100%; padding-top: 2.6667vw; background-color: #fff; margin-bottom: 4vw; padding-bottom: 2.6667vw; } .message > span { margin-left: 5.3333vw; font-weight: bold; } .message > div:nth-child(2) { display: flex; align-items: center; justify-content: space-between; width: 90%; margin: 0 auto; } .message > div:nth-child(2) div { display: flex; align-items: center; } .message div:nth-child(2) img { width: 13.3333vw; } .message > div:nth-child(3) { width: 90%; margin: 0 auto; } .job { width: 100%; background-color: #fff; overflow: hidden; margin-bottom: 4vw; } .intention { display: flex; justify-content: space-between; align-items: center; width: 90%; margin: 0 auto; padding-top: 2.6667vw; } .intention span { font-weight: bold; } .intention .van-icon { font-size: 5.3333vw; } .functions { display: flex; align-items: center; justify-content: space-between; width: 90%; margin: 0 auto; padding: 4vw 0; border-bottom: 2px solid #e4e4e4; } .left { width: 60%; } .left div { display: flex; justify-content: space-between; margin-bottom: 2.6667vw; } .experience { width: 100%; background-color: #fff; overflow: hidden; margin-bottom: 4vw; } .history { display: flex; justify-content: space-between; align-items: center; width: 90%; margin: 0 auto; padding-top: 2.6667vw; } .history span { font-weight: bold; } .history .van-icon { font-size: 5.3333vw; } .experience .content { width: 90%; margin: 0 auto; display: flex; flex-direction: column; padding-bottom: 4.6667vw; border-bottom: 1px solid #e4e4e4; } .content .firm { display: flex; justify-content: space-between; margin: 2.6667vw 0; } .content span:nth-child(3) { margin: 2.6667vw 0; } .part { background-color: #f2f2f2; color: #999999; } .part p { padding: 2.6667vw 1.6vw; } .educated { width: 100%; background-color: #fff; overflow: hidden; margin-bottom: 4vw; } .qualifications { display: flex; justify-content: space-between; align-items: center; width: 90%; margin: 0 auto; padding-top: 2.6667vw; } .qualifications span { font-weight: bold; } .qualifications .van-icon { font-size: 5.3333vw; } .educated .content { width: 90%; margin: 0 auto; display: flex; flex-direction: column; padding-bottom: 4.6667vw; border-bottom: 1px solid #e4e4e4; } .educated .content .school { display: flex; justify-content: space-between; margin: 2.6667vw 0; } .educated .content .degree { margin-top: 2.6667vw; } .educated .content .degree span:nth-child(1) { margin-right: 5.3333vw; } .certificate { width: 100%; background-color: #fff; overflow: hidden; margin-bottom: 4vw; } .certificate .cert { display: flex; justify-content: space-between; align-items: center; width: 90%; margin: 0 auto; padding-top: 2.6667vw; } .cert span { font-weight: bold; } .cert .van-icon { font-size: 5.3333vw; } .certificate .content { display: flex; width: 100%; flex-wrap: wrap; justify-content: space-around; } .certificate .content .credentials { width: 30%; background-color: #e4e4e4; padding: 1.3333vw 0.5333vw; text-align: center; margin-top: 5.3333vw; } </style>
效果圖
該頁面通過axios.get獲取數(shù)據(jù)再通過v-for進行循環(huán)渲染頁面
3.2.1求職意向修改頁面
代碼:
<!-- * @Author: wu07 1732042133@qq.com * @Date: 2023-02-01 11:20:29 * @LastEditors: wu07 1732042133@qq.com * @LastEditTime: 2023-02-03 16:20:35 * @FilePath: \recruitApp\recruitApp\src\pages\user\Me\Intent.vue * @Description: 這是默認設(shè)置,請設(shè)置`customMade`, 打開koroFileHeader查看配置 進行設(shè)置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE --> <!-- 視圖層 --> <template> <van-nav-bar title="求職意向" left-text="返回" left-arrow @click-left="onClickLeft" /> <van-form @submit="onSubmit"> <van-cell-group inset> <van-field v-model="result" is-link readonly name="picker" label="求職類型" placeholder="點擊選擇職位" @click="showPicker = true" /> <van-popup v-model:show="showPicker" position="bottom"> <van-picker :columns="columns" @confirm="onConfirm" @cancel="showPicker = false" /> </van-popup> <van-field v-model="resultTwo" is-link readonly name="area" label="地區(qū)選擇" placeholder="點擊選擇省市區(qū)" @click="showArea = true" /> <van-popup v-model:show="showArea" position="bottom"> <van-area :area-list="areaList" @confirm="onConfirmTwo" @cancel="showArea = false" /> </van-popup> <div class="a">薪資要求</div> <div class="money"> <van-field v-model="value" placeholder="請輸入" name="money" /> <span>-</span> <van-field v-model="valueOne" placeholder="請輸入" name="moneyOne" /> <span>k</span> </div> </van-cell-group> <div style="margin: 16px"> <van-button round block type="primary" native-type="submit"> 提交 </van-button> </div> </van-form> </template> <!-- 邏輯層 --> <script setup> // 導入useRouter方法 import { useRouter } from "vue-router"; import { ref } from "vue"; import { areaList } from "@vant/area-data"; import { get, post, put, del, patch } from "~/axios/http"; const router = useRouter(); // 返回上一頁 const onClickLeft = () => { router.go(-1); }; const result = ref(""); const showPicker = ref(false); const columns = [ { text: "會計", value: "Hangzhou" }, { text: "老師", value: "Ningbo" }, { text: "IT", value: "Wenzhou" }, { text: "稅務", value: "Shaoxing" }, { text: "管理", value: "Huzhou" }, ]; const onConfirm = ({ selectedOptions }) => { result.value = selectedOptions[0]?.text; showPicker.value = false; }; const resultTwo = ref(""); const showArea = ref(false); const onConfirmTwo = ({ selectedOptions }) => { showArea.value = false; resultTwo.value = selectedOptions.map((item) => item.text).join("/"); }; const value = ref(""); const valueOne = ref(""); async function onSubmit(values) { console.log("submit", values); let id = ref(localStorage.getItem("key")); let arr1 = ref(`${values.money}-${values.moneyOne}k`); let arr = ref({ name: values.picker, money: arr1.value, place: values.area }); console.log(arr.value); let res1 = await get(`/api/infomation/${id.value}`); res1.data.num4.push(arr.value); let res2 = await patch(`/api/infomation/${id.value}`, { num4: res1.data.num4, }); router.push("/resume"); } </script> <!-- 樣式層 --> <style scoped> .money { display: flex; align-items: center; } .a { margin-left: 4vw; margin-top: 8vw; } </style>
效果圖:
該頁面通過vant4組件獲取表單值,通過axios.patch修改數(shù)據(jù)
3.3我的意見反饋模塊
代碼:
<!-- * @Author: wu07 1732042133@qq.com * @Date: 2023-02-01 16:58:23 * @LastEditors: wu07 1732042133@qq.com * @LastEditTime: 2023-02-03 16:43:22 * @FilePath: \recruitAPP\recruitApp\recruitApp\src\pages\user\Me\Opinion.vue * @Description: 這是默認設(shè)置,請設(shè)置`customMade`, 打開koroFileHeader查看配置 進行設(shè)置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE --> <!-- 視圖層 --> <template> <van-nav-bar title="意見反饋" left-text="返回" left-arrow @click-left="onClickLeft" /> <div class="body"> <div class="content" v-for="(value, index) in arr" :key="inex"> <div class="one"> <span>反饋類型:{{ value.type }}</span ><van-button plain :type="value.color" class="bt">{{ value.state }}</van-button> </div> <div class="two"> <span>內(nèi)容:{{ value.content }}</span> </div> </div> </div> <van-button type="primary" block @click="runAdd">添加反饋</van-button> </template> <!-- 邏輯層 --> <script setup> import { ref } from "vue"; import { get, post, put, del, patch } from "~/axios/http"; // 導入useRouter方法 import { useRouter } from "vue-router"; const router = useRouter(); // 返回上一頁 const onClickLeft = () => { router.go(-1); }; const runAdd = () => { router.push("/add"); }; const value = ref(""); const arr = ref([]); async function message() { let id = ref(localStorage.getItem("key")); let res1 = await get(`/api/infomation/${id.value}`); console.log(res1.data.num7); arr.value = res1.data.num7; } message(); </script> <!-- 樣式層 --> <style scoped> .content { width: 100%; padding: 4vw 0; border: 0.2667vw solid #e6e6e6; } .content div { width: 90%; margin: 0 auto; } .one { display: flex; justify-content: space-between; align-content: center; } .two { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .body { margin-bottom: 5.3333vw; } .bt { width: 14.3333vw !important; padding: 0.2667vw !important; height: 8.6667vw; } </style>
效果圖:
頁面通過axioas.get獲取數(shù)據(jù)
四、總結(jié)
這次項目有了招聘app的基礎(chǔ)功能,但是還有許多細節(jié)需要完善。
到此這篇關(guān)于vue3+vite+vant4手機端項目的文章就介紹到這了,更多相關(guān)vue3+vite+vant4手機端項目內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
vue中keep-alive內(nèi)置組件緩存的實例代碼
這篇文章主要介紹了vue中的keep-alive內(nèi)置組件緩存,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-04-04使用VUE+iView+.Net Core上傳圖片的方法示例
這篇文章主要介紹了使用VUE+iView+.Net Core上傳圖片的方法示例,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2019-01-01Vue openLayers實現(xiàn)圖層數(shù)據(jù)切換與加載流程詳解
OpenLayers是一個用于開發(fā)WebGIS客戶端的JavaScript包,最初基于BSD許可發(fā)行。OpenLayers是一個開源的項目,其設(shè)計之意是為互聯(lián)網(wǎng)客戶端提供強大的地圖展示功能,包括地圖數(shù)據(jù)顯示與相關(guān)操作,并具有靈活的擴展機制2022-09-09Vue.js實現(xiàn)數(shù)據(jù)響應的方法
這篇文章主要介紹了Vue.js實現(xiàn)數(shù)據(jù)響應的方法,本文給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友可以參考下2018-08-08vue2中的el-select組件數(shù)據(jù)太多,如何實現(xiàn)滾動加載數(shù)據(jù)效果
這篇文章主要介紹了vue2中的el-select組件數(shù)據(jù)太多,如何實現(xiàn)滾動加載數(shù)據(jù)效果,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-04-04vue3?process.env.XXX環(huán)境變量不生效的解決方法
這篇文章主要給大家介紹了關(guān)于vue3?process.env.XXX環(huán)境變量不生效的解決方法,通過文中介紹的方法可以很方便的解決遇到的問題,對大家學習或者使用vue3具有一定的參考借鑒價值,需要的朋友可以參考下2023-08-08vue3實現(xiàn)tabs導航欄點擊每個導航項有下劃線動畫效果
這篇文章主要介紹了vue3實現(xiàn)tabs導航欄點擊每個導航項有下劃線動畫效果,本文通過實例代碼給大家介紹的非常詳細,感興趣的朋友跟隨小編一起看看吧2024-07-07