Element Plus 组件库 + 美化页面
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) return
await 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) return
await 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。
浙公网安备 33010602011771号