Omi × 雲開發『半天』搞定小程序 『markdown 內容發佈系統』

寫在前面

開發小程序,可是:沒有後端!沒有運維!沒有 DBA!沒有域名!沒有證書!沒有錢!沒有時間!沒有精力!javascript

沒有關係,會 javascript 就能夠,小程序•雲開發帶你起飛!css

開發者可使用雲開發開發微信小程序、小遊戲,無需搭建服務器,便可使用雲端能力。雲開發爲開發者提供完整的雲端支持,弱化後端和運維概念,無需搭建服務器,使用平臺提供的 API 進行核心業務開發,便可實現快速上線和迭代,同時這一能力,同開發者已經使用的雲服務相互兼容,並不互斥。html

目前提供三大基礎能力支持:前端

  • 雲函數:在雲端運行的代碼,微信私有協議自然鑑權,開發者只需編寫自身業務邏輯代碼
  • 數據庫:一個既可在小程序前端操做,也能在雲函數中讀寫的 JSON 數據庫
  • 存儲:在小程序前端直接上傳/下載雲端文件,在雲開發控制檯可視化管理

一步一步搭建

本文將一步一步教你使用 小程序•雲開發 + Omip + Comi 搭建一個支持 markdown 和代碼高亮的小程序內容展現和發佈系統。java

預覽:git

1.建表

操做路徑: 微信開發者工具→雲開發→數據庫→添加集合github

article 集合字段說明:數據庫

字段 說明
_id 數據的惟一 id,用戶寫入時系統自動生產
_openid 用戶的惟一標識,用戶寫入時系統自動生產
createTime 文章建立時間
md 文章內容
order 文章的順序
title 文章的標題

很明顯,這個表用來存儲全部的文章。而後設置表的讀寫權限:npm

由於後續可能支持用戶發表文章,全部設置成第一個。json

2.初始化項目目錄

$ npm i omi-cli -g 
$ omi init-cloud my-app     
$ cd my-app          
$ npm start          
複製代碼

這裏是使用 omip 做爲腳手架,也支持 Omi mps-cloud 建立原生小程序的雲開發的腳手架:

$ npm i omi-cli -g              
$ omi init-mps-cloud my-app    
$ cd my-app/miniprogram   
$ npm install
$ npm start               
複製代碼

3.項目初始化 app.js

import './app.css'
import './pages/list/index'
import { render, WeElement, define } from 'omi'

define('my-app', class extends WeElement {

  config = {
    pages: [
      'pages/list/index',
      'pages/detail/index',
      'pages/import/index'
    ],
    window: {
      backgroundTextStyle: 'light',
      navigationBarBackgroundColor: '#fff',
      navigationBarTitleText: 'Omi Cloud',
      navigationBarTextStyle: 'black'
    }
  }

  install() {
    if (!wx.cloud) {
      console.error('請使用 2.2.3 或以上的基礎庫以使用雲能力')
    } else {
      wx.cloud.init({
        traceUser: true,
      })
      this.globalData.db = wx.cloud.database({
        env: 'test-06eb2e'
      })
    }
  }

  render() {
    return (
      <page-list />
    )
  }
})

render(<my-app />, '#app')
複製代碼

wx.cloud.database 代碼參數裏的 env 能夠從上面獲取到,通常建立兩個環境,一個用戶測試環境,一個用於生產環境。

  • pages/list/index 文章列表首頁
  • pages/detail/index 文章詳情夜
  • pages/import/index 文章導入頁(先簡單經過代碼導入 markdown,沒提供 UI)

導入 markdown 數據

import { WeElement, define } from 'omi'
import data from './test.md'

const app = getApp()

define('page-import', class extends WeElement {

  installed() {
    wx.cloud.callFunction({
      name: 'login',
      data: {},
      success: res => {
        app.globalData.openid = res.result.openid
        app.globalData.db.collection('article').add({
          data: {
            md: data.md,
            title: 'test',
            createTime: app.globalData.db.serverDate()
          },
          success: (res) => {
            console.log(res)
          },
          fail: err => {
            console.error('[雲函數] [login] 調用失敗', err)
          }
        })
      },
      fail: err => {
        console.error('[雲函數] [login] 調用失敗', err)
      }
    })
  }

  ...
  ...
})
複製代碼

注意三點:

  • 經過 wx.cloud.callFunction 調用雲函數進行登錄,且獲取 openid,接着導入數據會自動帶上提交該 openid。
  • 經過 app.globalData.db.serverDate() 獲取服務端時間,客戶端時間不可靠
  • 文章導入只由管理員負責

注意 import data from './test.md',這裏經過修改 omip 裏的 scripts 邏輯實現。

這裏解釋下 import markdown 原理:

let code = fs.readFileSync(item).toString()
if (path.extname(item) === '.md') {
  code = `export default { md: \`${code.replace(/`/g, '\\`').replace(/\$/g, '\\$')}\` }`
}
複製代碼

檢測到 md 後綴的文件,把文件裏的 markdown 字符串對關鍵字進行轉義而後變成一個 js 模塊。

這也算是使用中間編譯的好處之一吧,若是原生的小程序目前沒辦法 import markdown 文件,固然原生小程序 API 和周邊生態在不斷進化,騰訊 Omi 團隊開發的 mps 框架 就是讓你在原生小程序中使用 jsx 和 less。

上面的詳細代碼能夠點擊這裏查看到。

列表頁

請求 list 數據

//先展現 loading
 wx.showLoading({
    title: '加載中'
  })
  //調用雲函數獲取 openid
  wx.cloud.callFunction({
    name: 'login',
    data: {},
    success: res => {
      app.globalData.openid = res.result.openid
      app.globalData.db.collection('article').field({
        title: true,
        _id: true,
        order: true
      }).get().then(res => {
        this.data.list = res.data.sort(function (a, b) {
          return a.order - b.order
        })
        this.update()
        wx.hideLoading()
      })
    },
    fail: err => {
      console.error('[雲函數] [login] 調用失敗', err)
    }
  })
複製代碼
  • 請求 list,經過 field 方法篩選字段,畢竟 list 不須要 md 字段,這樣能夠減小數據傳輸,節約帶寬
  • 經過 order 字段對 list 進行排序(這樣管理員不須要發版本就能夠手動調整 order 給 list 排序)

完整的代碼:

import { WeElement, define } from 'omi'
import './index.css'
import arrowPng from './arrow.png'

//獲取應用實例
const app = getApp()

define('page-about', class extends WeElement {
  config = {
    navigationBarBackgroundColor: '#24292e',
    navigationBarTextStyle: 'white',
    navigationBarTitleText: 'Omi',
    backgroundColor: '#ccc',
    backgroundTextStyle: 'light'
  }

  data = {
    list: []
  }

  installed() {
    wx.showLoading({
      title: '加載中'
    })
    wx.cloud.callFunction({
      name: 'login',
      data: {},
      success: res => {
        console.log('[雲函數] [login] user openid: ', res.result.openid)
        app.globalData.openid = res.result.openid
        app.globalData.db.collection('article').field({
          title: true,
          _id: true,
          order: true
        }).get().then(res => {
          this.data.list = res.data.sort(function (a, b) {
            return a.order - b.order
          })
          this.update()
          wx.hideLoading()
        })
      },
      fail: err => {
        console.error('[雲函數] [login] 調用失敗', err)

      }
    })
  }

  gotoDetail = (evt) => {
    wx.navigateTo({
      url: '../detail/index?id=' + evt.currentTarget.dataset.id
    })
  }

  render() {
    return (
      <view class='ctn'> {list.map(item => ( <view class='item' data-id={item._id} bindtap={this.gotoDetail}> <text>{item.title}</text> <image src={arrowPng}></image> </view> ))} </view>
    )
  }
})
複製代碼

Omip 能夠直接讓你使用 jsx 書寫 wxml 結構。編譯出的 wxml 以下:

<block>
  <view class="ctn">
    <view class="item" data-id="{{item._id}}" bindtap="gotoDetail" wx:for="{{list}}" wx:for-item="item"><text>{{item.title}}</text>
      <image src="{{arrowPng}}"></image>
    </view>
  </view>
</block>
複製代碼

這裏須要注意,點擊每一項跳轉詳情也必定要使用 evt.currentTarget.dataset.id,而不能使用 evt.target.dataset.id。這樣點擊到文字或者image 上獲取不到 id。

文章詳情展現

這裏使用 Comi 進行 markdown 渲染! Comi 讀 ['kəʊmɪ],相似中文 科米,是騰訊 Omi 團隊開發的小程序代碼高亮和 markdown 渲染組件。Comi 是基於下面幾個優秀的社區組件進行二次開發而成。

  • wxParse
  • remarkable
  • html2json
  • htmlparser
  • prism

效果預覽:

import { WeElement, define } from 'omi'
import './index.css'
import comi from '../../components/comi/comi'

//獲取應用實例
const app = getApp()

define('page-about', class extends WeElement {
  config = {
    navigationBarBackgroundColor: '#24292e',
    navigationBarTextStyle: 'white',
    navigationBarTitleText: ' ',
    backgroundColor: '#eeeeee',
    backgroundTextStyle: 'light'
  }

  install(options) {
    wx.showLoading({
      title: '加載中'
    })
    app.globalData.db.collection('article').doc(options.id).get().then(res=>{
      comi(res.data.md, this.$scope)
      wx.hideLoading()
    }).catch(err => {
      console.error(err)
    })
  }


  render() {
    return (
      <view> <include src="../../components/comi/comi.wxml" /> </view> ) } }) 複製代碼

除了在 omip 中使用,原生小程序也可使用 Comi:

先拷貝 此目錄 到你的項目。

js:

const comi = require('../../comi/comi.js');

Page({
  onLoad: function () {
    comi(`你要渲染的 md!`, this)
  }
})
複製代碼

wxml:

<include src="../../comi/comi.wxml" />
複製代碼

wxss:

@import "../../comi/comi.wxss";
複製代碼

大功告成,簡單把!

雲函數與調試

雲函數即在雲端(服務器端)運行的函數。在物理設計上,一個雲函數可由多個文件組成,佔用必定量的 CPU 內存等計算資源;各雲函數徹底獨立;可分別部署在不一樣的地區。開發者無需購買、搭建服務器,只需編寫函數代碼並部署到雲端便可在小程序端調用,同時雲函數之間也可互相調用。

一個雲函數的寫法與一個在本地定義的 JavaScript 方法無異,代碼運行在雲端 Node.js 中。當雲函數被小程序端調用時,定義的代碼會被放在 Node.js 運行環境中執行。咱們能夠如在 Node.js 環境中使用 JavaScript 同樣在雲函數中進行網絡請求等操做,並且咱們還能夠經過雲函數後端 SDK 搭配使用多種服務,好比使用雲函數 SDK 中提供的數據庫和存儲 API 進行數據庫和存儲的操做,這部分可參考數據庫和存儲後端 API 文檔。

雲開發的雲函數的獨特優點在於與微信登陸鑑權的無縫整合。當小程序端調用雲函數時,雲函數的傳入參數中會被注入小程序端用戶的 openid,開發者無需校驗 openid 的正確性由於微信已經完成了這部分鑑權,開發者能夠直接使用該 openid。

在本文的小程序裏有個 todo 的案例,裏面的 remove 使用了雲函數,用於清空全部已完成的任務。

const cloud = require('wx-server-sdk')
cloud.init()

const db = cloud.database()
const _ = db.command

exports.main = async (event, context) => {
  try {
    return await db.collection('todo').where({
      done: true
    }).remove()
  } catch (e) {
    console.error(e)
  }
}
複製代碼

不過最新的IED,雲函數支持了本地調試功能,感興趣的能夠點擊這裏瞭解下。

相關連接

相關文章
相關標籤/搜索