最近在研究React Native,準備用它寫一個筆記APP,但是并沒有搜到很好用的編輯器插件,因此準備使用WebView和已有的Web端編輯器自己封裝一個,
因本人沒有蘋果電腦,因此只嘗試安卓版本
完整專案地址:Tuzilow/rn-xnote
React Native WebView
WebView是一個能夠在原生APP上加載HTML頁面的組件,不過它沒有提供瀏覽器的地址欄、導航欄等功能,在原生APP的開發中經常會用到,
安裝
npm install react-native-webview
# or yarn add react-native-webview
基本使用
引入URL
import React, { Component } from 'react';
import { WebView } from 'react-native';
export default function MyWeb () {
return (
<WebView
source={{uri: 'https://github.com/facebook/react-native'}}
/>
);
}
引入本地檔案
import React, { Component } from 'react';
import { WebView, Platform } from 'react-native';
export default function MyWeb () {
return (
<WebView
source={
Platform.OS === 'ios'
? require('../../../assets/vditor.html')
: {uri: 'file:///android_asset/vditor.html'}
}
/>
);
}
Web和React Native之間的通信
Web到React Native
window.ReactNativeWebView.postMessage(message)該方法接收一個字串,并將該字串發送到React Native中,在React Native中使用WebView組件的onMessage屬性接收
React Native到Web
injectedJavaScript向網頁中注入jsinjectedJavaScriptBeforeContentLoaded在網頁加載之前向網頁中注入jspostMessage(message)向網頁中發送訊息,與window.ReactNativeWebView.postMessage(message)相對應,網頁可以通過監聽message事件收到訊息,
更多API請查看WebView檔案
封裝Vditor
準備HTML檔案
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta
name="viewport"
content="width=device-width, initial-scale=1.0, user-scalable=no"
/>
<!-- 以下檔案建議放到本地使用 -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/vditor/dist/index.css" />
<script src="https://cdn.jsdelivr.net/npm/vditor/dist/index.min.js"></script>
</head>
<body>
<div id="vditor"></div>
<script>
// window.options 會在React Native中通過injectedJavaScriptBeforeContentLoaded注入
const vditor = new Vditor('vditor', {
...window.options,
// 向編輯器輸入時,通過postMessage向React Native發送訊息,觸發onMessage
input: (value) => {
const message = {
type: 'onChange',
message: value,
};
window.ReactNativeWebView.postMessage(JSON.stringify(message));
}
});
// 監聽React Native發送來的訊息
window.document.addEventListener('message', (e) => {
vditor.setValue(e.data);
});
</script>
</body>
</html>
如果是安卓開發,需要將該檔案放到your-project/android/app/src/main/assets/下,之后通過{uri: 'file:///android_asset/xxxx.html'}引入
React Native組件
import React, { useRef, useState } from 'react';
import { WebView, WebViewMessageEvent } from 'react-native-webview';
export default function Vditor() {
const webviewRef = useRef<WebView>(null);
const [content, setContent] = useState('');
// 注入到網頁中的vditor配置資料
const options = `window.options=${JSON.stringify({
mode: 'ir',
toolbar: [],
outline: false,
debugger: false,
placeholder: '可使用markdown語法...',
})}`;
//#region 初始化編輯器內容
useEffect(() => {
const fetchData = https://www.cnblogs.com/xueyubao/archive/2021/02/17/async () => {
// 獲取初始化的資料
const data = await request();
setContent(data);
};
fetchData();
}, []);
useEffect(() => {
webviewRef.current?.postMessage(content);
}, [content]);
//#endregion
const onMessage = (e: WebViewMessageEvent) => {
const data = JSON.parse(e.nativeEvent.data);
if (data.type ==='onChange') {
setContent(data.message);
}
};
return (
<WebView
ref={webviewRef}
onMessage={onMessage}
javaScriptEnabled
source={
Platform.OS === 'ios'
? require('../../../assets/vditor.html')
: {uri: 'file:///android_asset/vditor.html'}
}
injectedJavaScriptBeforeContentLoaded={options}
style={{
height: Dimensions.get('window').height,
width: Dimensions.get('window').width,
}}
/>
);
}
注意:React Native中使用WebView必須要給他設定寬和高,不然可能會導致應用卡死
完整專案地址:Tuzilow/rn-xnote
參考文章
- 手摸手帶你封裝 React Native 富文本編輯器
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/260513.html
標籤:其他
上一篇:兩種輪播圖實作方式
下一篇:CSS頁面demo
