小程序开发 Taro 框架(React 与 Vue3)开发体验

2,685 阅读3分钟

小程序开发 Taro 框架(React 与 Vue3)开发体验

最近接到一个开发需求,是类似聊天室功能的 小程序开发。之前已经做过几次小程序的开发,使用的是原生的书写,一个页面 4 个文件,分拆 scss、wxs,甚至达到 6 个文件之多,十分苦恼。「不得不说,回看原生开发,坑相对来说少很多,文档的完整性也是最好的」。学习的技术栈一直都是 Vue,在小程序开发的契机下,寻找多端开发的框架,当下流行的有 uni-app、Taro;「看了很久 uni-app,配置项总感觉十分复杂;一看到 Taro 的说明文档如此清晰,就马上入坑」,调研了好一会,才发现 Taro 原生语言框架是 React;刚开始的时候,十分纠结,毕竟一直学习 Vue,一下子转入 React,怕有很多坑。「的确后续进了很多坑,特别是异步更新、hook 更新等」想着框架的东西本质上都十分相似的,不如入手看看。

Taro-React-TypeScript

我们都知道 React 有Class函数式 两种组件 个人建议在页面开发,使用 Class组件,为什么呢? 1、更好的支持 mobXredux等全局状态管理,函数式适合无状态的组件,当然通过hook变为有状态的组件,但是对全局状态管理等 npm 包支持却不好; 2、更好支持 生命周期函数; componentDidShow、componentDidHide、onShareTimeline等小程序生命周期函数,只有Class组件支持; 3、函数式组件更适合写公共组件,逻辑更加清晰;

import Taro, { FC, memo } from "@tarojs/taro";
import { View,Input } from "@tarojs/components";
import { useState } from 'react'
import {AtInput } from 'taro-ui';
import {loginSmsVerifyApi,bindXbApi} from '../../api/index'
import { get64string } from '../../util/methods';

import "./index.scss";
type props = {
  arr?: Array<number>;
  handleEmit: any
}
export const PInputbox: FC<props> = ({ arr = [1,2,3,4,5,6],handleEmit }) => {
    const [focusVal, setfocusVal] = useState<boolean>(true) //聚焦 state
    const [pwdValue, setPwdValue] = useState<string>('') // inputValue
    const length = arr.length;
    const onChange = function (event:any) {
      let e = event.detail.value;
      setPwdValue(e)
      if(e.length == 6){
        handleEmit(e)
      }
    }
    //inputbox Click
    const inputBoxClick = function(){
      setfocusVal(true)
    }
    const focusmethod = function(){
    }
    const blurmethod = function(){
      setfocusVal(false)
    }
    return (
        <View className="pint">
          <View className="pint-block" onClick={inputBoxClick}>
          {
                arr.map((item,index)=>{
                  return(
                    <View
                    key={index}
                    className="pint-inputbox" >
                      {
                       index < (pwdValue.length) ? pwdValue.toString().substr(index,1) : ''
                      }
                    </View>
                  )
                })
            }
      <Input
            maxlength={6}
            type="number"
            focus={focusVal}
            value={pwdValue}
            onFocus={focusmethod}
            onBlur={blurmethod}
            className="pint-input" name="pintInput" onInput={onChange}></Input>
          </View>
            </View>
    );
};

Taro-Vue3-TypeScript

当下用 Vue3 的重构进度大概在 60%左右,之前一直学习的是 Vue2;刚入手 Vue3,学习一波新特性: compositionAPI、script-setup、ref特性等等; 其中对 compositionAPIScript-setup特性最为感兴趣。

compositionAPI 通过 ref 进行包裹响应性变量,通过 xxx.value = newValue「在 setup 函数外,可直接 xxx = newValue」,语法上比 React 的 this.setDate({xxx: newValue}) 稍微好一些;

<template>
  <button @tap="increment">
    增加 1
  </button>
  <view>当前todolist事项已有:{{ existCount }}条;</view>
  <view>当前操作已新增:{{ count }} ,共有{{ total }}条。</view>
</template>
<script>
import { ref, computed, onMounted, toRefs, watch } from 'vue'
export default {
  name: 'case1',
  setup(props) {
    // ref响应式变量
    const count = ref(0)
    const existCount = ref(4)
    // computed方法,在count的value发生改变时,会触发计算total
    const total = computed(() => count.value + existCount.value )
    function increment() {
      count.value++
    }

    onMounted(() => console.log('component mounted!'))

    return {
      // 返回increment方法,existCount、count、total属性,供模板中调用
      increment,
      existCount,
      count,
      total,
    }
  }
}
</script>

Script-setup 使用Script-setup语法糖后的页面

<template>
  <view>
    <view>count:{{ count }},msg:{{ info }}</view>
    <button @tap="incAndChangeInfo">
      增加 1修改msg
    </button>
  </view>
</template>
<script setup=" props " lang="ts">
  import { ref, toRefs } from 'vue'
  interface Props {
		msg:String;
		info: String;
}

const props = withDefaults(defineProps<Props>(), {
		msg:'个人信息'
})
   const count = ref(0)
   const info = ref(props.msg)
   const incAndChangeInfo = () => {
    count.value++
    info.value = "change hello" + count.value
  }
</script>

没有使用Script-Setup 上述script标签里的代码效果等同于下面:

<script lang="ts">
import { ref, toRefs } from 'vue'
export default {
  props: {
    msg: String,
    },
  setup(props) {
  const count = ref(0)
  const info = ref(props.msg)
  const incAndChangeInfo = () => {
    count.value++
    info.value = "change hello" + count.value
    }
  return {
    count,
    info,
    incAndChangeInfo,
    }
  }
}
</script>

可以看出,Vue3.2Script-setup语法糖优势明显 1、不需要 return 语句,在 script-setup 中定义的变量默认 export; 2、支持更好的 props 验证、默认值撰写; 3、引入的组件,不需要在 components 中重新声明一次,可在 template 中直接引用;

提个疑问

不得不说,vue3 和 React 对 TypeScript 的支持度都很好; 在 Taro_React 开发中遇到一个这样的问题: 背景: ios 端,原生键盘,第三方键盘遇不到这个问题; 对话框中,当我在使用小程序中的 input 框,输入中文,在候选词阶段,即未按确认,当对方来信息的时候;会出现候选词置空; 个人猜测:当对方来信息时,React 会 DiffDom,发现数据不一样,重新渲染 Dom 树,而原生键盘的候选词状态因此被重置了。请问有什么解决方法吗?各位大神;

video-output-030273BE-249E-4C40-8BFA-2EB7925477C2

image-20211015085359985