热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

使用Vue+Django+AntDesign做一个留言评论模块的示例代码

这篇文章主要介绍了使用Vue+Django+AntDesign做一个留言评论模块,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

1.总览

留言的展示参考网络上参见的格式,如掘金社区:

一共分为两层,子孙留言都在第二层中

最终效果如下:

接下是数据库的表结构,如下所示:

有一张user表和留言表,关系为一对多,留言表有父留言字段的id,和自身有一个一对多的关系,建表语句如下:

CREATE TABLE `message` (
 `id` int NOT NULL AUTO_INCREMENT,
 `date` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
 `content` text NOT NULL,
 `parent_msg_id` int DEFAULT NULL,
 `user_id` int NOT NULL,
 PRIMARY KEY (`id`),
 KEY `user_id` (`user_id`),
 KEY `message_ibfk_1` (`parent_msg_id`),
 CONSTRAINT `message_ibfk_1` FOREIGN KEY (`parent_msg_id`) REFERENCES `message` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
 CONSTRAINT `message_ibfk_2` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=18 DEFAULT CHARSET=utf8


CREATE TABLE `user` (
 `id` int NOT NULL AUTO_INCREMENT,
 `username` varchar(255) NOT NULL,
 `password` varchar(255) NOT NULL,
 `identity` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
 PRIMARY KEY (`id`),
 UNIQUE KEY `username` (`username`)
) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8

2.后台接口

 2.1获取留言接口

在Django的views.py中定义两个接口,一个负责提供留言内容,一个负责插入留言,如下:

# 获取留言信息
@require_http_methods(['GET'])
def findAllMsg(request):
  respOnse= {}
  try:
    sql = '''
    SELECT 
    msg1.*,
    user.username,
    msg2.username AS parent_msg_username
    FROM message msg1
    LEFT JOIN
    (SELECT
    m.id,
    user.username
    FROM message m
    LEFT JOIN USER
    ON m.user_id = user.id
    )AS msg2
    ON msg1.parent_msg_id = msg2.id
    LEFT JOIN USER
    ON msg1.user_id = user.id
    ORDER BY msg1.date DESC;
    '''
    with connection.cursor() as cursor:
      cursor.execute(sql)
      response['messages'] = sortMsg(cursor)
    response['status_code'] = 200
  except Exception as e:
    response['status_code'] = 500
    response['error'] = e
  
  return JsonResponse(response)

先来看看这个sql能查出些什么东西:

上面接口中的sorMsg()函数用于整理留言信息,使子留言和父留言能对应起来,算法实现如下:

# 整理留言信息返回格式
def sortMsg(cursor):
  list = []  
  allMsg = dictfetchall(cursor)
  for i in range(len(allMsg)):
    tmpParent = allMsg[i]
    tmpChild = []
    # 如果没有属于根评论,则搜索该评论下的所有子评论
    if tmpParent.get('parent_msg_id') == None:
      tmpChild = bfs(tmpParent, allMsg)
    # 如果是子评论则跳过,子评论最终会出现在根评论的子节点中
    else:
      continue
    tmpParent['children'] = tmpChild
    # 格式化时间
    tmpParent['date'] = datetime.datetime.strftime(tmpParent['date'], '%Y-%m-%d %H:%M:%S')
    list.append(tmpParent)
  return list

# 搜索一条留言的所有子留言,广度优先
import queue
def bfs(parent, allMsg):
  childrenList = []
  q = queue.Queue()
  q.put(parent)
  while(not q.empty()):
    tmpChild = q.get()
    for i in range(len(allMsg)):
      if allMsg[i]['parent_msg_id'] is not None and allMsg[i]['parent_msg_id'] == tmpChild['id']:
        childrenList.append(allMsg[i])
        q.put(allMsg[i])
  # 子留言列表按时间降序排序
  childrenList = sorted(childrenList, key = lambda d: d['date'], reverse = True)
  # 格式化日期格式
  for item in childrenList:
    item['date'] = datetime.datetime.strftime(item['date'], '%Y-%m-%d %H:%M:%S')
  return childrenList

用postman测试接口,得到的json格式如下:

{
  "messages": [
    {
      "id": 12,
      "date": "2020-05-31 12:19:43",
      "content": "你好啊,太棒了",
      "parent_msg_id": null,
      "user_id": 5,
      "username": "wangwu",
      "parent_msg_username": null,
      "children": []
    },
    {
      "id": 11,
      "date": "2020-05-31 12:18:55",
      "content": "的时刻层6666666632\n2面的思考名称看到什么材料是isdafjoisdjiojildsc",
      "parent_msg_id": null,
      "user_id": 3,
      "username": "zhangsan",
      "parent_msg_username": null,
      "children": []
    },
    {
      "id": 5,
      "date": "2020-05-29 19:09:33",
      "content": "发的发射点发吖方吖是发是呵等方5爱的非4阿瑟东方 发",
      "parent_msg_id": null,
      "user_id": 4,
      "username": "lisi",
      "parent_msg_username": null,
      "children": [
        {
          "id": 13,
          "date": "2020-05-31 12:20:12",
          "content": "号好好好矮好矮好矮好好",
          "parent_msg_id": 5,
          "user_id": 6,
          "username": "zhaoliu",
          "parent_msg_username": "lisi"
        }
      ]
    },
    {
      "id": 1,
      "date": "2020-05-29 19:06:21",
      "content": "fasfdsafas法阿萨德方吖65阿瑟东方5是的发",
      "parent_msg_id": null,
      "user_id": 1,
      "username": "student",
      "parent_msg_username": null,
      "children": [
        {
          "id": 7,
          "date": "2020-05-29 19:29:29",
          "content": "hfhf2h22h222223232",
          "parent_msg_id": 6,
          "user_id": 1,
          "username": "student",
          "parent_msg_username": "zhaoliu"
        },
        {
          "id": 6,
          "date": "2020-05-29 19:09:56",
          "content": "而离开离开邻居哦i据哦i报价哦v保健品45465",
          "parent_msg_id": 4,
          "user_id": 6,
          "username": "zhaoliu",
          "parent_msg_username": "mike"
        },
        {
          "id": 4,
          "date": "2020-05-29 19:09:14",
          "content": "发送端非场地萨擦手d5asd32 1dads\r\ndsac十多次ds出错",
          "parent_msg_id": 2,
          "user_id": 8,
          "username": "mike",
          "parent_msg_username": "lisi"
        },
        {
          "id": 3,
          "date": "2020-05-29 19:08:56",
          "content": "奋发恶法撒打发士大夫士大夫是大 大师傅撒",
          "parent_msg_id": 2,
          "user_id": 2,
          "username": "teacher",
          "parent_msg_username": "lisi"
        },
        {
          "id": 2,
          "date": "2020-05-29 19:08:41",
          "content": "fasdfasdf发生的法撒旦飞洒多发点房地产",
          "parent_msg_id": 1,
          "user_id": 4,
          "username": "lisi",
          "parent_msg_username": "student"
        }
      ]
    }
  ],
  "status_code": 200
}

这个就是前台所要的内容了。

其实一开始我是很直观地认为是用深度优先来取出层层嵌套的留言的,如下:

# 递归搜索一条留言的所有子留言,深度优先
def dfs(parent, allMsg):
  childrenList = []
  for i in range(len(allMsg)):
    if allMsg[i]['parent_msg_id'] is not None and allMsg[i]['parent_msg_id'] == parent['id']:
      allMsg[i]['children'] = dfs(allMsg[i], allMsg)
      childrenList.append(allMsg[i])
  return childrenList

这样取出的json格式是这样的:

{
  "messages": [
    {
      "id": 5,
      "date": "2020-05-29 19:09:33",
      "content": "发的发射点发吖方吖是发是呵等方5爱的非4阿瑟东方 发",
      "parent_msg_id": null,
      "user_id": 4,
      "username": "lisi",
      "children": [
        {
          "id": 8,
          "date": "2020-05-29T17:23:37",
          "content": "哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈呵呵呵呵呵呵",
          "parent_msg_id": 5,
          "user_id": 3,
          "username": "zhangsan",
          "children": []
        }
      ]
    },
    {
      "id": 1,
      "date": "2020-05-29 19:06:21",
      "content": "fasfdsafas法阿萨德方吖65阿瑟东方5是的发",
      "parent_msg_id": null,
      "user_id": 1,
      "username": "student",
      "children": [
        {
          "id": 2,
          "date": "2020-05-29T19:08:41",
          "content": "fasdfasdf发生的法撒旦飞洒多发点房地产",
          "parent_msg_id": 1,
          "user_id": 4,
          "username": "lisi",
          "children": [
            {
              "id": 4,
              "date": "2020-05-29T19:09:14",
              "content": "发送端非场地萨擦手d5asd32 1dads\r\ndsac十多次ds出错",
              "parent_msg_id": 2,
              "user_id": 8,
              "username": "mike",
              "children": [
                {
                  "id": 6,
                  "date": "2020-05-29T19:09:56",
                  "content": "而离开离开邻居哦i据哦i报价哦v保健品45465",
                  "parent_msg_id": 4,
                  "user_id": 6,
                  "username": "zhaoliu",
                  "children": [
                    {
                      "id": 7,
                      "date": "2020-05-29T19:29:29",
                      "content": "hfhf2h22h222223232",
                      "parent_msg_id": 6,
                      "user_id": 1,
                      "username": "student",
                      "children": []
                    }
                  ]
                }
              ]
            },
            {
              "id": 3,
              "date": "2020-05-29T19:08:56",
              "content": "奋发恶法撒打发士大夫士大夫是大 大师傅撒",
              "parent_msg_id": 2,
              "user_id": 2,
              "username": "teacher",
              "children": []
            },
            {
              "id": 9,
              "date": "2020-05-29T17:27:13",
              "content": "alalla啦啦啦啦啦啦来的队列李大水泛滥的萨拉发 的  第三方哈l",
              "parent_msg_id": 2,
              "user_id": 7,
              "username": "joke",
              "children": []
            }
          ]
        }
      ]
    }
  ],
  "status_code": 200
}

但仔细一想,实际页面展示的时候肯定不能这样一层层无限地嵌套下去,否则留言多了页面就装不下了,于是还是改成了两层留言的格式,第二层使用广度优先搜索将树转为列表存储。

2.2 新增留言接口

前台提供留言内容、留言者id以及父留言的id(如果不是回复信息的话就是空)

import datetime

@require_http_methods(['POST'])
def insertMsg(request):
  respOnse= {}
  try:
    request.POST = request.POST.copy()
    request.POST['date'] = datetime.datetime.now()
    msg = Message()
    msg.date = request.POST.get('date')
    msg.cOntent= request.POST.get('content')
    msg.parent_msg_id = request.POST.get('parent_msg_id')
    msg.user_id = request.POST.get('user_id')
    msg.save()
    response['msg'] = 'success'
    response['status_code'] = 200
  except Exception as e:
    response['error'] = str(e)
    response['status_code'] = 500
  
  return JsonResponse(response)

3.前台设计

有了后台提供的数据,前台展示就比较简单了。

留言板块的设计我使用了Ant Design的留言组件。

留言界面主要由两个组件所构成——留言区组件以及评论表单的组件

3.1主视图Messeage.vue





3.2 留言区域组件CommentMessage.vue:





3.3 留言区域由多个Comment留言组件所构成,留言组件定义如下





3.4 添加留言或回复的表单组件CommentArea.vue


组装完成后实现的功能有:

留言界面的展示

点击回复按钮跳到留言表单(这里我直接用了a标签来锚定位,试过用scrollToView来平滑滚动过去,但不知道为什么只有第一次点击回复按钮时才能平滑滚动到,之后再点击他就不滚动了。。。),并把被回复者的用户名显示在placeholder中

点击添加留言按钮,清空placeholder,并自动实现router-view的局部刷新(不是整页刷新)显示出新增的留言

局部刷新的实现就是通过代码中的自定义事件 reload ,具体就是从表单组件开始发送 reload 事件,其父组件 Message.vue 收到后,再继续发送 reload 事件给外层的视图Home.vue,Home的再外层就是App.vue了,Home.vue的定义如下:





里面有一个reload方法,通过改变isRouterAlive来让router-view先隐藏,再显示,实现重新挂载。

到此这篇关于使用Vue+Django+Ant Design做一个留言评论模块的示例代码的文章就介绍到这了,更多相关Vue+Django+Ant Design留言评论内容请搜索以前的文章或继续浏览下面的相关文章希望大家以后多多支持!


推荐阅读
  • 本文介绍了如何使用jQuery和AJAX来实现动态更新两个div的方法。通过调用PHP文件并返回JSON字符串,可以将不同的文本分别插入到两个div中,从而实现页面的动态更新。 ... [详细]
  • 本文介绍了前端人员必须知道的三个问题,即前端都做哪些事、前端都需要哪些技术,以及前端的发展阶段。初级阶段包括HTML、CSS、JavaScript和jQuery的基础知识。进阶阶段涵盖了面向对象编程、响应式设计、Ajax、HTML5等新兴技术。高级阶段包括架构基础、模块化开发、预编译和前沿规范等内容。此外,还介绍了一些后端服务,如Node.js。 ... [详细]
  • Vue基础一、什么是Vue1.1概念Vue(读音vjuː,类似于view)是一套用于构建用户界面的渐进式JavaScript框架,与其它大型框架不 ... [详细]
  • Allegro总结:1.防焊层(SolderMask):又称绿油层,PCB非布线层,用于制成丝网印板,将不需要焊接的地方涂上防焊剂.在防焊层上预留的焊盘大小要比实际的焊盘大一些,其差值一般 ... [详细]
  • 一、Hadoop来历Hadoop的思想来源于Google在做搜索引擎的时候出现一个很大的问题就是这么多网页我如何才能以最快的速度来搜索到,由于这个问题Google发明 ... [详细]
  • 本文介绍了在开发Android新闻App时,搭建本地服务器的步骤。通过使用XAMPP软件,可以一键式搭建起开发环境,包括Apache、MySQL、PHP、PERL。在本地服务器上新建数据库和表,并设置相应的属性。最后,给出了创建new表的SQL语句。这个教程适合初学者参考。 ... [详细]
  • CSS3选择器的使用方法详解,提高Web开发效率和精准度
    本文详细介绍了CSS3新增的选择器方法,包括属性选择器的使用。通过CSS3选择器,可以提高Web开发的效率和精准度,使得查找元素更加方便和快捷。同时,本文还对属性选择器的各种用法进行了详细解释,并给出了相应的代码示例。通过学习本文,读者可以更好地掌握CSS3选择器的使用方法,提升自己的Web开发能力。 ... [详细]
  • 本文介绍了高校天文共享平台的开发过程中的思考和规划。该平台旨在为高校学生提供天象预报、科普知识、观测活动、图片分享等功能。文章分析了项目的技术栈选择、网站前端布局、业务流程、数据库结构等方面,并总结了项目存在的问题,如前后端未分离、代码混乱等。作者表示希望通过记录和规划,能够理清思路,进一步完善该平台。 ... [详细]
  • SpringMVC接收请求参数的方式总结
    本文总结了在SpringMVC开发中处理控制器参数的各种方式,包括处理使用@RequestParam注解的参数、MultipartFile类型参数和Simple类型参数的RequestParamMethodArgumentResolver,处理@RequestBody注解的参数的RequestResponseBodyMethodProcessor,以及PathVariableMapMethodArgumentResol等子类。 ... [详细]
  • SpringBoot整合SpringSecurity+JWT实现单点登录
    SpringBoot整合SpringSecurity+JWT实现单点登录,Go语言社区,Golang程序员人脉社 ... [详细]
  • 从零基础到精通的前台学习路线
    随着互联网的发展,前台开发工程师成为市场上非常抢手的人才。本文介绍了从零基础到精通前台开发的学习路线,包括学习HTML、CSS、JavaScript等基础知识和常用工具的使用。通过循序渐进的学习,可以掌握前台开发的基本技能,并有能力找到一份月薪8000以上的工作。 ... [详细]
  • 本文介绍了Java后台Jsonp处理方法及其应用场景。首先解释了Jsonp是一个非官方的协议,它允许在服务器端通过Script tags返回至客户端,并通过javascript callback的形式实现跨域访问。然后介绍了JSON系统开发方法,它是一种面向数据结构的分析和设计方法,以活动为中心,将一连串的活动顺序组合成一个完整的工作进程。接着给出了一个客户端示例代码,使用了jQuery的ajax方法请求一个Jsonp数据。 ... [详细]
  • 工作经验谈之-让百度地图API调用数据库内容 及详解
    这段时间,所在项目中要用到的一个模块,就是让数据库中的内容在百度地图上展现出来,如经纬度。主要实现以下几点功能:1.读取数据库中的经纬度值在百度上标注出来。2.点击标注弹出对应信息。3 ... [详细]
  • Django + Ansible 主机管理(有源码)
    本文给大家介绍如何利用DjangoAnsible进行Web项目管理。Django介绍一个可以使Web开发工作愉快并且高效的Web开发框架,能够以最小的代价构建和维护高 ... [详细]
  • 这篇文章给大家讲解如何利用dhtmlxGantt在服务器端集成数据。脚本数据保存如果您已初始化dataProcessor,则用户或以编程方式所做的任何更改都将自动 ... [详细]
author-avatar
晴天逍遥
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有