前言
一直以来开发用到的框架都是vue,小程序开发也都是使用基于vue的wepy,uniapp.
于是想尝试下react,近来开发小程序项目比较多,首先想到的就是基于react的多端开发框架taro.
本文会对vue react, uniapp taro进行一些简单的书写比较
安装
全局安装脚手架工具
npm i @tarojs/cli -g
新建项目 根据自身需求选择初始化配置
taro init project(项目名)
插件
安装less,以及pxtoviewport的插件
cnpm i less less-loader postcss-px-to-viewport -S
配置less和postcss-px-to-viewport
1. npm eject 释放出配置文件config
2 .进入weboack.config.js
3. 修改cssRegex const cssRegex = /\.(css|less)$/;
4. getStyleLoaders 方法中添加less-loader
{
loader: require.resolve('less-loader')
}
5. getStyleLoaders 方法中添加postcss-px-to-viewport配置参数
plugins: () => [
require('postcss-px-to-viewport')({
viewportWidth: 750, // (Number) The width of the viewport.
viewportHeight: 1334, // (Number) The height of the viewport.
unitPrecision: 3, // (Number) The decimal numbers to allow the REM units to grow to.
viewportUnit: 'vw', // (String) Expected units.
selectorBlackList: ['.ignore', '.hairlines'], // (Array) The selectors to ignore and leave as px.
minPixelValue: 1, // (Number) Set the minimum pixel value to replace.
mediaQuery: false // (Boolean) Allow px to be converted in media queries.
}),
]
开发
taro和react一样开发文件通常都分为两个js/jsx, css,css和js,html是分开的,
vue/uniapp则大多都直接写在一个文件里面,个人比较习惯使用vue的方式,在写样式和页面代码时不用多开窗口
taro.js
import Taro, { Component } from "@tarojs/taro";
import { View, Text, Image, Button } from "@tarojs/components";
import Panel from "../components/panel/panel";
使用taro进行html编写的时候,使用到的标签组件需要先引入进来,vue类就不需要这一步的操作了
export default class Index extends Component {
config = {
navigationBarTitleText: "页面标题"
}
constructor(props) {
super(props);
this.state = { // 这里相当于vue的data
type: 'taro',
img: require("../../assets/img/img.png"), // taro 需要先引入图片才能在html代码块中使用
list: [1,2,3,4,5]
}
}
componentWillMount() // 小程序的onLoad 相当于vue的created
componentDidMount() // 小程序onReady 相当于vue的mounted
componentDidShow() // 小程序的onShow
componentDidHide() // 小程序的onHide
render() // 输出html内容 相当于template
}
react和vue的写法差异点
1 使用变量
react在html中使用state中定义的变量,需要{this.state.type}去指向
vue中是通过{{type}}指向
react可以再render中通过es6对象解构的方式来达到和vue同样的写法
react/taro
render(
let { type } = this.state
return(
<View>{type}</View>
)
)
vue
<template>
<div>{{type}}</div>
</template>
2 标签属性值
taro 使用{}的语法糖 样式类用className 标签首字母需大写
<Image className="img" src={img} />
react 使用{}的语法糖 样式类用className
<img className="img" src={img} />
vue/uniapp 使用:的语法糖
<img class="img" :src="img">
3 列表渲染
react 通过js方法循环
render (
return (
{
list.map((item, index) => {
return (
taro
<View key={index}>{item}</View>
react
<div key={index}>{item}</div>
)
})
}
)
)
vue 通过v-for渲染
<template>
<div v-for="(item, index) in list" :key="index>{{item}}</div>
</template>
4 条件渲染
react
render (
let {type} = this.state
let code = null
if (type === 'taro') {
code = <div>{type}</div>
} else {
code = <div>{type}</div>
}
return (
通过 if else 判断渲染出code
<code />
使用es6的三元运算符渲染
{
type === 'taro' ? (
<div>{type}</div>
) : (
<div>{type}</div>
)
}
使用逻辑运算符&&
{
type === 'taro' && (<div>{type}</div>)
}
)
)
vue
<template>
<div v-if="type === 'taro'">taro</div>
<div v-else>vue</div>
</template>
5 事件处理
react 方法使用箭头函数,不然this回事underfine
test () => {
console.log(this.state.type)
}
render (
return (
<View onClick={this.test}></View>
)
)
或者通过bind绑定this的方式调用
test () {
console.log(this.type)
}
render (
return (
<View onClick={this.test.bind(this)}></View>
)
)
vue
export default {
methods: {
test () {
console.log(this.type)
}
}
}
<template>
<div @click="test"></div?
</template>
taro 方法使用onClick, vue使用@click, vue方法必须写在methods里面
6 组件交互
react
子组件修改父组件的状态时,需要父组件传入一个方法,子组件执行父组件传入的方法去更改
panel组件
import Taro, { Component } from "@tarojs/taro";
import { View, Image, Button } from "@tarojs/components";
export default class Panel extends Component {
static defaultProps = { // 类似于vue的props
type: '',
test: () => {}
}
render(
return (
<div onClick={this.test}>{type}框架</div>
)
)
}
父组件
render(
return (
<Panel type={type} onClick={this.test}/>
)
)
vue
子组件通过this.$emit让父组件执行方法
panel组件
<template>
<div @click="emit">{{type}}框架</div>
</template>
export default {
props: {
typeL String
},
methods: {
emit () {
this.$emit('clickTest')
}
}
}
父组件
<template>
<Panel :type="type" @clickTest="test" />
</template>
export default {
methods: {
test () {
console.log(this.type)
}
}
}
react组件调用方法的方式更加的方便,vue需要子组件再去通知到父组件,麻烦一些
7 渲染html内容
vue
<div v-html="html"></div>
react
<div dangerouslySetInnerHTML={{ __html: html }}></div>