给前端的flutter指南

    技术2022-07-11  111

    指南介绍

    如果你是前端开发人员,对Flutter感到好奇,想了解一下?

    如果使用过React Native, 那么同为跨平台框架,flutter上手究竟有多难?

    然后我尝试了一下……令我惊讶的是,我能够立即编写出高效的代码。以下内容将比较 Dart / Flutter 和 JS / ReactNative。

    前端使用 Ts , flutter 使用 dart 语言。

    程序的入口

    对于Js开发人员,程序并没有特定的一个入口。

    dart则指定了**方法main()**作为程序启始入口

    index.ts

    export const app = () => { // init app }; app();

    main.dart

    main() { // 程序内容 }

    变量

    typescript中第一个文件通常叫做index.ts,而在dart中第一个文件名通常叫做main.dart

    index.ts

    // Reassignable variables let person: string; person = 'jeff'; person = 'bob'; // Single assignment variables const lucky: number = 23; // Implicit const implicit = { name: 'Jeff' }; // Any const whoKnows: any = getSomethingDynamic();

    main.dart

    // Reassignable variables String person; person = 'Jeff'; person = 'Bob'; // Single Assignment final int lucky = 23; // Single Assignment & Immutable const Map person = 'Jeff'; // Implicit var implicit = { 'name': 'Jeff' }; // Map<String, String> // Any type dynamic whoKnows = getSomethingDynamic();

    import/export 导入导出

    在Js中,有几种导入/导出值的方法,所以让我们看一下现代的ES6方法。

    global.ts

    export default const = 'JS'; // or export const lang = 'JS';

    index.ts

    import lang from 'globals'; // or import { lang } from 'globals';

    在dart中, 一旦引入文件,那么有权访问声明该文件的所有内容。这个避免了Js中大量的import xxx😠 global.dart

    final String lang = 'Dart!';

    main.dart

    import 'globals.dart'; main() { print(lang) }

    打印 logging

    index.ts

    console.log('howdy!');

    main.dart

    print('howdy!');

    Map(键值对) 和 Object

    在Js中一个键值对就是map,而在dart中专门定义了Map这个类型指代键值对。

    index.ts

    const state = { lucky: 23 } state['unlucky'] = 11; const state = new Map([['lucky', 23]]); state.set('unlucky', 11);

    main.dart

    Map state = { 'lucky': 23 }; state['unlucky'] = 11;

    List and Array 列表 和数组

    在Js中,一个有序队列叫做 array(数组)。在dart中,一个有序队列叫做List(列表)

    index.ts

    const things: number[] = [1, 2, 3]

    main.dart

    List<int> things = [1, 2, 3]; things.forEach() things.reduce() things.last;

    Function 方法

    Js开发人员应该对Dart中的函数感到非常熟悉:它支持命名,匿名,箭头和高阶函数。 主要区别在于dart不需要function关键字。

    index.ts

    function addOne(val: number) { return val + 1; } // Higher Order function callme(cb: Function) { return cb('Hello?'); } callme((v) => console.log(v));

    main.dart

    addOne(int val) { return val + 1; } // Higher Order callme(Function cb) { return cb('Hello?'); } callme((v) => print(v));

    Class 类

    在Dart中会频繁地使用Class,它们非常强大。该语言支持基于mixin(混合)的继承,该继承可通过composition提供出色的代码重用。在Js中,类只是功能和原型继承的语法糖。

    index.ts

    export const main = () => { const myComponent = new Component() } class Component { }

    main.dart

    main() { var myWidget = Widget(); } class Widget { }

    constructor 类构造器

    在Js中使用class,通常会new一个对象。在Dart中,你可以像调用函数一样通过调用其名称来构造一个类,。直接调用,不用new。另外,你可以使用命名构造函数以不同的逻辑实例化相同的对象。

    index.ts

    export const main = () => { const bar = new Component(1,2); } class Component { constructor(private a, public b) { // non-ts version // this.a = a // this.b = b } }

    main.dart

    main() { Widget foo = Widget.withStrings('1', '2'); } class Widget { // Default Constructor Widget(_a, b); // Named Constructor Widget.withStrings(_a, b); }

    Async Programming 异步编程

    异步内容,Dart Future 与 Js Promise几乎一模一样,非常好理解。其中dart中地关键字 async位置不一样。

    index.ts

    async function howdy() { return 'partner 🤠'; } async function greet() { await howdy(); } greet().then(console.log).catch()

    main.dart

    Future howdy() async { return 'partner 🤠'; } greet() async { await howdy(); } greet().then(print).catchError();

    Streams and Observables 流和观察者

    JavaScript中还没有流式数据结构,但它们通过第三方库,比如RxJS,Mobx,和其他库共同提供。

    流类似于Promise(Future),区别在于A Stream就像一个Future事件发射中心,随着时间的推移会发出多个值,我们甚至可以将其与async / await use一起使用。

    main.dart

    main() async { var items = Stream.fromIterable([1,2,3]); await for (int i in items) { // do something } // Or setup a listener items.listen(print); }

    flutter框架

    Flutter受到JavaScript框架(例如React / Angular / Vue)的启发,该框架使小组件组件能够在数据更改时以响应式更新UI,也就是数据驱动UI。实际上,Flutter提供了setState一种与ReactJS中完全一样的方法。

    包管理

    pubspec.yaml👉package.jsonPub 👉 NPM
    Js中管理所有地库文件使用: package.jsondart中管理所有地库文件使用: pubspec.yaml

    widget | component

    在flutter中,任何模块都称之为部件 widget 在Js中,任何模块都称之为组件 compoent

    index.ts

    import React from 'react'; import { StyleSheet, Text, View } from 'react-native'; export default class MyApp extends React.Component { render() { return ( <View> <Text>Hello world!</Text> </View> ); } }

    main.dart

    import 'package:flutter/material.dart'; void main() => runApp(MyApp()); class MyApp extends StatelessWidget { @override build(context) { return Center( child: Text('Hello World'), ); } }

    完整的React Native比较

    从react native文档重新创建这个样式化的组件。注意,左侧的Flutter版本具有大约65%的代码占用空间,并保证了类型安全。另请参见本要点中的其他示例。

    Flutter提供了几种管理组件状态的方法。你可以setState像React一样使用,但是还有一些其他内置技术。

    我个人最喜欢的是将状态数据表示为a Stream或Rx Observable,然后使用StreamBuilder小部件有条件地绘制UI。如你所见,这不需要任何显式调用即可呈现UI,而是基于流中发出的最新值。代码占用空间略有改善,但是如果你发现自己频繁设置状态,则可以真正实现这一点。

    Processed: 0.017, SQL: 9