保姆级!!前端必会Taro入门级教学!!

我是歌谣 放弃很容易 但是坚持一定很酷 微信公众号关注前端小歌谣获取前端知识

本文将介绍 Taro 是如何从一个为了解决小程序开发问题的框架演变成一个多端统一开发框架的。

使用 React 语法来写小程序

谈一谈小程序开发

微信小程序为我们的业务提供了一种新的展现形态,但对于开发者来说,开发体验则显得并不那么友好。

首先,从文件组织上看,一个小程序页面或组件,需要同时包含 4 个文件:脚本逻辑、样式、模板以及配置文件,在开发一个功能模块时,就需要在 4 个文件之间切换,而当功能模块多的话,就需要在多个文件之间切换,这样显然非常浪费时间。

其次,从开发方式上看,在前端工程化思想深入人心的今天,小程序的种种开发方式显得有些落后了,主要体现在以下几个方面:

  • 没有自定义文件预处理,无法直接使用 Sass、Less 以及较新的 ES.Next 语法;
  • 字符串模板太过孱弱,小程序的字符串模板仿的是 Vue,但是没有提供 Vue 那么多的语法糖,当实现一些比较复杂的处理时,写起来就非常麻烦,虽然提供了 wxs 作为补充,但是使用体验还是非常糟糕;
  • 缺乏测试套件,无法编写测试代码来保证项目质量,也就不能进行持续集成,自动化打包。

所以,从开发方式上看,小程序开发没有融入目前主流的工程化开发思想,很多业界开发模式与工具没有在小程序开发中得到相应体现,像是从前端工业时代回退到了刀耕火种的年代。

最后,从代码规范上看,小程序的规范有很多不统一的地方,例如内置组件的属性名,有时候是全小写,有时候是 CamelCase 格式,有时候又是中划线分割的形式,这样就导致编码的时候得不时查阅文档才能确定写法。

如何更优雅地开发小程序

在 Taro 的设计之初,我们的想法就是希望能够以一种更加优雅的方式来开发小程序,解决小程序开发上的种种痛点,首先我们希望能使用前端工程化的方式来进行开发,同时在语法上,我们希望能抛弃小程序的四不像语法,遵循一套我们熟悉的框架语法来进行开发,这样不仅能更好地保证开发质量、提升开发体验,同时也能大大降低开发者开发小程序的成本。

于是,在开发方式上,Taro 打造了一套完善编译工具,引入了前置编译的机制,可以自动化地对源文件进行一系列的处理,最终输出小程序上的可执行文件,包括代码的编译转换处理,加入文件预处理功能,支持 NPM 包管理等等,这一部分的原理,将会在后续章节中为大家介绍。而语法标准上,我们把目光投向了市面上流行的三大前端框架。

ReactVueAngular 是目前前端框架三巨头,他们各有各的风格,关于他们的优劣,在业界也是一直争论不休,这本身也是智者见智仁者见仁的事,所以在本文中就不再评述。Taro 最终采用的是 React 语法来作为自己的语法标准,主要有以下几点考虑:

  • React 是一个非常流行的框架,也有广大的受众,使用它也能降低小程序开发的学习成本;
  • 小程序的数据驱动模板更新的思想与实现机制,与 React 类似;
  • React 采用 JSX 作为自身模板,JSX 相比字符串模板来说更自由,更自然,更具表现力,不需要依赖字符串模板的各种语法糖,也能完成复杂的处理
  • React 本身有跨端的实现方案 - React Native,并且非常成熟,社区活跃,对于 Taro 来说有更多的多端开发可能性。

最终,Taro 采用了 React 语法来作为自己的语法标准,配合前端工程化的思想,为小程序开发打造了更加优雅的开发体验。

如何实现优雅

那么如何实现使用 React 来开发小程序呢?在 Taro 中采用的是编译原理的思想,所谓编译原理,就是一个对输入的源代码进行语法分析,语法树构建,随后对语法树进行转换操作再解析生成目标代码的过程。

探索多端可能性

多端统一开发一直是所有开发人员的共同追求。在终端碎片化的大背景下,前有 Hybrid 模式拉开序幕,后有 React Native、Weex 风起云涌,再到如今 Flutter 横空出世,种种这些都是为了能够 Write once, run anywhere 。给每一种终端单独进行开发的成本是昂贵的,所以一个能够尽可能抹平多端开发差异的开发解决方案就显得极为重要。

多端转换原理

开发时我们遵循 React 语法标准,结合编译原理的思想,对代码文件进行一系列转换操作,最终获得可以在小程序运行的代码。而 React 最开始就是为了解决 Web 开发而生的,所以对代码稍加改动,也可以直接生成在 Web 端运行的代码,而同属 React 语法体系下的 React Native,也能够很便捷地提供支持。同理其他平台,如快应用、百度小程序等,将源码进行编译转换操作,也能获得该平台下的对应语法代码。

 

抹平多端差异

基于编译原理,我们已经可以将 Taro 源码编译成不同端上可以运行的代码了,但是这对于实现多端开发还是远远不够。因为不同的平台都有自己的特性,每一个平台都不尽相同,这些差异主要体现在不同的组件标准不同的 API 标准以及不同的运行机制上。

 

可以看出小程序和 Web 端上组件标准与 API 标准有很大差异,这些差异仅仅通过代码编译手段是无法抹平的,例如你不能直接在编译时将小程序的  直接编译成

这一套标准主要以三个部分组成,包括标准运行时框架、标准基础组件库、标准端能力 API,其中运行时框架和 API 对应 @taro/taro,组件库对应 @tarojs/components,通过在不同端实现这些标准,从而达到去差异化的目的。

而在标准的定制上,起初我们想重新定制一套标准规范,但是发现在所有端都得实现这套标准的成本太高,所以我们就思考为什么不以一个端的组件库、API 为标准呢?这样不仅省去了标准定制的时间,而且在这个端上我们可以不用去实现这套标准了。最终在所有端中,我们挑选了微信小程序的组件库和 API 来作为 Taro 的运行时标准,因为微信小程序的文档非常完善,而且组件与 API 也是非常丰富,同时最重要的是,百度小程序以及支付宝小程序都是遵循的微信小程序的标准,这样一来,Taro 在实现这两个平台的转换上成本就大大降低了。 

 

运行时

本文介绍的是 Taro 在编译成小程序和 H5 运行时发生了什么

JSX 转换微信小程序模板的实现

以这段代码为例:

import Taro, { Component } from '@tarojs/taro'
import { View, Text } from '@tarojs/components'class Home extends Component {config = {navigationBarTitleText: '首页'}state = {numbers: [1, 2, 3, 4, 5]}handleClick = () => {this.props.onTest()}render () {const oddNumbers = this.state.numbers.filter(number => number & 2)return (<ScrollView className='home' scrollTop={false}>奇数:{oddNumbers.map(number => <Text 
onClick={this.handleClick}>{number}</Text>)}偶数:{numbers.map(number => number % 2 === 0 && 
<Text onClick={this.handleClick}>{number}</Text>)}</ScrollView>)}
}

Taro 的结构主要分两个方面:运行时和编译时。运行时负责把编译后到代码运行在本不能运行的对应环境中,你可以把 Taro 运行时理解为前端开发当中 polyfill。举例来说,小程序新建一个页面是使用 Page 方法传入一个字面量对象,并不支持使用类。如果全部依赖编译时的话,那么我们要做到事情大概就是把类转化成对象,把 state 变为 data,把生命周期例如 componentDidMount 转化成 onReady,把事件由可能的类函数(Class method)和类属性函数(Class property function) 转化成字面量对象方法(Object property function)等等。

但这显然会让我们的编译时工作变得非常繁重,在一个类异常复杂时出错的概率也会变高。但我们有更好的办法:实现一个 createPage 方法,接受一个类作为参数,返回一个小程序 Page 方法所需要的字面量对象。这样不仅简化了编译时的工作,我们还可以在 createPage 对编译时产出的类做各种操作和优化。通过运行时把工作分离了之后,再编译时我们只需要在文件底部加上一行代码 Page(createPage(componentName)) 即可。

如果你是从 Taro CLIdist 文件夹看编译后的代码会发现它相当复杂,那是因为代码会再经过 babel 编译为 ES5。

除了 Page 类型之外,小程序还有 Component 类型,所以 Taro 其实还有 createComponent 方法。由于 Component 在小程序里是全局变量,因此我们还得把 import { Component } from '@tarojs/taro'Component 重命名。

回到一开始那段代码,我们定义了一个类属性 configconfig 是一个对象表达式(Object Expression),这个对象表达式只接受键值为标识符(Identifier)或字符串,而键名只能是基本类型。这样简单的情况我们只需要把这个对象表达式转换为 JSON 即可。另外一个类属性 statePage 当中有点像是小程序的 data,但它在多数情况不是完整的 data(下文会继续讨论data)。这里我们不用做过多的操作,babel的插件 transform-class-proerties 会把它编译到类的构造器中。函数 handleClick 我们交给运行时处理,有兴趣的同学可以跳到 Taro 运行时原理查看具体技术细节。

再来看我们的 render() 函数,它的第一行代码通过 filter 把数字数组的所有偶数项都过滤掉,真正用来循环的是 oddNumbers,而 oddNumbers 并没有在 this.state 中,所以我们必须手动把它加入到 this.state。和 React 一样,Taro 每次更新都会调用 render 函数,但和 React 不同的是,React 的 render 是一个创建虚拟 DOM 的方法,而 Taro 的 render 会被重命名为 _createData,它是一个创建数据的方法:在 JSX 使用过的数据都在这里被创建最后放到小程序 PageComponent 工厂方法中的 data 。最终我们的 render 方法会被编译为:

_createData() {this.__state = arguments[0] || this.state || {};this.__props = arguments[1] || this.props || {};const oddNumbers = this.__state.numbers.filter(number => number & 2);Object.assign(this.__state, {oddNumbers: oddNumbers});return this.__state;
}

开发指导

  1. 引入目录时如果不是在本模块文件下的不要使用相对路径,要使用绝对路径
如果是js 文件的引入,是和mgr 项目一样的,@/ 代表根目录
如果是 scss 文件的引入,styles 文件也做了 alias,引入的时候 `@import "~@/styles/variables.scss"`
  1. scss写的时候先引入变量文件,颜色字体统一使用定义好的。必选强制看一遍 /variables.scss文件。

我是歌谣 放弃很容易 但是坚持一定很酷

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/406470.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

js获取用户当前所在城市(ip)

被安利到一个是搜狐家查询ip地址的接口&#xff1a; http://pv.sohu.com/cityjson?ieutf-8 直接打开效果如下&#xff1a; 依照惯例&#xff0c;例子用法给大家放上来&#xff1a; <script src"http://pv.sohu.com/cityjson?ieutf-8"></script> <…

关于c++跟java区别的几个总结

之前c&#xff0c;最近java有点混乱&#xff0c;总结一下&#xff1a; 1.在写java程序的时候会发现&#xff0c;假如你自己写了一个类class A{。。。}&#xff0c;这个时候你要实例化&#xff0c;必须new一个&#xff1b;但是在c里面就不用&#xff0c;c中你可以直接声明A a; 为…

命令行编译c#源程序

开发环境&#xff1a;WinXP VS2010(C#) using System;public class Test {public static int Main(string[] args){string str DateTime.Now.ToString("HH:mm:ss"); // 时分秒(各占两位)Console.WriteLine("当前时间&#xff1a;{0}", str);return 0;} …

来自山西机器人乐队_格力:中国第一支工业机器人乐队重磅亮相

原标题&#xff1a;格力&#xff1a;中国第一支工业机器人乐队重磅亮相一直以来&#xff0c;格力的董明珠可谓是媒体的关注焦点&#xff0c;前有董小姐与雷军的10亿赌约&#xff0c;后有格力进军手机行业&#xff0c;现在格力更是涉足汽车以及芯片行业&#xff0c;而格力的智能…

Samba将Linux集成到Windows网络

&#xff08;一&#xff09;Samba是一个与Windows操作系统兼容的文件与打印共享服务器,通过在Linux服务器上配置Samba,可以使Linux系统集成到Windows网络中。在网络中,用户可以使用多种方法实现数据共享,例如常见的Web服务、FTP服务。使用这两种网络服务的好处是&#xff1a;它…

Vue、Element-ui项目中如何使用Iconfont(阿里图标库)

我们使用element-ui、vue开发网站的时候&#xff0c;往往图标是起着很重要的作用。 1.傻瓜式引用&#xff1a;由于这种方法及其简单 省去了很多繁琐的步骤&#xff0c; a.引入项目生成的&#xff0c;图标地址。 b.使用 推荐使用这种&#xff0c;详情请看文档&#xff01;&…

Unity与Android交互

转载自 http://www.narkii.com/club/thread-320335-1.html 这段时间在研究嵌入sdk&#xff0c;途中遇到不少问题和坑&#xff0c;在这就不一一说了。嵌入sdk是比较常见的吧&#xff0c;如接入广告啊&#xff0c; 新浪的分享...... 这些都需要接入sdk的。&#xff08;这些我在这…

自定义overflow:auto的滚动条样式

自定义overflow:auto的滚动条样式

angular路由传递参数_Angular路由——在路由时候传递数据

有3种方式1、在查询参数中传递数据2、在路由路径中传递数据定义路由路径时就要指定参数名字&#xff0c;在实际路径中携带参数。3、在路由配置中传递数据一、在查询参数中传递数据第一步&#xff1a;修改模版中商品详情链接&#xff0c;带一个指令queryParams商品详情效果&…

python自动登录百度空间

参考: http://blog.163.com/sunzs20113126/blog/static/3706880920120105131652/ 开发环境&#xff1a;Fedora12 Python2.6.2 #!/usr/bin/python # coding: GBKimport urllib,urllib2,httplib,cookielibdef auto_login_hi(url,name,pwd):url_hi"http://passport.baidu.c…

SQL WITH NOCHECK 和 CLUSTERED | NONCLUSTERED

ALTER TABLE [dbo].[atr_cont_b] WITH NOCHECK ADD CONSTRAINT [PK_atr_cont_b] PRIMARY KEY CLUSTERED ( [id_cont_b] ) ON [PRIMARY] GO WITH NOCHECK: 指定表中的数据是否用新添加的或重新启用的 FOREIGN KEY 或 CHECK 约束进行验证。如果没有指定&#xff0c;对于新约…

PHP 文件上传全攻略

PHP文件上传功能一般都是大家使用事先封装好的函数&#xff0c;要用的时候直接使用已封装的函数就完了&#xff0c;但有时候不能使用封装函数&#xff0c;还真不大能记住PHP的上传相关的东西&#xff0c;在此做个总结&#xff0c;以备后用。1.表单部分 允许用户上传文件&#x…

JS事件-鼠标滚轮事件

JS事件-鼠标滚轮事件 vue 监听滚轮滚动事件

java语言程序设计教程翁恺第二版课后答案_《JAVA语言程序设计教程(第2版)/翁恺 肖少拥》翁恺,肖少拥著【摘要 书评 在线阅读】-苏宁易购图书...

第1章 Java语言概述1.1 Java的历史1.2 Java程序运行环境与特点1.2.1 跨平台(Cross Platform)&#xff0f;可移植性(Portablc)1.2.2 运行效率1.2.3 稳 定1.2.4 简 单1.2.5 动 态1.3 面向对象的基本概念1.3.1 对 象1.3.2 面向对象1.3.3 类1.4 面向对象程序设计的…

Python网页抓取、模拟登录

From: http://www.cnblogs.com/bboy/archive/2010/10/29/1864537.html 用python抓取网页是非常简单的事&#xff0c;简单的几行代码就可以解决。。。这里稍微记录一下 需要引用的包有主要是 urllib2&#xff0c;urllib也可以引入&#xff0c;具体 看代码 #--------------------…

深入分析Flex [Bindable] (总结)

[Bindable]大概又是Flex用得最多的元数据了。刚开始用用确实好简单&#xff0c;效率真是没的说。不过这几天用着却碰到了些问题&#xff0c;我自己搜集了些资料&#xff0c;想着有必要在blog里总结一下吧。啥是元数据&#xff08;metadata&#xff09;知道就跳过吧。今天不晓得…

爬取IMDBTOP250

在网上看到有人利用pythonbeautifulsoup爬取豆瓣Top250 试着自己模仿这个做了个爬取IMDB的&#xff0c; 可惜只能爬取到11个。 后来检查了超久&#xff0c; 才发现&#xff0c; soupBeautifulSoup(contents)这里&#xff0c;内容不完整&#xff0c;只能到11个电影为止。 代码如…

Vue Video.js播放m3u8视频流格式(video+videojs-contrib-hl)

Vue Video.js播放m3u8视频流格式&#xff08;videovideojs-contrib-hl&#xff09; videojs中文文档详解 Vue.js中this.$nextTick()的使用 videojs画中画小窗口播放问题&#xff1f;