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。

posted on 2026-06-18 16:18  seeeaeeee  阅读(1)  评论(0)    收藏  举报