小程序开发 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、更好的支持 mobX
、redux
等全局状态管理,函数式适合无状态的组件,当然通过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特性等等; 其中对 compositionAPI
和 Script-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.2
的Script-setup
语法糖优势明显
1、不需要 return 语句,在 script-setup 中定义的变量默认 export;
2、支持更好的 props 验证、默认值撰写;
3、引入的组件,不需要在 components 中重新声明一次,可在 template 中直接引用;
提个疑问
不得不说,vue3 和 React 对 TypeScript 的支持度都很好;
在 Taro_React 开发中遇到一个这样的问题:
背景: ios 端,原生键盘,第三方键盘遇不到这个问题;
对话框中,当我在使用小程序中的 input 框,输入中文,在候选词阶段,即未按确认,当对方来信息的时候;会出现候选词置空
;
个人猜测:当对方来信息时,React 会 DiffDom,发现数据不一样,重新渲染 Dom 树,而原生键盘的候选词状态因此被重置了。请问有什么解决方法吗?各位大神;