博主是苦逼前端还未写过移动端 , 但是总要掌握一个移动端技术 . 难免什么时候遇见公司需要写移动端 , 决定学习Flutter , 不然到时候再学就太迟了 .
会JavaScript 看Dart语法还是比较相似的 , 感觉比较友好.
搭建Dart开发环境:
下载并解压Dart SDK
https://dart.cn/ 右上角获取Dart SDK 然后选取对应系统版本即可
mac 配置环境变量
sudo vim ~/.zshrc
// 指定Dart SDK 安装路径
export PATH=''$PATH:/User/xxx/SDK/dart-sdk/bin''
source ~/.zshrc
Windows 配置环境变量
博主下载2.17版本 默认windows版本 此处有坑 如果不切换其他版本 下载的只是一个1kb的文件, 必须要切换为其它系统SDK 再换回Windows版本 才是压缩包!
使用windows10搜索功能 输入env 便可打开环境变量进行配置
检查是否安装成功
dart --version
Dart文件的后缀是.dart
类型
void main() {
// 打印信息
print('hello Dart');
// 变量 var 常量const 和 final
}
区别:
const是编译期常量 , 用于记录程序在编译期就要能确定的值
final 是运行时常量 , 用于记录程序在运行时确定的值
数值类型
void main() {
// 整数 浮点数
num n1 = 10;
// 整数
int n2 = 10;
// 浮点数
double n3 = 10.1;
// 整数赋值给double会显示为10.0
}
布尔类型
// 布尔类型
bool isLogin = true;
字符串类型
// 字符串类型
String name = 'itcast';
// 字符串拼接 $P{} 插值表达式
String price = '$n3起';
列表(类似JS数组)
void main() {
// 定义列表 List
List categories = ['电脑', 'Switch', 'PS5'];
print(categories);
// 列表 增删查改
// length 索引 同JavaScript
// 添加
categories.add('Xbox'); // 类似JavaScript push
// 删除
categories.remove('Xbox');
// 使用索引删除
categories.removeAt(3);
print(categories);
}
字典
void main() {
// 定义字典 { key : value }
Map cetegory = {'id': 1, 'name': 'Waley'};
// 使用字典
String name = cetegory['name'];
print(name);
// 删除: remove(key)
cetegory.remove('name');
print(cetegory);
// 新增: 字典[新key] = 值
cetegory['name'] = 'waley';
print(cetegory);
// 遍历字典
cetegory.forEach((key, value) {
print('$key-$value');
});
}
声明一个可以为空的变量
String? name;
// 非空检查
print(name?.length);
泛型
void main() {
List<String> categories = ['Waley', 'Pauline'];
Map<String, String> category = {
// 参数 key value
'name': 'Pauline',
};
// 函数
T demo<T>(T parm) {
return parm;
}
print(demo<String>('name'));
}
运算符
void main() {
int num1 = 10;
int num2 = 4;
// 取整 10 / 4 = 2 --- 2
print(num1 ~/ num2);
}
函数
// 返回值类型和参数类型是可以省略的
// 函数都有返回值 , 如果没有明确的指定返回值 , 那么默认返回null
void main() {
// 函数定义: 无参数无返回值函数
void func() {
print('这是一个无参数无返回值函数');
}
func();
// 案例: 定义函数 , 计算任意两个整数的和 , 并返回计算结果
int func1(int num1, int num2) {
int result = num1 + num2;
print(result);
return result;
}
func1(1, 2);
// 可选参数 可选参数必须要用花括号包裹起来
void func2(String name, {int? age, String? sex}) {
print('$name-$age-$sex');
}
func2('Waley', age: 15);
// 可选参数默认值
void func3(String name, {int? age = 24, String? sex = '男'}) {
print('$name-$age-$sex');
}
func3('Waley');
}
类
void main() {
// 使用自定义类名构造函数创建对象
Waley waley = Waley('Waley', 18);
// 使用工厂构造函数创建对象
Waley waley1 = Waley.withInfo('子林', 26);
print('我名字是${waley.name}今年${waley.age}岁');
print('我名字是${waley1.name}今年${waley1.age}岁');
}
class Waley {
// 默认构造函数=>和类同名 如果参数名和属性相同 可以简写Waley(this.name, this.age);
Waley(String name, int age) {
this.age = age;
this.name = name;
}
// 定义命名构造函数
Waley.withName(String name);
// 工厂构造函数
factory Waley.withInfo(String name, int age) {
// 需要手动的创建对象并返回
return Waley(name, age);
}
// 属性
String? name;
int? age;
// 方法
void eat() {
print('干饭 干饭');
}
}
私有属性与方法
dog.dart文件
class Dog {
// 公有属性
String? name;
// 私有属性 前面加_下划线表示私有属性
int? _age;
// 公有方法
void eat() {
print('吃狗粮');
}
// 私有方法
void _run(){
print('猛狗奔跑');
}
}
hello.dart文件
import './dog.dart';
void main() {
Dog dog = Dog();
dog.name = '赛虎';
print(dog.name);
dog.eat();
dog._run(); //访问私有属性编辑器和编译的时候会报错
}
继承
和JavaScript类继承一样 extends 写法
1. Dart的继承是单继承 , 一个子类只能有一个父类
2. 子类只会继承父类里面可见的属性和方法 , 不会继承私有属性和方法
3. 子类只会继承父类的默认的构造函数 , 不会继承其他构造函数
4. 子类可以重写父类的方法 , 也可以使用super调用父类方法
void main() {
// 创建实例
Cat cat = Cat('三花');
cat.eat();
}
class Person {
void walk() {
print('行走');
}
}
class Cat extends Animal {
// 继承父类如果写了默认构造函数 那么子类必须写构造函数
Cat(String name) : super(name);
void walk() {
print('行走');
}
// 重写父类方法
@override
void eat() {
// 执行子类自己的逻辑
print('执行子类自己的逻辑');
// 如果要继续调用父类方法
super.eat();
}
}
class Fish extends Animal {
Fish(String name) : super(name);
}
class Animal {
// 默认构造函数
Animal(String name);
// 父类方法
void eat() {
print('eat');
}
}
maxin
三个不同组件 Cat组件和Fish组件和name属性 Cat组件和Person有walk行为 虽然可以给父组件Animal添加name属性和walk行为 但是为了结构更加清晰 使用mixin把walk行为抽离出来
void main() {
// 创建实例
Cat cat = Cat('三花');
cat.eat();
Person person = Person('子林');
person.walk();
}
// 定义mixin mixin关键字
mixin Walkxin {
void walk() {
print('walk');
}
}
// 使用 mixin , with 关键字
class Person extends Animal with Walkxin {
Person(String name) : super(name);
}
class Cat extends Animal with Walkxin {
// 继承父类如果写了默认构造函数 那么子类必须写构造函数
Cat(String name) : super(name);
// 重写父类方法
@override
void eat() {
// 执行子类自己的逻辑
print('执行子类自己的逻辑');
// 如果要继续调用父类方法
super.eat();
}
}
class Fish extends Animal {
Fish(String name) : super(name);
}
class Animal {
// 默认构造函数
Animal(String name);
// 父类方法
void eat() {
print('eat');
}
}
异步编程
web端的异步解决方案是Promise , 配合async-await
Dart提供了异步解决方案Future , 也可以配合async-await
import 'dart:io';
void main() {
// 模拟耗时操作阻塞程序的问题 , 并使用Future解决阻塞问题
// sleep 休眠 Duration 指定时间
print('开始任务');
Future(() {
// 耗时任务执行的地方
sleep(Duration(seconds: 5));
// 返回异步任务执行结果
return '异步任务结束';
}).then((value) {
// value 异步任务执行结果
print(value);
}).catchError((err) {
// 错误信息
print(err);
});
print('不能被阻塞的代码');
}
async-await
import 'dart:io';
void main() {
// 模拟登录操作
Future login(String name) {
return Future(() {
sleep(Duration(seconds: 2));
print('用户登录操作');
return 'Pauline';
});
}
// 保存用户信息操作
Future saveUserInfo(String userInfo) {
return Future(() {
sleep(Duration(seconds: 2));
print('保存用户信息');
return 'ok';
});
}
// async
Login() async {
String userInfo = await login('Pauline');
await saveUserInfo(userInfo);
}
Login();
// 不被阻塞的代码
print('start');
}