手拉手带你用 vite2 + vue3 + elementPlus 做个博客尝尝鲜(四)

简介: 这里主要是体验一下 vite2 + vue3 做项目是什么样子的,重点在于 vite2 + vue3 方面的介绍,博客只是一个例子,所以博客的功能比较弱,只实现了几个最基本的功能。

博文内容 + 讨论

<template>
  <el-row :gutter="12">
    <el-col :span="5">
      <!--分组-->
      <blogGroup :isDetail="true"/>
    </el-col>
    <el-col :span="18">
      <!--显示博文-->
      <h1>{{blogInfo.title}}</h1>
      ({{dateFormat(blogInfo.addTime).format('YYYY-MM-DD')}})
      <v-md-preview :text="blogInfo.concent"></v-md-preview>
      <hr>
      <!--讨论列表-->
      <discussList :id="id"/>
      <!--讨论表单-->
      <discussForm :id="id"/>
    </el-col>
  </el-row>
</template>
【引入的代码略】
// 组件的属性,博文ID
const props = defineProps({
  id: String
})
// 管理
const { getArtcileById } = blogManage()
// 表单的model
const blogInfo = reactive({})
getArtcileById(props.id).then((data) => {
  Object.assign(blogInfo, data)
})

这个代码就很简单了,因为只实现了基本的发讨论和显示讨论的功能,其他暂略。

看看效果:

50.png


好吧,这个讨论做的蛮敷衍的,其实有好多想法,只是篇幅有限,以后再介绍。

组件级别的代码

虽然在vue里面,除了js文件,就是vue文件了,但是我觉得还是应该细分一下。比如上面都是是页面级的代码,下面这些是“组件”级别的代码了。

1

博文分组

多次提到的博文分组。

<template>
  <!--分组,分为显示状态和编辑状态-->
  <el-card shadow="hover"
    v-for="(item, index) in blogGroupList"
    :key="'grouplist_' + index"
  >
    <template #header>
      <div class="card-header">
        <span>{{item.label}}</span>
        <span class="button"></span>
      </div>
    </template>
    <div
      class="text item"
      style="cursor:pointer"
      v-for="(item, index) in item.children"
      :key="'group_' + index"
      @click="changeGroup(item.value)"
    >
      {{item.label}}
    </div>
  </el-card>
</template>

暂时先用 el-card 来实现,后期会改成 NavMenu 来实现。

【引入的代码略】
// 组件的属性
const props = defineProps({
  isDetail: Boolean
})
/** 
* 博文的分组列表
*/
const blogGroupList = reactive([
  {
    value: '1000',
    label: '前端',
    children: [
      {  value: '1001', label: 'vue基础知识',  },
      {  value: '1002', label: 'vue组件',     },
      {  value: '1003', label: 'vue路由',     }
    ]
  },
  {  value: '2000',  label: '后端',
     children: [
      { value: '2001', label: 'MySQL',     },
      { value: '2002', label: 'web服务',    }
    ]
  }
])
// 选择分组
const { setCurrentGroupId } = blogStateManage()
const router = useRouter()
const changeGroup = (id) => {
  setCurrentGroupId(id)
  // 判断是不是要跳转
  // 首页、编辑页不跳,博文详细页面调整 
  if (props.isDetail) {
    // 跳转到列表页
    router.push({ name: 'groups', params: { groupId: id }})
  }
}

分组数据暂时写死了,没有做成可以维护的方式,以后再完善。

2

博文列表,编辑用

<template>
  <!--添加标题-->
  <el-card shadow="hover">
    <template #header>
      <div class="card-header">
        <el-button @click="addNewArticle" >添加新文章</el-button>
        <span class="button"></span>
      </div>
    </template>
    <div
      class="text item"
      style="cursor:pointer"
      v-for="(item, index) in blogList"
      :key="'article_' + index"
      @click="changeArticle(item.ID)"
    >
      {{item.ID}}:{{item.title}} ({{dateFormat(item.addTime).format('YYYY-MM-DD')}})
    </div>
    <el-empty description="该分类里面还没有文章呢。" v-if="blogList.length === 0"></el-empty>
  </el-card>
</template>

用 el-card 做个列表,上面是 添加博文的按钮,下面是博文列表,单击可以进行修改。

【引入的代码略】
// 博文列表
const blogList = reactive([])
// 博文管理
const { addNewBlog, getBlogListByGroupId } = blogManage()
// 状态管理
const { getBlogState, setEditArticleId } = blogStateManage()
// 博文的状态
const blogState = getBlogState()
// 更新列表
const load = () => {
  getBlogListByGroupId(blogState.currentGroupId).then((data) => {
    blogList.length = 0
    blogList.push(...data)
  })
}
load()
// 监控选择的分组的ID
watch(() => blogState.currentGroupId, () => {
  load()
})
// 添加新文章,仅标题、时间
const addNewArticle = () => {
  const newArticle = blogForm()
  // 选择的分组ID
  newArticle.groupId = blogState.currentGroupId
  // 用日期作为默认标题
  newArticle.title = dayjs(new Date()).format('YYYY-MM-DD')
  addNewBlog(newArticle).then((id) => {
    // 设置要编辑的文章ID
    setEditArticleId(id)
    // 通知列表
    newArticle.ID = id
    blogList.unshift(newArticle)
  })
}
// 选择要编辑的文章
const changeArticle = (id) => {
  setEditArticleId(id)
}

3

讨论列表

<el-card shadow="hover"
    v-for="(item, index) in discussList"
    :key="'bloglist_' + index"
  >
    <template #header>
      <div class="card-header">
        {{item.discusser}}
        <span class="button">({{dateFormat(item.addTime).format('YYYY-MM-DD')}})</span>
      </div>
    </template>
    <!--简介-->
    <div class="text item" v-html="item.concent"></div>
    <hr>
    <i class="el-icon-circle-check"></i>&nbsp;{{item.agreeCount}}&nbsp;&nbsp;
  </el-card>
  <!--没有找到数据-->
  <el-empty description="没有讨论呢,抢个沙发呗。" v-if="discussList.length === 0"></el-empty>

还是用 el-card 做个列表,el-empty 做一个没有讨论的提示。

【引入的代码略】
// 组件的属性
const props = defineProps({
  id: String
})
// 管理
const { getDiscussListByBlogId } = blogManage()
// 获取状态
const { getBlogState } = blogStateManage()
const blogState = getBlogState()
// 表单的model
const discussList = reactive([])
getDiscussListByBlogId(props.id).then((data) => {
  discussList.push(...data)
})
watch(() => blogState.isReloadDiussList, () => {
  getDiscussListByBlogId(props.id).then((data) => {
    discussList.length = 0
    discussList.push(...data)
  })
})

因为功能比较简单,所以代码也很简单,获取讨论数据绑定显示即可,暂时没有实现分页功能。

4

讨论表单

<el-form
    style="width:400px;"
    label-position="top"
    :model="dicussModel"
    label-width="80px"
  >
  <el-form-item label="昵称">
    <el-input v-model="dicussModel.discusser"></el-input>
  </el-form-item>
  <el-form-item label="内容">
    <el-input type="textarea" v-model="dicussModel.concent"></el-input>
  </el-form-item>
  <el-form-item>
    <el-button type="primary" @click="submit">发表讨论</el-button>
    <el-button>取消</el-button>
  </el-form-item>
</el-form>

用 el-form 做个表单。

【引入的代码略】
// 组件的属性
const props = defineProps({
  id: String
})
// 管理
const { addDiuss } = blogManage()
// 获取状态
const { getBlogState, setReloadDiussList } = blogStateManage()
const blogState = getBlogState()
// 表单的model
const dicussModel = reactive(discuss())
// 发布讨论
const submit = () => {
  dicussModel.blogId = props.id // 这是博文ID
  addDiuss(dicussModel).then((id) => { // 可以想象成 axios 的提交
      // 通知列表
    setReloadDiussList()
  })
}

分成多个组件,每个组件的代码就可以非常少了,这样便于维护。发布讨论的函数,先使用blogManage的功能提交数据,回调函数里面,使用的状态管理的功能提醒讨论列表刷新数据。

源码

https://gitee.com/naturefw/vue3-blog


52.png


52.png



在线演示

https://naturefw.gitee.io/vue3-blog

本文作者:自然框架

个人网址:jyk.cnblogs.com

声明:本文为 脚本之家专栏作者 投稿,未经允许请勿转载。


相关文章
|
2月前
|
JavaScript 前端开发 安全
Vue 3
Vue 3以组合式API、Proxy响应式系统和全面TypeScript支持,重构前端开发范式。性能优化与生态协同并进,兼顾易用性与工程化,引领Web开发迈向高效、可维护的新纪元。(238字)
529 139
|
2月前
|
缓存 JavaScript 算法
Vue 3性能优化
Vue 3 通过 Proxy 和编译优化提升性能,但仍需遵循最佳实践。合理使用 v-if、key、computed,避免深度监听,利用懒加载与虚拟列表,结合打包优化,方可充分发挥其性能优势。(239字)
248 1
|
7月前
|
缓存 JavaScript PHP
斩获开发者口碑!SnowAdmin:基于 Vue3 的高颜值后台管理系统,3 步极速上手!
SnowAdmin 是一款基于 Vue3/TypeScript/Arco Design 的开源后台管理框架,以“清新优雅、开箱即用”为核心设计理念。提供角色权限精细化管理、多主题与暗黑模式切换、动态路由与页面缓存等功能,支持代码规范自动化校验及丰富组件库。通过模块化设计与前沿技术栈(Vite5/Pinia),显著提升开发效率,适合团队协作与长期维护。项目地址:[GitHub](https://github.com/WANG-Fan0912/SnowAdmin)。
1007 5
|
3月前
|
开发工具 iOS开发 MacOS
基于Vite7.1+Vue3+Pinia3+ArcoDesign网页版webos后台模板
最新版研发vite7+vue3.5+pinia3+arco-design仿macos/windows风格网页版OS系统Vite-Vue3-WebOS。
408 11
|
2月前
|
JavaScript 安全
vue3使用ts传参教程
Vue 3结合TypeScript实现组件传参,提升类型安全与开发效率。涵盖Props、Emits、v-model双向绑定及useAttrs透传属性,建议明确声明类型,保障代码质量。
283 0
|
4月前
|
缓存 前端开发 大数据
虚拟列表在Vue3中的具体应用场景有哪些?
虚拟列表在 Vue3 中通过仅渲染可视区域内容,显著提升大数据列表性能,适用于 ERP 表格、聊天界面、社交媒体、阅读器、日历及树形结构等场景,结合 `vue-virtual-scroller` 等工具可实现高效滚动与交互体验。
463 1
|
4月前
|
缓存 JavaScript UED
除了循环引用,Vue3还有哪些常见的性能优化技巧?
除了循环引用,Vue3还有哪些常见的性能优化技巧?
273 0
|
5月前
|
JavaScript
vue3循环引用自已实现
当渲染大量数据列表时,使用虚拟列表只渲染可视区域的内容,显著减少 DOM 节点数量。
143 0
|
7月前
|
JavaScript API 容器
Vue 3 中的 nextTick 使用详解与实战案例
Vue 3 中的 nextTick 使用详解与实战案例 在 Vue 3 的日常开发中,我们经常需要在数据变化后等待 DOM 更新完成再执行某些操作。此时,nextTick 就成了一个不可或缺的工具。本文将介绍 nextTick 的基本用法,并通过三个实战案例,展示它在表单验证、弹窗动画、自动聚焦等场景中的实际应用。
620 17
|
8月前
|
JavaScript 前端开发 算法
Vue 3 和 Vue 2 的区别及优点
Vue 3 和 Vue 2 的区别及优点

热门文章

最新文章