iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 14
1

在前面我們知道上傳資料的方法了,接下來我們要來處理編輯文章的介面。

重新整理一下目前幾個 .vue 檔。
App.vue:

<template>
  <div id="app">
    <b-container fluid class="hero" v-if="$router.history.current.fullPath.search('backend') === -1">
      <b-row>
        <b-col cols="12">
          <div class="hero--chooseHero">
            <div class="hero--chooseHero__content">
              <h1 @click="showLoginClick">IT幫幫忙 - 鐵人賽 30 天</h1>
              <p @click="showUser">自討苦吃</p>
            </div>
          </div>
        </b-col>
      </b-row>
    </b-container>

    <b-navbar type="dark" variant="dark" v-if="$router.history.current.fullPath.search('backend') === -1">

      <!-- 這邊使用 BV 支援 <router-link to=...>的元件 -->
      <b-navbar-nav>
        <b-nav-item to="/">Home</b-nav-item>
        <b-nav-item to="/about">About Me</b-nav-item>
        <b-nav-item to="/login" v-if="loginShow">登入</b-nav-item>
      </b-navbar-nav>
      <!-- 這邊使用 BV navbar 的搜尋框元件,後面用以搜尋文章 -->
      <b-navbar-nav class="ml-auto">
        <b-nav-form>
          <b-form-input size="sm" class="mr-sm-2" placeholder="Search"></b-form-input>
          <b-button size="sm" class="my-2 my-sm-0" type="submit">Search</b-button>
        </b-nav-form>
      </b-navbar-nav>
    </b-navbar>

    <!-- 負責顯示所有內容 -->
    <router-view/>

  </div>
</template>

<script>
export default {
  name: 'App',
  data () {
    return {
      loginShow: false,
      loginClick: 0
    }
  },
  created () {
    this.stateWatcher()
  },
  methods: {
    showLoginClick () {
      this.loginClick++
      if (this.loginClick > 2) {
        this.loginShow = true
        setTimeout(() => {
          this.loginClick = 0
          this.loginShow = false
        }, 3000)
      }
    }
  }
}

</script>

<style lang="scss" scope>
* {
  font-family: 微軟正黑體;
  box-sizing: border-box;
}

#app {
  h1,h2,h3,h4,h5,h6,p {
    margin: 0px;
  }

  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  color: #2c3e50;
}

.container-fluid.hero {
  background-color: #024e82;
  .hero--chooseHero {
    position: relative;
    padding: 1rem;
    height: 300px;
    color: #ddd;

    & > .hero--chooseHero__content {
      position: absolute;
      left: 50%;
      top: 50%;
      transform: translate(-50%, -50%);
      padding: 3rem;
      border: solid 2px #ddd;
      border-radius: 5px;
      text-align: center;

      & > h1,p {
        user-select: none;
      }
    }
  }
}

nav {
  &.navbar { padding: 1rem; }
  .nav-item {
    a {
      font-weight: bold;
      color: #ccc;
      user-select: none;
    }
    a.router-link-exact-active {
      color: #42b983 !important;
    }
  }
}

</style>

backend 的組件中, 先拉一個 sidebar 出來和一個觸發 sidebar 的 button 之後有時間再來想想怎麼版面優化。我們把之後會用到的功能通通先塞到 sidebar裡面,下面多加入一個 router-view 讓他負責來顯示文章編輯器組件、或者之後新增的功能。

Backend.vue 內
<template>
  <b-container class="pageBackend">
    <b-sidebar id="sidebar-1" title="Sidebar" shadow backdrop>
      <div class="px-3 py-2">
        <div><router-link to="/backend/article_editor">新增文章</router-link></div>
        <div @click="signOut"><router-link to="/" >登出</router-link></div>
      </div>
    </b-sidebar>

    <b-row>
      <b-col cols="12 ">
        <h1>30天鐵人賽,後台</h1>
        <b-button v-b-toggle.sidebar-1>Toggle Sidebar</b-button>
      </b-col>
    </b-row>
    <b-row>
      <router-view></router-view>
    </b-row>
  </b-container>
</template>

<script>
// import '../plugins/markdown.js'
import { firebase } from '../Model/FirebaseModel.js'
export default {
  name: 'Backend',
  data () {
    return {}
  },
  methods: {
    signOut () {
      firebase.auth().signOut().then(function () {
        // Sign-out successful.
      // eslint-disable-next-line handle-callback-err
        console.log('登出成功')
      })
    }
  }
}
</script>

<style language="scss">
.pageBackend {
  padding: 1rem;
}
</style>


加完一個 router-view 後,來 router 內的 index.js 設定一下路由,這次這個路由是嵌套的,路徑為

/backend/article_editor,所以必須在 backend 下加入 children,可參考文件。後面等部落格功能比較齊全了如果有時間的話我們再來補充 router 的用法。

router/index.js內

...

const routes = [
  {
    path: '/',
    name: 'Home',
    component: Home
  },
  {
    path: '/about',
    name: 'About',
    // route level code-splitting
    // this generates a separate chunk (about.[hash].js) for this route
    // which is lazy-loaded when the route is visited.
    component: () => import(/* webpackChunkName: "about" */ '../views/About.vue')
  },
  {
    path: '/login',
    name: 'Login',
    component: () => import('../views/Login.vue')
  },
  {
    path: '/backend',
    name: 'Backend',
    component: () => import('../views/Backend.vue'),
    children: [
      {
        path: 'article_editor',
        name: 'ArticleEditor',
        component: () => import('../components/ArticleEditor.vue')
      }
    ]
  }
]

接者來準備 /components/ArticleEditor.vue 組件檔,這邊使用到這個套件,是大陸人開發的,覺得介面做得很好就拿來用了:

https://github.com/zhaoxuhui1122/vue-markdown

是一個使用在 Vue 上的 Markdown 編譯器組件,請自行在專案目錄 npm 他一下。

接著是 ArticleEditor.vue 組件檔內容, 把 Markdown 組件 import 進來使用:

<template>
  <b-container class="pageArticleEditor">
    <b-row>
      <b-col cols="12">
        <label for="input-large">文章標題:</label>
        <b-form-input id="input-large" size="lg" placeholder="請輸入文章標題" v-model="title"></b-form-input>
      </b-col>
      <b-col cols="12">
        <MarkdownPro
          @on-save="updateData"
        ></MarkdownPro>
      </b-col>
      <b-col class="mt-2"><b-button v-b-modal.modal-1 variant="primary">點擊新增文章</b-button></b-col>
    </b-row>
  </b-container>
</template>

<script>
import { MarkdownPro } from 'vue-meditor'
import { db } from '../Model/FirebaseModel.js'
console.log(db)
export default {
  name: 'ArticleEditor',
  data () {
    return {
      title: '',
      articleData: {}
    }
  },
  components: {
    MarkdownPro
  },
  methods: {
    
  }
}
</script>

<style lang="scss" scope>
.pageArticleEditor {
  padding: 1rem;

  & > .row {
    & > div {
      margin: 1rem;;
    }
  }
}

.markdown-body {
  border: #aaa 2px solid;
  border-radius: 5px;
  height: 100%;
  padding: 1rem;
}
</style>

長這樣,打完內容按 Ctrl + S 會進行存檔並觸發事件,裡面會返回文章內容和 html,請先自行接 methods 試試看,這部分明日繼續。

https://ithelp.ithome.com.tw/upload/images/20200922/20129819vnItvPKdH3.jpg

今天先這樣,把編輯器準備好,下一章準備上傳寫好的文章,突然覺得開發 Markdown 的人也好強阿,真是學海無涯...。


沒事也可以逛逛我們其他團隊成員的文章啦 ~~
eien_zheng: 前端小嘍嘍的Golang學習旅程_The journey of learning Golang 系列
PollyPO技術: 前端設計轉前端工程師-JS踩坑雜記 30 天 系列
阿電: 忍住不打牌位,只要30天VueJS帶你上A牌 系列
喬依司: 實作經典 JavaScript 30 系列


上一篇
Day 13: 功能復用小幫手,還不錯的 Mixin 混入
下一篇
Day 15: 串接前後端,動態取得首頁文章
系列文
Vue CLI + Firebase 雲端資料庫 30天打造簡易部落格及後臺管理30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言