项目地址:https://gitee.com/liangPromise/vue-app-toutiaoAdmin/tree/article/

创建组件并配置路由

1、创建 src/views/publish/index.vue 组件

2、配置页面路由

{path: '/home',component: () => import('@/views/home/Home.vue'),children: [{path: '',component: () => import('@/views/home/indexHoem.vue')},{name: 'article',path: 'article',component: () => import('@/views/article')},{// 发布文章路由name: 'publish',path: 'publish',component: () => import('@/views/publish')}]}

页面布局和绑定数据

使用element-ui布局 另外还使用到了富文本编辑器

富文本编辑器的使用具体看我另一篇文章关于项目中的富文本编辑器的使用方法

根据后端接口的要求处理绑定数据绑定

<template><el-card class="box-card"><div slot="header" class="clearfix"><el-breadcrumb separator-class="el-icon-arrow-right"><el-breadcrumb-item :to="{ path: '/home' }">首页</el-breadcrumb-item><el-breadcrumb-item>发布文章</el-breadcrumb-item></el-breadcrumb></div><el-form :model="form" :rules="rules" ref="ruleForm" label-width="100px"><el-form-item label="标题:" prop="title"><el-row><el-col :span="10"><el-input v-model="form.title"></el-input></el-col></el-row></el-form-item><el-form-item label="内容:" prop="content"><el-tiptap :extensions="extensions" v-model="form.content"></el-tiptap></el-form-item><el-form-item label="封面:" prop="cover.type"><el-radio-group v-model="form.cover.type"><el-radio :label="1">单图</el-radio><el-radio :label="3">三图</el-radio><el-radio :label="0">无图</el-radio><el-radio :label="-1">自动</el-radio></el-radio-group></el-form-item><el-form-item label="频道:" prop="channel_id"><el-select v-model="form.channel_id" placeholder="请选择频道"><el-optionv-for="item in channels":key="item.id":label="item.name":value="item.id"></el-option></el-select></el-form-item><!-- 条件渲染 根据isEdit显示发布或者修改 --><el-form-item v-if="!isEdit"><el-button type="primary" @click="onSubmit(false)">发布</el-button><el-button @click="onSubmit(true)">存入草稿</el-button></el-form-item><el-form-item v-else><el-button type="primary" @click="editArticle">修改</el-button></el-form-item></el-form></el-card>
</template><script>
import {ElementTiptap,// necessary extensionsDoc,Text,Paragraph,Heading,Bold,Underline,Italic,Strike,ListItem,BulletList,OrderedList,Image,CodeBlock,Blockquote,TextAlign,Indent,Table,TableHeader,TableCell,TableRow,TextColor,HorizontalRule// LineHeigh
} from 'element-tiptap'import {getChannels,addArticle,inquireArticle,editArticle
} from '@/api/article.js'// 上传图片接口
import { uploadingImg } from '@/api/images.js'
export default {name: 'Publish',components: {'el-tiptap': ElementTiptap},data () {return {form: {title: '',content: '',cover: {type: 1,images: []},channel_id: 2},// 频道信息channels: [],// 是否是修改文章 有id就是修改 没有就不是isEdit: this.$route.query.id,// 验证规则rules: {title: [{ required: true, message: '请输入文章标题', trigger: 'blur' },{ min: 5, max: 30, message: '长度在 5 到 30 个字符', trigger: 'blur' }],content: [{ required: true, message: '请输入内容', trigger: 'blur' }],'cover.type': [{ required: true, message: '请选择图片类型', trigger: 'blur' }],channel_id: [{ required: true, message: '请选择频道', trigger: 'blur' }]},extensions: [new Doc(),new Text(),new Paragraph(),new Heading({ level: 5 }),new Bold({ bubble: true }), // render command-button in bubble menu.new Underline({ bubble: true, menubar: false }), // render command-button in bubble menu but not in menubar.new Italic(),new Strike(),new ListItem(),new BulletList(),new OrderedList(),new CodeBlock(),new Image({// 默认会把图片生成 base64async uploadRequest (file) {const fd = new FormData()fd.append('image', file)const data = await uploadingImg(fd).catch(err => err)console.log(data)return data.data.data.url}}),new Blockquote(),new TextAlign(),new Indent(),new Table(),new TableHeader(),new TableCell(),new TableRow(),new HorizontalRule(),new TextColor()]}},methods: {// 发布按钮onSubmit (draft) {this.$refs.ruleForm.validate(async valid => {if (!valid) return falseconsole.log(1231231313)const data = await addArticle(this.form, draft).catch(err => err)if (data.status !== 201) return this.$message.error('文章发布失败')this.$message.success('文章发布成功')this.$router.push({ path: '/home/article' })})},// 修改按钮editArticle () {this.$refs.ruleForm.validate(async valid => {if (!valid) return falseconst data = await editArticle(this.form, this.isEdit).catch(err => err)if (data.status !== 201) return this.$message.error('文章修改失败')this.$message.success('文章修改成功')this.$router.push({ path: '/home/article' })})},// 获取频道信息async getChannelsFn () {this.loading = trueconst data = await getChannels().catch(err => err)if (data.status !== 200) return this.$message.error('频道信息获取失败')this.channels = data.data.data.channelsthis.loading = false},// 查询文章async inquireArticleFn () {const data = await inquireArticle(this.isEdit).catch(err => err)if (data.status !== 200) return this.$message.error('文章信息获取失败')this.form = data.data.data}},created () {// 获取频道信息this.getChannelsFn()// 如果是修改页面就要获取文章数据if (this.isEdit) {this.inquireArticleFn()}}
}
</script><style></style>

处理文章频道数据

 一、展示频道列表

1、请求获取频道列表数据

2、绑定到模板中展示

二、将频道绑定到表单元素选择器

1、在 article 中添加频道数据字段

2、将数据绑定到频道选择器中

      <el-form-item label="频道:" prop="channel_id"><el-select v-model="form.channel_id" placeholder="请选择频道"><el-optionv-for="item in channels":key="item.id":label="item.name":value="item.id"></el-option></el-select></el-form-item>--------------------------------------------------------------------------------// 获取频道信息async getChannelsFn () {const data = await getChannels().catch(err => err)if (data.status !== 200) return this.$message.error('频道信息获取失败')this.channels = data.data.data.channels},

发布文章

一、封装数据接口

// 发布文章
const addArticle = (data, params) => {console.log(data, params)return request({method: 'POST',url: '/mp/v1_0/articles',params: {draft: params // 是否存为草稿(true 为草稿)},data})
}

二、在发布文章组件中请求调用

1、加载请求方法

2、给发布和存入草稿绑定事件处理函数

3、处理函数如下

      <!-- 条件渲染 根据isEdit显示发布或者修改 --><el-form-item v-if="!isEdit"><el-button type="primary" @click="onSubmit(false)">发布</el-button><el-button @click="onSubmit(true)">存入草稿</el-button></el-form-item><el-form-item v-else><el-button type="primary" @click="editArticle">修改</el-button></el-form-item></el-form>-----------------------------------------------------------
// 引入接口
import {getChannels,addArticle,inquireArticle,editArticle
} from '@/api/article.js'------------------------------------------------------------// 发布按钮onSubmit (draft) {this.$refs.ruleForm.validate(async valid => {if (!valid) return falseconsole.log(1231231313)const data = await addArticle(this.form, draft).catch(err => err)if (data.status !== 201) return this.$message.error('文章发布失败')this.$message.success('文章发布成功')this.$router.push({ path: '/home/article' })})},

编辑文章

展示编辑文章内容

1、封装获取文章的数据接口

2、点击编辑,导航到发布文章页面

<el-buttontype="danger"icon="el-icon-delete"@click="removeArticleFn(scope.row.id)"circle
></el-button>-----------------------------------------------------------// 修改文章editArticleFn (id) {this.$router.push(`publish?id=${id}`)}

3、在发布文章页面组件中,处理加载编辑文章内容

判断是发布还是修改

在发布文章模块中 因为我们修改和发布使用的是一个模块,所以我们要判断一下是否是修改如果是修改我么就显示修改的内容,如果不是就显示发布

在修改按钮中我们使用路由跳转的时候传第一个路由参数

因此我们可以根据这个路由参数来判断 如果有路由参数就是修改 没有就是发布

      // 是否是修改文章 有id就是修改 没有就不是isEdit: this.$route.query.id,

在结构中通过v-if来判断一下显示对应的按钮

      <!-- 条件渲染 根据isEdit显示发布或者修改 --><el-form-item v-if="!isEdit"><el-button type="primary" @click="onSubmit(false)">发布</el-button><el-button @click="onSubmit(true)">存入草稿</el-button></el-form-item><el-form-item v-else><el-button type="primary" @click="editArticle">修改</el-button></el-form-item>

在组件生命周期中我们通过created生命周期钩子在Dom元素创建之前就判断一下路由中有没有路由参数

  created () {// 获取频道信息this.getChannelsFn()// 如果是修改页面就要获取文章数据if (this.isEdit) {this.inquireArticleFn()}}
}

如果是修改我们通过这个文章的id获取到这篇文章的内容 把数据渲染到页面

    // 查询文章async inquireArticleFn () {const data = await inquireArticle(this.isEdit).catch(err => err)if (data.status !== 200) return this.$message.error('文章信息获取失败')this.form = data.data.data}

提交更新

1、封装更新文章的数据接口

2、加载请求方法

3、修改发布文章的处理逻辑

    // 发布按钮onSubmit (draft) {this.$refs.ruleForm.validate(async valid => {if (!valid) return falseconsole.log(1231231313)const data = await addArticle(this.form, draft).catch(err => err)if (data.status !== 201) return this.$message.error('文章发布失败')this.$message.success('文章发布成功')this.$router.push({ path: '/home/article' })})},// 修改按钮editArticle () {this.$refs.ruleForm.validate(async valid => {if (!valid) return falseconst data = await editArticle(this.form, this.isEdit).catch(err => err)if (data.status !== 201) return this.$message.error('文章修改失败')this.$message.success('文章修改成功')this.$router.push({ path: '/home/article' })})},

表单验证处理

验证规则配置对象:

      // 验证规则rules: {title: [{ required: true, message: '请输入文章标题', trigger: 'blur' },{ min: 5, max: 30, message: '长度在 5 到 30 个字符', trigger: 'blur' }],content: [{ required: true, message: '请输入内容', trigger: 'blur' }],'cover.type': [{ required: true, message: '请选择图片类型', trigger: 'blur' }],channel_id: [{ required: true, message: '请选择频道', trigger: 'blur' }]},

处理富文本编辑器中的图片

创建 src/api/image.js 封装数据接口

// 素材接口
import request from '@/utils/request.js'const uploadingImg = data => {// 一般文件上传的接口都要求把请求头中的Content-Type设置为multipart/form-data 但是我们使用axios上传文件的话不需要手动设置,你只要给data一个FormData对象即可。 new FormData()return request.post('/mp/v1_0/user/images', data)
}export { uploadingImg }

自定义图片上传到服务器

        new Image({// 默认会把图片生成 base64async uploadRequest (file) {new FormData()const fd = new FormData()fd.append('image', file)const data = await uploadingImg(fd).catch(err => err)return data.data.data.url    // 将图片的地址返回}}),// 一般文件上传的接口都要求把请求头中的Content-Type设置为multipart/form-data 但是我们使用axios上传文件的话不需要手动设置,你只要给data一个FormData对象即可。 new FormData()

Vue项目——文章发布和修改相关推荐

  1. (三)01 -Vue项目打包发布移动App——vue.config.js中配置相对路径publicPath为空字符串 在public中添加HBuilderX的打包配置文件manifest.json

    Vue 项目打包发布移动 App--npm run build打包 & vue.config.js文件中配置相对路径publicPath为空字符串 & 在 public中添加HBuil ...

  2. java 黑马头条 day4 自媒体文章发布 自媒体文章列表查询 频道列表展示 自媒体文章-发布、修改、保存草稿 自媒体文章-根据id查询 自媒体文章-删除

    1 自媒体文章列表查询 1.1 需求分析 1.2 表结构和实体类 wm_news 自媒体文章表 需求: 如果有文章标题,按照文章标题模糊查询 如果有频道信息,按照频道ID查询 如果有文章状态,按照状态 ...

  3. vue 项目中,动态修改浏览器标签页的图标

    vue 项目中,动态修改浏览器标签页的图标 需求: 项目中有一个入口可以修改平台的名称和图标,图标同步展示为浏览器页签的图标 实现: 1.找到项目中的app.vue 文件,动态创建link标签,调用后 ...

  4. Jenkins自动化构建vue项目然后发布到远程Linux服务器

    部署Jenkins参照另一篇博客: centos7安装Jenkins及其卸载 一.jenkins相关插件的安装 1.安装Publish Over SSH插件用于SSH连接远程的服务器. 登录 jenk ...

  5. Jenkins自动化构建vue项目然后发布到远程服务器

    一.请确保当前服务器安装了docker和jenkins,没安装的请看<在centos7系统安装docker及用docker安装jenkins> (jenkins里面的目录路径为/var/j ...

  6. 【vue项目问题解决】如何做到webpack打包vue项目后,可以修改配置文件IP和端口

    记录在项目开发过程中遇到的小问题,积累开发经验,欢迎大家一起留言探讨 问题 我们在vue项目中打包的时候,webpack会将我们的组件,html,js,css,jpg等其他文件进行打包,其中请求的ip ...

  7. vue 项目打包通过命令修改 vue-router 模式,修改 API 接口前缀

    需求说明: 在开发 vue 项目的过程中遇到的需求是要把 api 接口前缀暴露在命令行,通过 npm run build apiUrl 即可修改接口入口,用于从 docker 部署到不同的测试服务器上 ...

  8. vue项目打包后直接修改ip地址

    在 Vue 项目的配置文件中可以设置 devServer.host 属性来指定开发服务器的主机名.打包后的项目文件中并不包含该配置,所以需要使用其他方式来修改 IP 地址. 一种方法是在本地的 hos ...

  9. php文章发布时间修改,Dedecms编辑文章更新当前时间的修改方法

    关于Dedecms的发布时间问题,前些有位站长咨询烈火小编,正好最近dede58又上线了Dedecms的源码下载频道,在编辑和审核软件时,经常要把以前的时间更新到现在的时间,手动输入真的太麻烦了,加上 ...

最新文章

  1. Shell-流程控制
  2. led显字风扇原理?
  3. 媒体查询 200304
  4. 不为人知的稠密特征加入CTR预估模型的方法
  5. 【java】java AsyncHttpClient使用
  6. python高级-------python2.7教程学习【廖雪峰版】(四)
  7. CNN推理哪家强?英伟达/英特尔/骁龙/麒麟/ActionSemi大测评
  8. matlab保存每次循环的结果
  9. 有什么软件方便画er图_数据库ER图绘制工具(DbSchema)
  10. 丁小平:人类究竟需要什么样的微积分原理
  11. 【手游逆向】初探Unity3d+il2cpp.so网游修改新手教程篇[内附所有相关工具下载地址和说明介绍】
  12. volte的sip信令流程_VOLTE-SIP完整信令解析
  13. Java面试笔试题大汇总一(最全+详细答案)
  14. 扫描隧道显微镜STM功能介绍及用途
  15. 台式计算机品牌怎么查,教你怎么看电脑主板型号和品牌
  16. 数显之家快讯:【SHIO世硕心语】2021,写给自己的几段宽心话!
  17. 51nod 1629 B君的圆锥
  18. 液晶屏ESD防护解决方案
  19. python实现图像差异性分析(标记并记录差异点)
  20. 用Excel做排列图

热门文章

  1. 玩机搞机---小米机型格机 檫除分区后修复nv损坏问题的硬件类修复步骤解析
  2. 手机:运行内存,机身内存,内存卡的区分
  3. Python杀死Excel?众多模块哪家强
  4. VR 终极选购指南:入门、进阶与高端
  5. 2D前景触发与3D触发结合案例
  6. PHP+python+nodejs+ springboot+vue 社区互助平台
  7. C++实现Cholesky分解
  8. 从 smali 接入第三方 sdk
  9. 你开始变的虚伪 是自尊心一直作祟
  10. 为方便旅客,某航空公司拟开发一个机票预定系统。旅行社把预定机票的旅客信息......