Springboot+Vue实现发表文章功能

全栈开发者社区

共 9657字,需浏览 20分钟

 ·

2020-07-30 21:39

点击上方[全栈开发者社区]右上角[...][设为星标⭐]





效果图

前端编辑页面


文章列表页面

文章详情页面






环境介绍

JDK:1.8

数据库:Mysql5.6

前端:Vue

后端:SpringBoot





核心代码介绍

AtricleCtrle.class

@RestController@RequestMapping("/article")@CrossOriginpublic class ArticleCtrler {  @Autowired  private ArticleService articleService;  @ApiOperation(value="添加文章")  @PostMapping("/addarticle")  public Object addarticle(@Valid Article vo)  {    try     {      articleService.insert(vo);       return Result.success(null);    }    catch (Exception e)     {      e.printStackTrace();    }     return Result.error(CodeMsg.SERVER_ERROR);  }  @PostMapping("/loadPage")  @ApiOperation(value="文章分页列表")  public Object loadPage(@Valid Article_Condit vo)  {    try     {      PageInfo
 loadPage = articleService.loadPage(vo); return Result.success(loadPage); } catch (Exception e) { e.printStackTrace(); } return Result.error(CodeMsg.SERVER_ERROR); }}

ArticleService.interface

public interface ArticleService {  void insert(Article vo);  PageInfo
loadPage(Article_Condit vo);}

ArticleServiceImpl.class

@Service@Transactionalpublic class ArticleServiceImpl implements ArticleService {  @Autowired  private ArticleDao articleDao;  @Override  public void insert(Article vo) {    vo.setCreatedatetime(new Timestamp(new Date().getTime()));    vo.setCreateuserid("system");    articleDao.save(vo);  }  @Override  public PageInfo
loadPage(Article_Condit vo) {    PageHelper.startPage(vo.getPageIndex()==null?0:vo.getPageIndex(), vo.getPageSize()==null?0:vo.getPageSize());    List
 findByCondit = articleDao.findByCondit(vo); return new PageInfo
(findByCondit);  }}

ArticleDao.class

@Repositorypublic interface ArticleDao {  void save(Article vo);  List
findByCondit(Article_Condit vo);}

Helloworld.vue

@ApiModel(value="发布文章", description="发布文章")public class Article implements Serializable{  private static final long serialVersionUID = 1L;  @ApiModelProperty(value = "文章编号",hidden = true)  private Long id;  @ApiModelProperty(value = "文章标题",required = true)  @NotBlank(message = "标题不能为空")  private String title;  @ApiModelProperty(value = "文章描述",required = true)  @NotBlank(message = "文章描述不能为空")  private String description;  @ApiModelProperty(value = "文章内容",required = true)  @NotBlank(message = "文章内容不能为空")  private String content;  @ApiModelProperty(value = "文章类型",required = false)  private String articletype;  @ApiModelProperty(value = "创建时间",hidden = true)  @JsonFormat(pattern="yyyy-MM-dd HH:mm", timezone="GMT+8")  private Timestamp createdatetime;  @ApiModelProperty(value = "创建人",hidden = true)  private String createuserid;  public Long getId() {    return id;  }  public void setId(Long id) {    this.id = id;  }  public String getTitle() {    return title;  }  public void setTitle(String title) {    this.title = title;  }  public String getDescription() {    return description;  }  public void setDescription(String description) {    this.description = description;  }  public String getContent() {    return content;  }  public void setContent(String content) {    this.content = content;  }  public Timestamp getCreatedatetime() {    return createdatetime;  }  public void setCreatedatetime(Timestamp createdatetime) {    this.createdatetime = createdatetime;  }  public String getCreateuserid() {    return createuserid;  }  public void setCreateuserid(String createuserid) {    this.createuserid = createuserid;  }  public String getArticletype() {    return articletype;  }  public void setArticletype(String articletype) {    this.articletype = articletype;  }  @Override  public String toString() {    return "Article [id=" + id + ", title=" + title + ", description=" + description + ", content=" + content        + ", articletype=" + articletype + ", createdatetime=" + createdatetime + ", createuserid="        + createuserid + "]";  }}
articleMapper.xml
<mapper namespace="com.yxyz.dao.ArticleDao">  <insert id="save" parameterType="com.yxyz.vo.Article">    insert       into t_article(title,description,content,articletype,createdatetime,createuserid)    values    (      #{title,jdbcType=VARCHAR},#{description,jdbcType=VARCHAR},#{content,jdbcType=LONGVARCHAR},      #{articletype,jdbcType=VARCHAR},#{createdatetime,jdbcType=TIMESTAMP},#{createuserid,jdbcType=VARCHAR}    )  insert>  <select id="findByCondit" parameterType="com.yxyz.condit.Article_Condit" resultType="com.yxyz.vo.Article">    select t1.* from t_article t1 where 1=1    <if test="articletype != null and articletype !=''">      and t1.articletype like concat('%',#{articletype},'%')    if>    <if test="createuserid != null and createuserid !=''">      and t1.createuserid = #{createuserid}    if>  select>mapper>

main.js

import Vue from 'vue'import App from './App.vue'import router from './router'import ElementUI from 'element-ui'import 'element-ui/lib/theme-chalk/index.css'
Vue.use(ElementUI)Vue.config.productionTip = false
new Vue({ router, render: (h) => h(App),}).$mount('#app')

About.vue

<template>  <div class>    <h3>编辑页面h3>    <el-form ref="form" :model="form" label-width="80px">      <el-form-item label="标题">        <el-input v-model="form.title">el-input>      el-form-item>      <el-form-item label="描述">        <el-input v-model="form.description">el-input>      el-form-item>      <el-form-item label="正文">        <quill-editor          ref="myQuillEditor"          class="editor"          v-model="form.content"          :options="editorOption"          @blur="onEditorBlur($event)"          @focus="onEditorFocus($event)"          @ready="onEditorReady($event)"        />      el-form-item>      <el-button class="btn" block type="primary" @click="submit">提交el-button>    el-form>  div>template>
<script>import 'quill/dist/quill.core.css'import 'quill/dist/quill.snow.css'import 'quill/dist/quill.bubble.css'
import { quillEditor } from 'vue-quill-editor'import axios from 'axios'export default { components: { quillEditor }, props: {}, data() { return { form: { title: '', description: '', content: '', }, editorOption: { modules: { toolbar: [ ['bold', 'italic', 'underline', 'strike'], //加粗,斜体,下划线,删除线 ['blockquote', 'code-block'], //引用,代码块
[{ header: 1 }, { header: 2 }], // 标题,键值对的形式;1、2表示字体大小 [{ list: 'ordered' }, { list: 'bullet' }], //列表 [{ script: 'sub' }, { script: 'super' }], // 上下标 [{ indent: '-1' }, { indent: '+1' }], // 缩进 [{ direction: 'rtl' }], // 文本方向
[{ size: ['small', false, 'large', 'huge'] }], // 字体大小 [{ header: [1, 2, 3, 4, 5, 6, false] }], //几级标题
[{ color: [] }, { background: [] }], // 字体颜色,字体背景颜色 [{ font: [] }], //字体 [{ align: [] }], //对齐方式
['clean'], //清除字体样式 // ['image', 'video'], //上传图片、上传视频 ], }, theme: 'snow', }, } }, computed: {}, created() {}, mounted() {}, watch: {}, methods: { onEditorBlur(quill) { console.log('editor blur!', quill) }, onEditorFocus(quill) { console.log('editor focus!', quill) }, onEditorReady(quill) { console.log('editor ready!', quill) }, submit() { if (!this.form.title) { this.$message('请输入标题') } if (!this.form.description) { this.$message('请输入描述') } if (!this.form.content) { this.$message('请输入正文') }
let formData = new FormData() formData.append('title', this.form.title) formData.append('description', this.form.description) formData.append('content', this.form.content) // 发送 POST 请求 axios({ method: 'post', url: 'http://139.159.147.237:8080/yxyz/article/addarticle', data: formData, headers: { 'Content-Type': 'application/x-www-form-urlencoded', }, }) .then(function(response) { if (res.code === 0) { this.$message('提交成功') } // this.form = { // title: '', // description: '', // content: '', // } this.$router.goBack() }) .catch(function(error) { console.log(error) }) }, },}script>
<style scoped lang="less">.editor { height: 500px;}.btn { margin-top: 100px;}style>

Detail.vue

<template>  <div class="">    <h2>文章详情h2>    <el-card>      <div class="title">{{ detail.title }}div>      <div class="des">{{ detail.description }}div>      <div class="con" v-html="detail.content">div>      <div class="time">{{ detail.createdatetime }}div>    el-card>  div>template>
<script>export default { components: {}, props: {}, data() { return { detail: {}, } }, computed: {}, created() { console.log(this.$route) let item = this.$route.params.item
this.detail = item }, mounted() {}, watch: {}, methods: {},}script>
<style scoped lang="less">.title { font-weight: bold; font-size: 16px; text-align: left; margin-bottom: 10px;}.des { font-size: 14px; text-align: left; margin-bottom: 10px;}.con { font-size: 14px; text-align: left; margin-bottom: 10px;}.time { font-size: 14px; text-align: left;}style>

Home.vue

<template>  <div class="">    <h2>文章详情h2>    <el-card>      <div class="title">{{ detail.title }}div>      <div class="des">{{ detail.description }}div>      <div class="con" v-html="detail.content">div>      <div class="time">{{ detail.createdatetime }}div>    el-card>  div>template>
<script>export default { components: {}, props: {}, data() { return { detail: {}, } }, computed: {}, created() { console.log(this.$route) let item = this.$route.params.item
this.detail = item }, mounted() {}, watch: {}, methods: {},}script>
<style scoped lang="less">.title { font-weight: bold; font-size: 16px; text-align: left; margin-bottom: 10px;}.des { font-size: 14px; text-align: left; margin-bottom: 10px;}.con { font-size: 14px; text-align: left; margin-bottom: 10px;}.time { font-size: 14px; text-align: left;}style>

application.yml

spring:  profiles:    active: dev

application-dev.yml

server:  port: 8080  servlet:    context-path: /yxyzspring:  datasource:    name: yxyz    url: jdbc:mysql://localhost/test?serverTimezone=GMT%2b8&characterEncoding=UTF8    username: root    password: 123 # 使用druid数据源    type: com.alibaba.druid.pool.DruidDataSource    driver-class-name: com.mysql.cj.jdbc.Driver    filters: stat    maxActive: 20    initialSize: 1    maxWait: 60000    minIdle: 1    timeBetweenEvictionRunsMillis: 60000    minEvictableIdleTimeMillis: 300000    validationQuery: select 'x'    testWhileIdle: true    testOnBorrow: false    testOnReturn: false    poolPreparedStatements: true    maxOpenPreparedStatements: 20## 该配置节点为独立的节点mybatis:  mapper-locations: classpath:mapping/*Mapper.xml #注意:一定要对应mapper映射xml文件的所在路径  type-aliases-package: com.yxyz.vo # 注意:对应实体类的路径#打印sql最终填充的参数值  log-impl: org.apache.ibatis.logging.stdout.StdOutImpl


觉得本文对你有帮助?请分享给更多人

关注「全栈开发者社区」加星标,提升全栈技能


本公众号会不定期给大家发福利,包括送书、学习资源等,敬请期待吧!

如果感觉推送内容不错,不妨右下角点个在看转发朋友圈或收藏,感谢支持。


好文章,留言、点赞、在看和分享一条龙吧❤️

浏览 53
点赞
评论
收藏
分享

手机扫一扫分享

举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

举报