美文网首页
(四)koa+mysql 实现一个简书文章操作

(四)koa+mysql 实现一个简书文章操作

作者: 梦想成真213 | 来源:发表于2019-12-26 11:17 被阅读0次

这一个系列的前面几篇,从安装 mysql 到 Node 操作 mysql 再到 将 Node 项目按照 MVC 架构拆分组织,这一篇实现一个简单的简书获取文章列表,添加文章,更新文章,删除文章的操作,来巩固一下前面学习的知识。

首先还在之前的 koa-test 下新建一个md_to_html 的文件夹,前端不使用任何框架,直接原生操作,因为重点不是在前端,而是在后端接口实现上。实现的效果如下:



可以新建文章,获取文章的列表, 更新编辑文章,删除文章,每一次操作都会重新请求最新的文章列表。

前端部分

先看前端部分,主要分为 html , css,js,这一块都是直接写,html,css 没什么好说的,贴一下 js 的代码吧,js 主要都在手动操作 dom 上,其中有一个点就是更新文章的时候,做了防抖处理,在300毫秒之后再去请求更新接口,不至于只要输入发生变化就频繁的请求接口。

// static/js/index.js
;(function(){
    const { debounce } = MD2HTML_Util
    const { 
        addService, 
        getContentService, 
        getListService, 
        deleteService,
        updateService
    } = MD2HTML_Service

    const new_article = document.getElementById('new_article')
    const articleList = document.getElementById('article-list')
    const add_title = document.getElementById('add_title')
    const editor_origin = document.getElementById('editor-origin')

    const html_title = document.getElementById('html-title')
    const html_content = document.getElementById('html-content')
    
    let ID = null;
    let global_index = 0

    function addController (params, cb){
        let id = null, content = null, title = null
        addService(params)
        .then((res) => {
            return new Promise((resolve, reject) => {
                id = res.data.id
                title = res.data.title
                getContentService(id)
                .then((resp) => {
                    content = resp.data.content
                    resolve()
                })
            })
        })
        .then(() => {
            if(cb) cb({id, title, content})
        })
    }

    function getArticleList(){
        getListService()
        .then((resp) => {
            if(resp.code == 0){
                //resp.data.reverse();
                let fragment = document.createDocumentFragment()
                resp.data.forEach((item, index) => {
                    let li = document.createElement('li')
                    li.setAttribute('data-index', index)
                    li.setAttribute('data-id', item.id)
                    li.className = 'li-title';
                    li.textContent = item.title
                    let span = document.createElement('span')
                    span.setAttribute('data-id', item.id)
                    span.className = 'delete-article'
                    span.textContent = '删除'
                    li.appendChild(span)
                    fragment.appendChild(li)
                })
                if(articleList.children.length > 0){
                    articleList.innerHTML = ''
                }
                articleList.appendChild(fragment)

                const li = articleList.querySelectorAll('.li-title')
                if(li.length > 0){
                    if(global_index != 0){
                        ID = resp.data[global_index].id
                        title = resp.data[global_index].title
                        content = resp.data[global_index].content
                        li[global_index].className = 'li-title active'
                    } else{
                        ID = resp.data[0].id
                        title = resp.data[0].title
                        content = resp.data[0].content
                        li[0].className = 'li-title active'
                    }
                }
                add_title.value = html_title.innerHTML = title
                editor_origin.value = content

                html_content.innerHTML = renderHtml(content)
            } else {
                console.log(resp.message)
            }
        })
    }

    function updateArticle(params){
        updateService(params)
        .then(res => {
            const data = res.data
            if(res.code === 0){
                html_title.innerHTML = data.title
                html_content.innerHTML = renderHtml(data.content)

                add_title.value = data.title
                editor_origin.value = data.content

                getArticleList()
            }
        })
    }

    getArticleList();

    new_article.onclick = function(){
        addController({title: '2019-11-14', author: 'hcj'}, (article) => {
            add_title.value = article.title
            editor_origin.value = article.content
        })
        getArticleList()
    }

    articleList.onclick = function(e){
        const target = e.target
        const li = articleList.querySelectorAll('.li-title')
        if(target.className.indexOf('li-title') > -1){
            const index = target.getAttribute('data-index')
            global_index = index
            const id = target.getAttribute('data-id')
            ID = id
            li.forEach((item) => {
                item.className = 'li-title'
            })
            li[index].className = 'li-title active'
            getContentService(id)
            .then((resp) => {
                add_title.value = resp.data.title
                editor_origin.value = resp.data.content

                html_title.innerHTML = resp.data.title
                html_content.innerHTML = renderHtml(resp.data.content)
            })
            
        }
        if(target.className == 'delete-article'){
            //删除接口
            const id = target.getAttribute('data-id')
            deleteService(id)
            .then((res) => {
                if(res.code === 0){
                    getArticleList();
                } else {
                    console.log(res.message)
                }
            })
        }
    }

    add_title.onkeyup = editor_origin.onkeyup = debounce(() => {
        const params = {
            id: ID,
            title: add_title.value,
            content: editor_origin.value,
            author: 'hcj'
        }
        updateArticle(params)
    }, 1000)


    function renderHtml(text){
        let htmlStr = MdtoHtml(text)
        return htmlStr;
    }
})();

后端接口实现

依然跟之前的差不多,大概看看吧。

// server/server.js
const Koa = require('koa')
const static = require('koa-static')
const Router = require('koa-router')
const koaBody = require('koa-body')
const { join } = require('path')
const { query } = require('./db/db')
const { addSql } = require('./db/sql/article_sql')


const staticPath = '../static'
const app = new Koa()
const router = new Router()

app.use(koaBody());
app.use(static(join(__dirname, staticPath)))
app.use(router.routes()).use(router.allowedMethods())

router.get('/articleList', async (ctx, next) => {
    let list = await query('SELECT * FROM article;')
    let data = [];
    list.forEach(({ id, title, author, content, createTime }) => {
        data.push({
            id,
            title,
            author,
            content,
            createTime
        })
    })
    ctx.body = {
        code: 0,
        data,
        message: 'get list success'
    }
})

router.post('/add', async (ctx, next) => {
    const params = ctx.request.body
    let result = await query(addSql, params)
    ctx.body = {
        code: 0,
        data: {
            id: result.insertId,
            title: params.title,
        },
        message: 'add success'
    }
})

router.get('/getContent/:id', async (ctx, next) => {
    let result = await query('SELECT * FROM article WHERE id = ?;', ctx.params.id)
    ctx.body = {
        code: 0,
        data: {
            title: result[0].title,
            content: result[0].content
        },
        message: 'get content success'
    }
})

router.put('/update/:id', async (ctx, next) => {
    const postData = ctx.request.body
    await query('UPDATE article SET title = ?, content = ?, author = ? WHERE id = ?;', [postData.title, postData.content, postData.author, postData.id])
    const result = await query('SELECT * FROM article WHERE id = ?;', ctx.params.id)
    ctx.body = {
        code: 0,
        data: result[0],
        message: 'update success'
    }
})

router.post('/delete', async (ctx, next) => {
    const postData = ctx.request.body;
    await query('DELETE FROM article WHERE id = ?;', postData.id)
    ctx.body = {
        code: 0,
        data:{},
        message: 'delete success'
    }
})

app.listen(3000)
console.log('listenning at port 3000')

其实这一篇文章跟其他的几篇没什么太大的区别,我写这个小项目是为了写一个 markdown 的转译器,将左边的 markdown 语法实时转译为右边的 html 显示出来。本来想随便写个页面,但是由于强迫症,还是想看着能好看点,就多写了很多样式,js 操作之类的代码,兜了一大圈,那就当做是巩固知识吧,毕竟 12 月快过完了,还没出一篇文章,心慌慌,就当是凑篇幅了,(捂脸)。

github 地址:https://github.com/mxcz213/koa-test

分支切到md_to_html就可以看到了。

相关文章

网友评论

      本文标题:(四)koa+mysql 实现一个简书文章操作

      本文链接:https://www.haomeiwen.com/subject/rtkhoctx.html