zoukankan      html  css  js  c++  java
  • 编辑文章

    1). 添加编辑文章路由

    打开 src/router/routes.js 文件,在数组的最后面,添加编辑文章路由 Edit

    src/router/routes.js

    1   // Edit
    2   {
    3     path: '/articles/:articleId/edit',
    4     name: 'Edit',
    5     component: () => import('@/views/articles/Create'),
    6     meta: { auth: true }
    7   },

    我们这里使用了跟 Create 一样的组件页面,但将其路径指向一个新的地址,并命名为 Edit

    2). 添加编辑入口

    1、打开 src/views/articles/Content.vue 文件,复制以下代码替换原 <script>

    src/views/articles/Content.vue

     1 <script>
     2 import SimpleMDE from 'simplemde'
     3 import hljs from 'highlight.js'
     4 import emoji from 'node-emoji'
     5 import { mapState } from 'vuex'
     6 
     7 export default {
     8   name: 'Content',
     9   data() {
    10     return {
    11       title: '', // 文章标题
    12       content: '', // 文章内容
    13       date: '', // 文章创建时间
    14       uid: 1 // 用户 ID
    15     }
    16   },
    17   computed: {
    18     ...mapState([// 将仓库的以下状态混入到计算属性之中
    19       'auth',
    20       'user'
    21     ])
    22   },
    23   created() {
    24     const articleId = this.$route.params.articleId
    25     const article = this.$store.getters.getArticleById(articleId)
    27     if (article) {
    28       let { uid, title, content, date } = article
    30       this.uid = uid
    31       this.title = title
    32       this.content = SimpleMDE.prototype.markdown(emoji.emojify(content, name => name))
    33       this.date = date
    35       this.$nextTick(() => {
    36         this.$el.querySelectorAll('pre code').forEach((el) => {
    37           hljs.highlightBlock(el)
    38         })
    39       })
    40     }
    41 
    42     this.articleId = articleId
    43   },
    44   methods: {
    45     editArticle() {
    46       this.$router.push({ name: 'Edit', params: { articleId: this.articleId } })
    47     },
    48     deleteArticle() {
    49 
    50     }
    51   }
    52 }
    53 </script>

    2、查找 <div class="markdown-body",在其后面添加『编辑删除图标』:

    1 <div class="markdown-body" v-html="content"></div>
    2 
    3 <!-- 编辑删除图标 -->
    4 <div v-if="auth && uid === 1" class="panel-footer operate">
    5   <div class="actions">
    6     <a @click="deleteArticle" class="admin" href="javascript:;"><i class="fa fa-trash-o"></i></a>
    7     <a @click="editArticle" class="admin" href="javascript:;"><i class="fa fa-pencil-square-o"></i></a>
    8   </div>
    9 </div>

    我们先判断用户是否已登录,已登录且当前用户 ID 为 1 时,渲染编辑删除图标。

    3). 添加编辑文章逻辑

    打开 src/store/actions.js 文件,复制以下代码替换原 post 事件:

    src/store/actions.js

     1 export const post = ({ commit, state }, { article, articleId }) => {
     2   let articles = state.articles
     3 
     4   if (!Array.isArray(articles)) articles = []
     5 
     6   if (article) {
     7     const uid = 1
     8     const { title, content } = article
     9     const date = new Date()
    10 
    11     if (articleId === undefined) {
    12       const lastArticle = articles[articles.length - 1]
    13 
    14       if (lastArticle) {
    15         articleId = parseInt(lastArticle.articleId) + 1
    16       } else {
    17         articleId = articles.length + 1
    18       }
    19 
    20       articles.push({
    21         uid,
    22         articleId,
    23         title,
    24         content,
    25         date
    26       })
    27     }else { // 如果有传 articleId
    28   // 遍历所有文章
    29   for (let article of articles) {
    30     // 找到与 articleId 对应的文章
    31     if (parseInt(article.articleId) === parseInt(articleId)) {
    32       // 更新文章的标题
    33       article.title = title
    34       // 更新文章的内容
    35       article.content = content
    36       break
    37     }
    38   }
    39 }
    40     commit('UPDATE_ARTICLES', articles)
    41     router.push({ name: 'Content', params: { articleId, showMsg: true } })
    42   }
    43 }

    4). 修改创作文章页面

    1、打开 src/views/articles/Create.vue 文件,复制以下代码替换原 <script>

    src/views/articles/Create.vue

     1 <script>
     2 import SimpleMDE from 'simplemde'
     3 import hljs from 'highlight.js'
     4 import ls from '@/utils/localStorage'
     5 
     6 window.hljs = hljs
     7 
     8 export default {
     9   name: 'Create',
    10   data() {
    11   return {
    12     articleId: undefined // 文章 ID
    13   }
    14 },
    15 beforeRouteEnter(to, from, next) {
    16   next(vm => {
    17     // 确认渲染组件的对应路由时,设置 articleId
    18     vm.setArticleId(vm.$route.params.articleId)
    19   })
    20 },
    21 // 在离开该组件的对应路由前
    22 beforeRouteLeave(to, from, next) {
    23   // 清空自动保存的文章数据
    24   this.clearData()
    25   next()
    26 },
    27 watch: {
    28   // 监听路由参数的变化
    29   '$route'(to) {
    30     // 清空自动保存的文章数据
    31     this.clearData()
    32     // 设置 articleId
    33     this.setArticleId(to.params.articleId)
    34   }
    35 },
    36 methods: {
    37   // 填充文章数据
    38   fillContent(articleId) {
    39     // 编辑器
    40     const simplemde = this.simplemde
    41     // 自动保存的标题
    42     const smde_title = ls.getItem('smde_title')
    43 
    44     // 有 articleId 时
    45     if (articleId !== undefined) {
    46       // 获取对应文章
    47       const article = this.$store.getters.getArticleById(articleId)
    48 
    49       if (article) {
    50         // 获取文章的标题和内容
    51         const { title, content } = article
    52 
    53         // 有自动保存的标题时,使用自动保存的标题,否则使用文章的标题
    54         this.title = smde_title || title
    55         // 有自动保存的内容时,使用自动保存的内容,否则使用文章的内容
    56         this.content = simplemde.value() || content
    57         // 设置编辑器的内容
    58         simplemde.value(this.content)
    59       }
    60     } else { // 没有 articleId 时,使用自动保存的标题和内容
    61       this.title = smde_title
    62       this.content = simplemde.value()
    63     }
    64   },
    65   post() {
    66     if (title !== '' && content.trim() !== '') {
    67       // 在分发 post 事件时,附带 articleId 参数
    68       this.$store.dispatch('post', { article, articleId: this.articleId })
    69     }
    70   },
    71   // 设置 articleId
    72   setArticleId(articleId) {
    73     // 获取 localStorage 保存的 articleId,临时用它来判断是否还处于当前编辑页面
    74     const localArticleId = ls.getItem('articleId')
    75 
    76     // 手动在两个不同的编辑页面之间跳转时(如 /articles/1/edit 和 /articles/2/edit)时
    77     if (articleId !== undefined && !(articleId === localArticleId)) {
    78       // 清空自动保存的文章数据
    79       this.clearData()
    80     }
    81 
    82     // 设置当前实例的 articleId
    83     this.articleId = articleId
    84     // 填充文章数据
    85     this.fillContent(articleId)
    86     // 在 localStorage 保存一个 articleId
    87     ls.setItem('articleId', articleId)
    88   }
    89 }
    90 </script>

    上面代码的核心就是利用路由参数的 articleId,获取对应的文章数据,来填充编辑页面。在不同的编辑页面之间跳转(如 /articles/1/edit 和 /articles/2/edit)时,因为我们会优先填充自动保存的数据,所以需要先调用 clearData 清空它们。

    涉及的新知识点:

    1 beforeRouteLeave(to, from, next) {
    2   this.clearData()
    3   next()
    4 }

    beforeRouteLeave 是组件内的守卫,在离开该组件的对应路由时调用,此时可以访问 this,需要使用 next() 确认导航。

    监听 '$route'

    1 watch: {
    2   '$route'(to) {
    3     this.clearData()
    4     this.setArticleId(to.params.articleId)
    5   }
    6 }

    我们可以通过监听 '$route' 来得知路由参数的变化,我们通常会在两个路由都渲染相同的组件时监听 '$route',这是因为 Vue 会复用组件实例,以导致组件内的部分钩子不再被调用。举例来说,我们的『编辑文章』和 『创作文章』都使用 Create.vue 组件,当我们从『编辑文章』导航到『创作文章』时(在编辑文章页面点击创作文章按钮),beforeRouteEnter 就不会被调用,所以我们需要监听 '$route',以响应路由参数的变化。

    2、查找 <h2 class="text-center">,作如下修改:

    1 <!-- 修改 -->
    2 <h2 class="text-center">创作文章</h2>
    3 <!-- 为 -->
    4 <h2 class="text-center">{{ articleId ? '编辑文章' : '创作文章' }}</h2>
  • 相关阅读:
    [转]Magento刷新索引的几种方法
    [转]centos7 移动mysql5.7.19 数据存储位置
    [转]解决Magento批量导入带图片的商品的问题
    [转]【mysql监控】查看mysql库大小,表大小,索引大小
    [转]Centos系统中查看文件和文件夹大小
    [转]Magento 2.2 Developer Documentation
    [转]Magento2开发教程
    [转]Magento Configurable Product
    [转]论magento1和magento2的速度性能优化问题
    [转]本地 Windows 计算机密码登录 登录 腾讯云 Linux 实例
  • 原文地址:https://www.cnblogs.com/yangguoe/p/9318320.html
Copyright © 2011-2022 走看看