首页 > 文章列表 > VUE3入门实例:构建一个简单的图片库管理系统

VUE3入门实例:构建一个简单的图片库管理系统

vue 管理系统 图片库
473 2023-06-15

随着互联网的发展,图片成为网站、移动应用、企业、个人信息化建设中必不可少的一部分。如何高效地管理和使用图片,已经成为一个技术难题。在这个背景下,我们可以使用Vue3构建一个简单的图片库管理系统,帮助我们高效地管理和使用图片。

  1. 系统需求

我们需要一个简单的图片库管理系统,能够实现以下功能:

• 添加图片:能够上传、选择图片,并填写图片名称、描述等信息。

• 删除图片:从图片库中删除选中的图片。

• 编辑图片:能够编辑选中的图片名称、描述等信息。

• 搜索图片:能够按照图片名称、描述等信息查找图片。

  1. 技术实现方案

我们选择使用Vue3作为前端框架,使用Element-Plus作为UI组件库,后端使用Node.js,数据库使用MongoDB。其中,我们使用axios实现前后端的数据交互,并且采用JSON格式进行数据的传输。

  1. 系统模块设计

系统主要分为三个模块:图片展示、图片上传与管理、搜索与过滤。具体实现如下:

• 图片展示模块:展示当前用户拥有的所有图片,并且可以点击图片查看其详细信息。

• 图片上传与管理模块:提供上传图片、删除图片、编辑图片信息等功能,管理用户的图片信息。

• 搜索与过滤模块:提供搜索图片、过滤图片、按时间分类等功能,帮助用户快速查找需要的图片。

  1. 系统实现

在实现前,需要安装Vue3的脚手架,搭建一个简单的框架。

  1. 安装vue-cli脚手架

使用终端或命令行工具输入以下命令安装:

npm install -g @vue/cli
  1. 构建项目

使用以下命令构建Vue3项目:

vue create my-project
  1. 安装相关依赖库

使用以下命令安装Element-Plus和axios:

npm i element-plus axios
  1. 设计路由和页面

在src/router/index.js文件中增加以下代码:

import { createRouter, createWebHashHistory } from 'vue-router'
import Home from '../views/Home.vue'
import AddImage from '../views/AddImage.vue'
import ImageDetail from '../views/ImageDetail.vue'

const routes = [
  {
    path: '/',
    name: 'Home',
    component: Home
  },
  {
    path: '/add-image',
    name: 'AddImage',
    component: AddImage
  },
  {
    path: '/image-detail/:id',
    name: 'ImageDetail',
    component: ImageDetail
  }
]

const router = createRouter({
  history: createWebHashHistory(),
  routes
})

export default router

在src/views/文件夹下面新建三个组件文件:Home.vue、AddImage.vue和ImageDetail.vue,然后分别编写对应的界面:

<!-- Home.vue -->
<template>
  <div>
    <h2 class="title">图片列表</h2>
    <div class="list">
      <div class="item" v-for="image in images" :key="image.id">
        <img :src="image.src" @click="toDetail(image.id)" />
        <p class="name">{{ image.name }}</p>
      </div>
    </div>
  </div>
</template>

<script>
import { reactive, onMounted } from 'vue'
import axios from 'axios'
export default {
  name: 'Home',
  setup() {
    const state = reactive({
      images: []
    })
    const getData = async () => {
      const res = await axios.get('/api/images')
      state.images = res.data.list
    }
    const toDetail = id => {
      this.$router.push({ path: `/image-detail/${id}` })
    }
    onMounted(() => {
      getData()
    })
    return {
      images: state.images,
      toDetail
    }
  }
}
</script>

<style scoped>
/* 样式省略 */
</style>


<!-- AddImage.vue -->
<template>
  <div>
    <h2 class="title">上传图片</h2>
    <form class="form" @submit.prevent="submit">
      <div class="form-group">
        <label>名称:</label>
        <input type="text" v-model="name" />
      </div>
      <div class="form-group">
        <label>描述:</label>
        <input type="text" v-model="description" />
      </div>
      <div class="form-group">
        <input type="file" ref="file" @change="getFile" />
      </div>
      <div class="form-action">
        <button class="submit" type="submit">上传</button>
      </div>
    </form>
  </div>
</template>

<script>
import { reactive } from 'vue'
import axios from 'axios'

export default {
  name: 'AddImage',
  setup() {
    const state = reactive({
      name: '',
      description: '',
      file: null
    })
    const submit = async () => {
      if (!state.file) {
        alert('没有选择图片')
        return
      }
      const formData = new FormData()
      formData.append('file', state.file)
      formData.append('name', state.name)
      formData.append('description', state.description)
      await axios.post('/api/image', formData)
      this.$router.push({ path: '/' })
    }
    const getFile = e => {
      const file = e.target.files[0]
      state.file = file
    }
    return {
      name: state.name,
      description: state.description,
      submit,
      getFile
    }
  }
}
</script>

<style scoped>
/* 样式省略 */
</style>



<!-- ImageDetail.vue -->
<template>
  <div class="detail">
    <h2 class="title">{{ image.name }}</h2>
    <img :src="image.src" />
    <div class="description">{{ image.description }}</div>
  </div>
</template>

<script>
import { reactive, onMounted } from 'vue'
import axios from 'axios'
export default {
  name: 'ImageDetail',
  setup(props) {
    const state = reactive({
      image: {}
    })
    const getData = async () => {
      const id = props.route.params.id
      const res = await axios.get(`/api/image/${id}`)
      state.image = res.data.data
    }
    onMounted(() => {
      getData()
    })
    return {
      image: state.image
    }
  }
}
</script>

<style scoped>
/* 样式省略 */
</style>
  1. 实现系统功能

在src/api/文件夹中,新建api.js文件,封装前后端交互的代码:

import axios from 'axios'

export const getImages = async () => {
  const res = await axios.get('/api/images')
  return res.data.list
}

export const addImage = async (data) => {
  await axios.post('/api/image', data)
}

export const deleteImage = async (id) => {
  await axios.delete(`/api/image/${id}`)
}

export const getImage = async (id) => {
  const res = await axios.get(`/api/image/${id}`)
  return res.data.data
}

export const updateImage = async (id, data) => {
  await axios.put(`/api/image/${id}`, data)
}

export const searchImages = async (keywords) => {
  const res = await axios.get(`/api/images?keywords=${keywords}`)
  return res.data.list
}

在src/store/文件夹中,新建store.js文件,封装状态管理的代码:

// store.js
import { reactive } from 'vue'
import { getImages, addImage, deleteImage, getImage, updateImage, searchImages } from '../api/api'

const store = reactive({
  images: [],
  searchTxt: '',
  setSearchTxt(txt) {
    this.searchTxt = txt
  },
  async getImages() {
    this.images = await getImages()
  },
  async deleteImage(id) {
    await deleteImage(id)
    this.getImages()
  },
  async addImage(data) {
    await addImage(data)
    this.getImages()
  },
  async getImage(id) {
    const res = await getImage(id)
    return res
  },
  async updateImage(id, data) {
    await updateImage(id, data)
    this.getImages()
  },
  async searchImages() {
    if (!this.searchTxt) {
      this.getImages()
    } else {
      this.images = await searchImages(this.searchTxt)
    }
  }
})

export default store

在src/main.js文件中,引入store和Element-Plus组件库,并挂载Vue实例:

import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import store from './store/store'
import ElementPlus from 'element-plus'
import 'element-plus/lib/theme-chalk/index.css'
const app = createApp(App)

app.use(ElementPlus)
app.use(store)
app.use(router)

app.mount('#app')

系统的核心逻辑已经实现。我们可以使用以下命令启动前端服务器:

npm run serve

在另一个终端或命令行工具中启动后端服务器:

node server.js

现在,我们就可以使用浏览器打开localhost:8080,进入图片管理系统。

  1. 总结

通过使用Vue3构建一个简单的图片库管理系统,我们可以掌握基本的Vue3应用开发,理解组件化和状态管理的思想,同时也学习了Element-Plus组件库和axios库的使用。希望本文能够帮助你快速理解Vue3的开发思想和应用场景。