Taro开发小程序扩展全局调用API的实践

2022-07-14 20:57:15 浏览数 (1)

实际电源的两种模型及其等效变换

前情回顾

上篇文章大致总结了前端开发人员在开发过程中需要考虑的问题。今天聊一下Taro开发小程序扩展全局调用API的实践。

为什么问这个问题

一般情况下,拿到设计稿以后会对整体的UI进行划分,考虑某些模块儿可以拆分出来单独作为一个组件,组件又可以分为展示组件行为组件,展示组件只负责展示界面,行为组件则带有属于自己的动作。

进行模块儿拆分最大的好处就是解耦,讲一个复杂的页面逻辑拆分成多个简单的小模块儿,根据需要进行组合的同时又实现了代码复用,同时又增强了代码的可读性及可维护性,真是一举多得。

Taro有个全局的APIshowModal方法,用来对用户进行弹窗提示。但是有时候UI出的稿子跟这个showModal的样式不一样,并且有很多地方都会用到这个自己定义的弹窗。

这个时候能不能定义一个跟Taro.showModal()同样可以用API调用的组件呢?

基于Taro扩展API调用组件的实践

  • 尝试实现全局API调用

按照以往的经验,封装一个组件,组件内部提供show,hide方法,然后将该组件挂载到全局对象上即可。实例代码如下:

代码语言:javascript复制
// 组价代码
import React, {useState,useEffect} from 'react';
import {Dimensions,View,Text,Image,StyleSheet} from 'react-native'
var width = Dimensions.get('window').width;//得到屏幕宽度
class Alert extends React.Component {
  constructor(props){
    super(props)
    this.state = {
      visible:false,
      type:'success',
      msg:''
    }
  }
  //////////////  更新部分 更新show 方法 
  show = ({
    msg,
    duration,
    type,
    cb
  }) => {
    this.setState({
      visible:true,
      type:type,
      msg:msg
    })
      setTimeout(()=>{
        this.setState({
          visible:false
        })
        if(cb && typeof cb == 'function'){
          cb()
        }
      },duration||3000)
    }
  // 组件内属性 控制显示隐藏

  render(){
    const { visible,type,msg} = this.state
    if(visible){
      return (
        <View style={Style[type]}>
          <Text style={Style.msgColor}>{msg}</Text>
        </View>
      )
    }
     return null
  }
}
})
export default Alert
代码语言:javascript复制
// 挂载到全局
const App = () => {
 return (
  <NavigationContainer>
   <Drawer.Navigator
    screenOptions={{
     headerStyle: {
      backgroundColor: '#f4511e',
      borderBottomWidth: 0,
      elevation: 0
     },
     headerTintColor: '#fff',
     headerTitleStyle: {
      fontWeight: 'bold',
      // textAlign:'center'
     },
     header: () => {
      return null
     }
    }}
   >
    <Stack.Screen name="Main" component={MainStackScreen} />
    <Stack.Screen name="BriefInfo" component={BriefInfo} />
    <Stack.Screen name="BaseInfo" component={BaseInfo} />
    <Stack.Screen name="ResetPass" component={ResetPass} />
   </Drawer.Navigator>
  // 这里用ref挂载到全局
   <Alert ref={(ref) => { global.Alert = ref }} />
  </NavigationContainer>
 )
}

调用方式

代码语言:javascript复制
// api 调用方式
global.Alert.show({
  title:'title',
  content:'content'
})

这种写法在web及react-native中是可行的,但是在小程序中就不行了。,web及react-native中之所以可行,是因为这个组件可以渲染到界面上,但是在小程序上这个组件没办法提前渲染到界面上,因为小程序跟web不同,web应用可以将别的界面当做模板插入根元素中,小程序的界面是一个个独立的webView,小程序界面的通信也是由微信客户端做中转。而且写在小程序里面的js也是采用jsCore线程运行JS脚本。

小程序的通信模型下图所示:

个人对jsCore的理解仅限于知道它是WebKit 的 JavaScript 引擎,基于C言实现的。所以这个基于Taro扩展一个全局调用的API算是失败了。

  • 基于redux的实现

这个实现发方法就比较简单了。思路是先实现一个弹窗组件,然后将小程序的界面作为children。需要显示弹窗的时候就dispatch({type:'showMotal',payload:{...}})

这个方法也是个比较不错的方法,新项目的话可以很方便的进行全局调用,如果是老项且页面特别多的情况下,就需要多次复制粘贴才行。

扩展一个全局调用的API到底能不能实现?

根据目前个人的实践,在自己的项目中基于Taro扩展一个涉及底层操作的API似乎是实现不了的。但是扩展一些工具方法及其他函数还是可以的。比如:

代码语言:javascript复制
  Taro.protoType.tellStroy=function(){
    console.log('tell a story')
  }
  // 调用
  Taro.tellStory()

今日总结

  • 实现API调用的方法
  • 小程序通信模型
  • 考虑上面那些问题的目的在于提高生产效率

下一篇文章聊聊多语言适配方案

javascript基础知识总结

0 人点赞