当前位置: 首页> 教育> 幼教 > seo教程技术整站优化_武汉人才网官方网站入口_国内广告投放平台_查询网

seo教程技术整站优化_武汉人才网官方网站入口_国内广告投放平台_查询网

时间:2025/7/17 13:26:51来源:https://blog.csdn.net/m0_74825699/article/details/144679337 浏览次数:0次
seo教程技术整站优化_武汉人才网官方网站入口_国内广告投放平台_查询网

云风网
云风笔记
云风知识库

一、创建前端部分

1、vite初始化项目

npm create vite@latest admin-frontend – --template vue-ts

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2、安装必要的依赖
npm install vue-router pinia axios element-plus @element-plus/icons-vue

安装完成后package.json如下:

{"name": "admin-frontend","private": true,"version": "0.0.0","type": "module","scripts": {"dev": "vite","build": "vue-tsc -b && vite build","preview": "vite preview"},"dependencies": {"@element-plus/icons-vue": "^2.3.1","axios": "^1.7.7","element-plus": "^2.8.7","pinia": "^2.2.6","vue": "^3.5.12","vue-router": "^4.4.5"},"devDependencies": {"@vitejs/plugin-vue": "^5.1.4","typescript": "~5.6.2","vite": "^5.4.10","vue-tsc": "^2.1.8"}
}
3、创建必要的文件结构
├── src/
│   ├── assets/
│   ├── api/
│   ├── components/
│   ├── layouts/
│   ├── router/
│   ├── store/
│   ├── types/
│   ├── utils/
│   └── views/
4、在main.ts引入router 、pinia、elementPlus
import { createApp } from 'vue'
import './style.css'
import App from './App.vue'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
import { createPinia } from 'pinia'
import router from './router' 
const app = createApp(App)
const pinia = createPinia()
app.use(pinia) 
app.use(router) 
app.use(ElementPlus) 
app.mount('#app')
5、在vite.config.ts进行别名alias和base地址配置
import { defineConfig } from 'vite'
import path from 'path'
import vue from '@vitejs/plugin-vue'
export default defineConfig({plugins: [vue()],base: '/',resolve: {alias: {'@': path.resolve(__dirname, './src')}}
})

这里如果采用的是ts的写法,配置完可能不会生效,解决方案可以参考
ts兼容别名处理

6、新建router/index.ts管理项目路由
import { createRouter, createWebHistory } from 'vue-router'
import Layout from '@/layouts/BasicLayout.vue'
const routes = [{path: '/login',component: () => import('@/views/Login.vue'),meta: { requiresAuth: false }},{path: '/',component: Layout,meta: { requiresAuth: true },children: [{path: '',redirect: '/dashboard'},{path: 'dashboard',component: () => import('@/views/Dashboard.vue')},{path: 'users',component: () => import('@/views/user/UserList.vue')}]}
]const router = createRouter({history: createWebHistory(),routes
})router.beforeEach((to, from, next) => {const token = localStorage.getItem('token')if (to.meta.requiresAuth && !token) {next('/login')} else {next()}
})export default router 
7、新建公共组件layouts/BasicLayout.vue
<template><div class="basic-layout"><header class="header"><h1 class="logo">My Application</h1><nav class="nav"><router-linkto="/dashboard"class="nav-item":class="{ active: isActive('/dashboard') }"@click="setActive('/dashboard')">Dashboard</router-link><router-linkto="/users"class="nav-item":class="{ active: isActive('/users') }"@click="setActive('/users')">Users</router-link></nav></header><main class="main"><router-view /></main><footer class="footer"><p>&copy; 2024 My Application</p></footer></div>
</template><script setup lang="ts">
import { useRoute } from 'vue-router'const activeMenu = ref('')// 获取当前路由
const route = useRoute()// 设置选中的菜单项
const setActive = (menu: string) => {activeMenu.value = menu
}// 检查当前菜单项是否为选中状态
const isActive = (menu: string) => {return activeMenu.value === menu || route.path === menu
}// 初始化选中的菜单项
setActive(route.path)
</script><style scoped>
.basic-layout {display: flex;flex-direction: column;min-height: 100vh;
}.header {background-color: #282c34;color: white;padding: 20px;display: flex;justify-content: space-between;align-items: center;
}
.main {flex: 1; /* 使主内容区域占据剩余空间 */background-color: #f4f4f4; /* 浅色背景 */padding: 20px; /* 内边距 */
}.footer {background-color: #282c34; /* 深色背景 */color: white; /* 白色文本 */text-align: center; /* 中心对齐 */padding: 10px; /* 内边距 */
}
.logo {font-size: 24px;font-weight: bold;
}.nav {display: flex;
}.nav-item {color: white;text-decoration: none;padding: 10px 15px;transition: background-color 0.3s;
}.nav-item:hover {background-color: #3a3f47;border-radius: 5px;
}.nav-item.active {background-color: #409eff; /* 选中状态的背景色 */border-radius: 5px; /* 圆角 */
}
</style>

这里可能会报错ref找不到相应的模块,这是可以采用自动导入插件unplugin-auto-import

可以参考 unplugin-auto-import自动导入

8、改写app.vue
<template><div id="app"><router-view /></div>
</template><script setup lang="ts"></script><style>
body {margin: 0;font-family: Arial, sans-serif;background-color: #f4f4f4;
}#app {min-height: 100vh;width: 100%;
}
</style>
9、新建views/Login.vue
<template><div class="login-container"><el-card class="login-card" shadow="hover"><h2 class="login-title">系统登录</h2><el-form :model="loginForm" @submit.prevent="handleLogin"><el-form-item><el-inputv-model="loginForm.username"placeholder="用户名":prefix-icon="User"class="input-field"/></el-form-item><el-form-item><el-inputv-model="loginForm.password"type="password"placeholder="密码":prefix-icon="Lock"class="input-field"/></el-form-item><el-form-item class="button-container"><el-button type="primary" native-type="submit" class="login-button">登录</el-button></el-form-item></el-form></el-card></div>
</template><script setup lang="ts">
import { ref } from 'vue'
import { useRouter } from 'vue-router'
import { useUserStore } from '../store/user'
import type { LoginForm } from '../types/user'
import { User, Lock } from '@element-plus/icons-vue'
const router = useRouter()
const userStore = useUserStore()const loginForm = ref<LoginForm>({username: '',password: ''
})const handleLogin = async () => {try {await userStore.login(loginForm.value)router.push('/')} catch (error) {console.error(error)}
}
</script><style scoped>
* {margin: 0;padding: 0;box-sizing: border-box;
}html, body {height: 100%;overflow: hidden; /* Prevent scrollbars */
}.login-container {height: 100vh;display: flex;justify-content: center;align-items: center;background-color: #e9ecef; /* Light background color */
}.login-card {width: 400px; /* Increased width for better aesthetics */padding: 20px; /* Padding for the card */border-radius: 10px; /* Rounded corners */box-shadow: 0 4px 20px rgba(0, 0, 0, 0.1); /* Soft shadow */background-color: #ffffff; /* White background for the card */
}.login-title {text-align: center;margin-bottom: 20px; /* Space below the title */font-size: 24px; /* Larger font size */color: #333; /* Darker text color */
}.input-field {margin-bottom: 15px; /* Space between input fields */
}.button-container {display: flex; /* Use flexbox for centering */justify-content: center; /* Center the button horizontally */
}.login-button {background-color: #409eff; /* Primary color */color: #fff; /* Text color */border: none; /* Remove border */border-radius: 5px; /* Rounded corners */padding: 10px 20px; /* Padding for the button */font-size: 16px; /* Button font size */transition: background-color 0.3s, transform 0.2s; /* Transition effects */width: 100%; /* Make button full width */
}.login-button:hover {background-color: #66b1ff; /* Lighter color on hover */transform: translateY(-2px); /* Slight lift effect */
}.login-button:active {background-color: #007bff; /* Darker color on click */transform: translateY(0); /* Reset lift effect */
}
</style> 
10、新建store/user.ts进行全局变量状态管理
import { defineStore } from 'pinia'
import { login } from '@/api/user'
import type { LoginForm, UserInfo } from '@/types/user'export const useUserStore = defineStore('user', {state: () => ({token: localStorage.getItem('token') || '',userInfo: null as UserInfo | null}),actions: {async login(loginForm: LoginForm) {const { token, userInfo } = await login(loginForm)this.token = tokenthis.userInfo = userInfolocalStorage.setItem('token', token)},logout() {this.token = ''this.userInfo = nulllocalStorage.removeItem('token')}}
}) 
11、新建api/user.ts定义接口请求方法
import axios from 'axios';
import type { LoginForm, UserInfo } from '@/types/user';export async function login(loginForm: LoginForm): Promise<{ token: string; userInfo: UserInfo }> {try {const response = await axios.post('/api/login', loginForm);return response.data;} catch (error) {console.error('Login failed:', error);throw new Error('Login failed');}
} 
12、新建types/user.ts定义接口interface
export interface LoginForm {username: stringpassword: string
}export interface UserInfo {id: stringusername: string
} 
13、新建utils/request.ts定义请求配置以及拦截器
import axios from 'axios'
import { ElMessage } from 'element-plus'const request = axios.create({baseURL: '/',timeout: 6000
})request.interceptors.request.use(config => {const token = localStorage.getItem('token')if (token) {config.headers.Authorization = `Bearer ${token}`}return config},error => {return Promise.reject(error)}
)request.interceptors.response.use(response => response.data,error => {ElMessage.error(error.response?.data?.message || '请求失败')return Promise.reject(error)}
)export default request 
14、项目安装mock进行接口请求模拟数据处理
1、安装依赖
npm i mockjs vite-plugin-mock --save-dev
2、新建src/mock/index.ts定义模拟返回数据
// mock/index.js
export default [{type: 'get',url: '/api/login',response: () => {return {token: '1234567890',userInfo: {name: 'admin',avatar: 'https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif'}}}
}]
3、main.ts引入
import './mock/index.ts' 
4、vite.config.ts进行配置引入
import { defineConfig } from 'vite'
import path from 'path'
import vue from '@vitejs/plugin-vue'
import AutoImport from 'unplugin-auto-import/vite';
import { viteMockServe } from 'vite-plugin-mock'
// https://vite.dev/config/
export default defineConfig({plugins: [vue(),AutoImport({imports:['vue','vue-router'],dts: 'src/auto-imports.d.ts'}),viteMockServe({mockPath: 'src/mock/',enable: true})],base: '/',resolve: {alias: {'@': path.resolve(__dirname, './src')},extensions: ['.mjs', '.js', '.ts', '.jsx', '.tsx', '.json', '.vue']}
})

有可能引用不生效可以参考mock数据处理

15、项目首页新建view/Dashboard.vue
<template><div class="dashboard"><h2>Dashboard</h2><p>Welcome to the dashboard! Here you can find an overview of your application.</p><div class="stats"><div class="stat-card"><h3>Total Users</h3><p>{{ totalUsers }}</p></div><div class="stat-card"><h3>Total Posts</h3><p>{{ totalPosts }}</p></div><div class="stat-card"><h3>Total Comments</h3><p>{{ totalComments }}</p></div></div></div>
</template><script setup lang="ts">
import { ref } from 'vue'// 定义响应式数据
const totalUsers = ref(100) // 示例数据
const totalPosts = ref(50)   // 示例数据
const totalComments = ref(200) // 示例数据
</script><style scoped>
.dashboard {padding: 1rem;
}.stats {display: flex;justify-content: space-around;margin-top: 2rem;
}.stat-card {border: 1px solid #ccc;border-radius: 8px;padding: 1rem;width: 30%;text-align: center;
}
</style>
15、项目用户管理新建view/user/UserList.vue
<template><div class="user-list"><h2>User List</h2><table><thead><tr><th>ID</th><th>Name</th><th>Email</th><th>Actions</th></tr></thead><tbody><tr v-for="user in users" :key="user.id"><td>{{ user.id }}</td><td>{{ user.name }}</td><td>{{ user.email }}</td><td><button @click="editUser(user.id)">Edit</button><button @click="deleteUser(user.id)">Delete</button></td></tr></tbody></table></div>
</template><script setup lang="ts">
import { ref } from 'vue'// 示例用户数据
const users = ref([{ id: 1, name: 'Alice', email: 'alice@example.com' },{ id: 2, name: 'Bob', email: 'bob@example.com' },{ id: 3, name: 'Charlie', email: 'charlie@example.com' }
])// 编辑用户的函数
const editUser = (id: number) => {console.log(`Edit user with ID: ${id}`)// 在这里添加编辑用户的逻辑
}// 删除用户的函数
const deleteUser = (id: number) => {console.log(`Delete user with ID: ${id}`)// 在这里添加删除用户的逻辑
}
</script><style scoped>
.user-list {padding: 1rem;
}table {width: 100%;border-collapse: collapse;
}th, td {border: 1px solid #ccc;padding: 0.5rem;text-align: left;
}button {margin-right: 0.5rem;
}
</style>

至此用户相关前端部分基础完成,运行项目可以看到效果

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
附加 package.json:

{"name": "admin-frontend","private": true,"version": "0.0.0","type": "module","scripts": {"dev": "vite","build": "vue-tsc -b && vite build","preview": "vite preview"},"dependencies": {"@element-plus/icons-vue": "^2.3.1","axios": "^1.7.7","element-plus": "^2.8.7","pinia": "^2.2.6","vite-plugin-mock": "^3.0.2","vue": "^3.5.12","vue-router": "^4.4.5"},"devDependencies": {"@types/mockjs": "^1.0.10","@types/node": "^22.9.0","@vitejs/plugin-vue": "^5.1.4","mockjs": "^1.1.0","typescript": "~5.6.2","unplugin-auto-import": "^0.18.4","vite": "^5.4.10","vue-tsc": "^2.1.8"}
}
关键字:seo教程技术整站优化_武汉人才网官方网站入口_国内广告投放平台_查询网

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

责任编辑: