uni-app + Cloudbase——uni-app 項目中如何使用騰訊雲開發后端服務


1 基本介紹

uni-app 是一個基於 Vue.js 的跨端開發框架,一套代碼可以發布到 App、小程序、Web 等不同平台

騰訊雲開發平台 Cloudbase 提供的 @cloudbase/js-sdk 可以讓開發者在 Web 端(例如 PC Web 頁面、微信公眾平台 H5 等)使用 JavaScript 訪問 Cloudbase 服務和資源。

但是 @cloudbase/js-sdk 只支持 Web(瀏覽器環境)的開發,不兼容其他類 Web 平台(比如小程序)。因為這些平台在網絡請求、本地存儲、平台標識等特性上與瀏覽器環境有明顯差異。

@cloudbase/js-sdk 不認識這些差異,比如@cloudbase/js-sdk不知道這些平台是怎么發送網絡請求的,因此我們不能在開發類 Web 應用時直接使用@cloudbase/js-sdk

針對這些差異,@cloudbase/js-sdk提供了一套完整的適配擴展方案,遵循此方案規范開發對應平台的適配器,就可以實現平台的兼容性

對於 uni-app,不同於瀏覽器,它基於 ECMAScript 擴展了獨有的 uni 對象,它也不能直接使用@cloudbase/js-sdk,因為它在網絡請求、本地存儲等特性上和瀏覽器環境也存在明顯差異

如果想讓 uni-app 開發的小程序和 PC Web 應用使用同一套雲開發后端服務,就需要開發針對 uni-app 的適配器

2 適配器

開發適配器之前需要安裝官方提供的接口聲明模塊@cloudbase/adapter-interface

# npm
npm i @cloudbase/adapter-interface
# yarn
yarn add @cloudbase/adapter-interface

適配器模塊需要導出一個adapter對象:

const adapter = {
  genAdapter,
  isMatch,
  // runtime標記平台唯一性
  runtime: '平台名稱'
};

export adapter;
export default adapter;

必須包含以下三個字段:

  • runtime: string,平台的名稱,用於標記平台唯一性;
  • isMatch: Function,判斷當前運行環境是否為平台,返回boolean值;
  • genAdapter: Function,創建adapter實體。

runtime

runtime用於標記平台的唯一性

isMatch

isMatch函數用於判斷當前運行環境是否與適配器匹配,通常是通過判斷平台特有的一些全局變量、API 等。

我們可以通過 uni 對象來判斷是否為 uni-app

function isMatch() {
    return uni ? true : false
}

genAdapter

genAdapter函數返回適配器的實體對象,結構如下:

interface SDKAdapterInterface {
  // 全局根變量,瀏覽器環境為window
  root: any;
  // WebSocket類
  wsClass: WebSocketContructor;
  // request類
  reqClass: SDKRequestConstructor;
  // 無localstorage時persistence=local降級為none
  localStorage?: StorageInterface;
  // 無sessionStorage時persistence=session降級為none
  sessionStorage?: StorageInterface;
  // storage模式首選,優先級高於persistence
  primaryStorage?: StorageType;
  // 獲取平台唯一應用標識的api
  getAppSign?(): string;
}

我們只要使用 uni-app 提供的方法來實現指定的接口即可,示例:

// Request類為平台特有的網絡請求,必須實現post/upload/download三個public接口
export class UniRequest extends AbstractSDKRequest {
  // 實現post接口
  public post(options: IRequestOptions) {
    const { url, data, headers } = options
    return new Promise((resolve, reject) => {
      try {
        uni.request({
          url,
          data,
          header: headers,
          method: 'POST',
          success: (res) => {
            resolve(res)
          },
          fail: (err) => {
            reject(err)
          }
        })
      } catch (error) {
        reject(error)
      }
    });
  }
  // 實現upload接口
  public upload(options: IUploadRequestOptions) {
    const { url, file, name } = options
    return new Promise((resolve, reject) => {
      try {
        uni.uploadFile({
          url,
          filePath: file,
          name,
          success: (res) => {
            resolve(res)
          },
          fail: (err) => {
            reject(err)
          }
        })
      } catch (error) {
        reject(error)
      }
    });
  }
  // 實現download接口
  public download(options: IRequestOptions) {
    const { url } = options
    return new Promise((resolve, reject) => {
      try {
        uni.downloadFile({
          url,
          success: (res) => {
            resolve(res)
          },
          fail: (err) => {
            reject(err)
          }
        })
      } catch (error) {
        reject(error)
      }
    });
  }
}
// Storage為平台特有的本地存儲,必須實現setItem/getItem/removeItem/clear四個接口
export const Storage: StorageInterface = {
  setItem(key: string, value: any) {
    uni.setStorage({
      key,
      data: value,
      success: (res) => {
        console.log(res);
      }
    })
  },
  getItem(key: string): any {
    return uni.getStorageSync(key)
  },
  removeItem(key: string) {
    uni.removeStorage({
      key,
      success: (res) => {
        res
      }
    })
  },
  clear() {
    uni.clearStorage()
  }
};
// WebSocket為平台特有的WebSocket,與HTML5標准規范一致
export class WebSocket {
  constructor(url: string, options: object = {}) {
    const socketTask: WebSocketInterface = {
      set onopen(cb) {
        // ...
      },
      set onmessage(cb) {
        // ...
      },
      set onclose(cb) {
        // ...
      },
      set onerror(cb) {
        // ...
      },
      send: (data) => {
        // ...
      },
      close: (code?: number, reason?: string) => {
        // ...
      },
      get readyState() {
        // ...
        return readyState;
      },
      CONNECTING: 0,
      OPEN: 1,
      CLOSING: 2,
      CLOSED: 3
    };
    return socketTask;
  }
}

// genAdapter函數創建adapter實體
function genAdapter() {
  const adapter: SDKAdapterInterface = {
    // root對象為全局根對象,沒有則填空對象{}
    root: {},
    reqClass: UniRequest,
    wsClass: WebSocket as WebSocketContructor,
    localStorage: Storage,
    // 首先緩存存放策略,建議始終保持localstorage
    primaryStorage: StorageType.local,
    // sessionStorage為可選項,如果平台不支持可不填
    sessionStorage: sessionStorage
  };
  return adapter;
}

此處未實現 WebSocket ,若有需要可按需實現

3 接入流程

現在我們有了適配器,就可以愉快地在 uni-app 項目中使用 Cloudbase 了

第 1 步:安裝並引入適配器

安裝 @cloudbase/js-sdk

# 安裝 @cloudbase/js-sdk
npm i @cloudbase/js-sdk

在業務代碼中引入適配器(這里我將適配器放在 utils 目錄下)

import cloudbase from "@cloudbase/js-sdk";
import adapter from '@/utils/adapter.ts'

cloudbase.useAdapters(adapter);

第 2 步:配置安全應用來源

登錄雲開發 CloudBase 控制台,在安全配置頁面中的移動應用安全來源一欄:

點擊“添加應用”按鈕,輸入應用標識:比如 uniapp

添加成功后會創建一個安全應用的信息,如下圖所示:

第 3 步:初始化雲開發

在業務代碼中初始化雲開發時將第 2 步配置的安全應用信息作為參數傳遞給 init 方法:

import cloudbase from '@cloudbase/js-sdk';
import adapter from '@/utils/adapter.ts'

cloudbase.useAdapters(adapter);

cloudbase.init({
  env: '環境ID',
  appSign: '應用標識',
  appSecret: {
    appAccessKeyId: '應用憑證版本號'
    appAccessKey: '應用憑證'
  }
})
  • 環境 ID 可以在環境總覽中獲取:

  • appSignstring,應用標識,對應移動應用安全來源中“應用標識”一欄(比如uniapp)

  • appSecretObject,應用憑證信息,包括以下字段:

    • appAccessKeyIdstring,對應移動應用安全來源中“版本”一欄,同一個應用標識可以最多可以添加兩個版本的憑證信息,以便區分開發和生產環境;
    • appAccessKeystring,對應移動應用安全來源中“操作”一欄點擊“獲取憑證”之后獲取到的信息。

第 4 步:編寫業務代碼

經過以上准備工作之后便可以編寫自身的業務代碼。

比如我們要訪問雲函數 test :

const tcb = cloudbase.init({
	env: '環境id',
	appSign: 'uniapp',
	appSecret: {
		appAccessKeyId: '1',
		appAccessKey:'應用憑證'
	}
})
 
tcb.callFunction({
	name: 'test'
}).then(res => {
	console.log(res)
})

4 訪問權限問題

經過上述准備工作以后,我們可能仍然無法訪問雲函數、雲數據庫、雲存儲等資源,控制台出現如下信息:

這時可以查看訪問權限,以雲函數為例:

4.1 權限控制

點擊雲函數的權限控制按鈕

對雲函數訪問權限進行配置,比如下面將test權限配置成true

4.2 登錄授權

打開登錄授權中的“未登錄”選項,不登錄即可訪問應用

現在,就可以愉快地訪問了~

5 源碼地址

https://github.com/Melonvin/uniapp-cloudbase-demo


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM