Element Plus 组件库 + 美化页面
一、操作步骤
1. 安装 Element Plus
在项目根目录终端执行:
npm install element-plus
2. 修改 main.js(全局引入 Element Plus)
将 src/main.js 替换为以下完整代码:
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import { createPinia } from 'pinia'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'const app = createApp(App)
app.use(router)
app.use(createPinia())
app.use(ElementPlus)
app.mount('#app')
3. 修改 Login.vue(使用 Element Plus 表单)
将 src/views/Login.vue 替换为以下完整代码:
<template><div class="login-container"><el-card class="login-card"><h2>微头条登录</h2><el-form :model="form" :rules="rules" ref="formRef"><el-form-item prop="username"><el-input v-model="form.username" placeholder="用户名" prefix-icon="User" /></el-form-item><el-form-item prop="password"><el-input v-model="form.password" type="password" placeholder="密码" prefix-icon="Lock" /></el-form-item><el-form-item><el-button type="primary" @click="handleLogin" style="width:100%">登录</el-button></el-form-item></el-form><div class="register-link"><router-link to="/register">立即注册</router-link></div></el-card></div>
</template><script setup>
import { reactive, ref } from 'vue'
import { useRouter } from 'vue-router'
import { useUserStore } from '../stores/user'
import { login } from '../api/user'
import { ElMessage } from 'element-plus'const form = reactive({ username: '', password: '' })
const rules = {username: [{ required: true, message: '请输入用户名', trigger: 'blur' }],password: [{ required: true, message: '请输入密码', trigger: 'blur' }]
}
const router = useRouter()
const userStore = useUserStore()
const formRef = ref(null)const handleLogin = async () => {if (!formRef.value) returnawait formRef.value.validate(async (valid) => {if (valid) {try {const res = await login({ username: form.username })if (res.length > 0 && res[0].password === form.password) {userStore.setUser(form.username, 'fake-token')ElMessage.success('登录成功')router.push('/home')} else {ElMessage.error('用户名或密码错误')}} catch {ElMessage.error('登录请求失败')}}})
}
</script><style scoped>
.login-container {height: 100vh;display: flex;justify-content: center;align-items: center;background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
}
.login-card {width: 400px;
}
.register-link {text-align: center;margin-top: 16px;
}
</style>
4. 修改 Register.vue(使用 Element Plus,如没有则创建)
创建 src/views/Register.vue,完整代码如下:
<template><div class="register-container"><el-card class="register-card"><h2>微头条注册</h2><el-form :model="form" :rules="rules" ref="formRef"><el-form-item prop="username"><el-input v-model="form.username" placeholder="用户名" /></el-form-item><el-form-item prop="password"><el-input v-model="form.password" type="password" placeholder="密码" /></el-form-item><el-form-item prop="confirmPassword"><el-input v-model="form.confirmPassword" type="password" placeholder="确认密码" /></el-form-item><el-form-item><el-button type="primary" @click="handleRegister" style="width:100%">注册</el-button></el-form-item></el-form><div class="login-link"><router-link to="/login">已有账号?去登录</router-link></div></el-card></div>
</template><script setup>
import { reactive, ref } from 'vue'
import { useRouter } from 'vue-router'
import { useUserStore } from '../stores/user'
import { register } from '../api/user'
import { ElMessage } from 'element-plus'const form = reactive({ username: '', password: '', confirmPassword: '' })
const rules = {username: [{ required: true, message: '请输入用户名', trigger: 'blur' }],password: [{ required: true, message: '请输入密码', trigger: 'blur' }],confirmPassword: [{ required: true, message: '请再次输入密码', trigger: 'blur' },{validator: (rule, value, callback) => {if (value !== form.password) {callback(new Error('两次输入密码不一致'))} else {callback()}},trigger: 'blur'}]
}
const router = useRouter()
const userStore = useUserStore()
const formRef = ref(null)const handleRegister = async () => {if (!formRef.value) returnawait formRef.value.validate(async (valid) => {if (valid) {try {const newUser = { id: Date.now(), username: form.username, password: form.password }await register(newUser)userStore.setUser(form.username, 'fake-token')ElMessage.success('注册成功,已自动登录')router.push('/home')} catch {ElMessage.error('注册失败,用户名可能已存在')}}})
}
</script><style scoped>
.register-container {height: 100vh;display: flex;justify-content: center;align-items: center;background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
}
.register-card {width: 400px;
}
.login-link {text-align: center;margin-top: 16px;
}
</style>
5. 修改 src/api/user.js(添加 register 方法)
将 src/api/user.js 替换为以下完整代码:
javascript
import request from '@/utils/request'export const login = (data) => {return request.get('/users', { params: { username: data.username } })
}export const register = (data) => {return request.post('/users', data)
}
6. 修改 src/views/Home.vue(使用 Element Plus 表格)
将 src/views/Home.vue 替换为以下完整代码(注意:暂不依赖 api/news.js,先使用 Mock 数据,课次9再替换为真实 API):
vue
<template><div class="container"><div class="header"><h2>微头条首页</h2><div>欢迎,{{ userStore.username }}</div><el-button type="danger" @click="logout">退出</el-button></div><div class="publish-area"><el-input v-model="newTitle" placeholder="新闻标题" style="flex:1" /><el-input v-model="newContent" placeholder="新闻内容" style="flex:2" /><el-button type="primary" @click="addNews">发布微头条</el-button></div><el-table :data="newsList" style="width:100%"><el-table-column prop="title" label="标题" /><el-table-column prop="time" label="时间" width="180" /><el-table-column prop="likes" label="点赞数" width="100" /><el-table-column label="操作" width="200"><template #default="{ row }"><el-button type="text" @click="viewDetail(row.id)">查看详情</el-button><el-button type="text" @click="deleteNews(row.id)">删除</el-button><el-button type="text" @click="likeNews(row.id, row.likes)">点赞</el-button></template></el-table-column></el-table></div>
</template><script setup>
import { ref } from 'vue'
import { useRouter } from 'vue-router'
import { useUserStore } from '../stores/user'
import { ElMessage } from 'element-plus'const router = useRouter()
const userStore = useUserStore()// Mock 数据,课次9会替换为从后端加载
const newsList = ref([{ id: 1, title: '微头条1.0 正式发布', time: '2025-06-01 10:30:00', content: '内容...', likes: 5 },{ id: 2, title: 'Vue3 组合式 API 学习心得', time: '2025-06-02 15:20:00', content: '内容...', likes: 8 }
])
const newTitle = ref('')
const newContent = ref('')const addNews = () => {if (!newTitle.value.trim() || !newContent.value.trim()) {ElMessage.warning('标题和内容不能为空')return}const newNews = {id: Date.now(),title: newTitle.value,content: newContent.value,time: new Date().toLocaleString(),likes: 0}newsList.value.unshift(newNews)ElMessage.success('发布成功')newTitle.value = ''newContent.value = ''
}const deleteNews = (id) => {newsList.value = newsList.value.filter(item => item.id !== id)ElMessage.success('删除成功')
}const likeNews = (id, currentLikes) => {const item = newsList.value.find(i => i.id === id)if (item) item.likes = currentLikes + 1
}const viewDetail = (id) => {router.push(`/detail/${id}`)
}const logout = () => {userStore.logout()router.push('/login')
}
</script><style scoped>
.container {max-width: 1000px;margin: 20px auto;padding: 20px;
}
.header {display: flex;justify-content: space-between;align-items: center;margin-bottom: 20px;
}
.publish-area {display: flex;gap: 10px;margin-bottom: 20px;
}
</style>
7. 修改 src/router/index.js(添加注册页路由)
将 src/router/index.js 替换为以下完整代码:
javascript
import { createRouter, createWebHistory } from 'vue-router'
import Login from '../views/Login.vue'
import Register from '../views/Register.vue'
import Home from '../views/Home.vue'const routes = [{ path: '/', redirect: '/login' },{ path: '/login', component: Login },{ path: '/register', component: Register },{ path: '/home', component: Home }
]const router = createRouter({history: createWebHistory(),routes
})router.beforeEach((to, from, next) => {const token = localStorage.getItem('token')if (to.path === '/home' && !token) {next('/login')} else {next()}
})export default router
8. 启动项目测试
确保 json-server 已启动(npx json-server --watch db.json --port 3000),然后运行:
bash
npm run dev
访问 http://localhost:5173,应看到 Element Plus 美化的登录页和首页,所有交互均使用 Mock 数据,不依赖后端新闻 API。