俗话说光说不练假把式。那就先来感受下Weex的魅力:
目前项目已上传至GitHub上,需要的可自行前去下载:
原生项目(Xcode)
Weex项目(WebStorm)
一.目的
Weex虽然从阿里爸爸把它生出来也有两年时间了,但我想对于广大开发者来说,可能对它的了解少之又少。对于这种新鲜的事物,我们总是要持有敬畏的态度的,因为当你在进一步了解它的时候,你会发现它有无穷的魅力在吸引你。我当初就是被它的魅力深深吸引,想更深入的了解,但我在度娘那里没有找到多少真正的项目实战,即使有也是比较笼统的讲了一下大概,没有详细的介绍。因此我写此篇文章的目的是帮助那些刚刚开始接触Weex又急于想找个项目练手的新手玩家们,我会以一个初学者的角度,尽可能的讲解项目的每个细节。
二.声明
对于小白:如果在这之前你没听说过Weex,那很好,这篇文章你可以读一读。啥?没兴趣?那我可以把Weex的广告语透露给你,Write Once, Run Everywhere。点我
对于新手:如果你是刚刚开始接触并且跃跃欲试的新手玩家,正想找个真实项目练练手。那更好,这篇文章对你在合适不过了。跟我一起,边学边练。我会一步一步的介绍整个项目的流程。
对于大佬:如果您是Weex大佬,那更好了。不要走,留下联系方式,小弟我有点问题想跟您请教请教。
学习门槛:
1.Vue:Vue语言基础
2.ES6:ECMAScript 6 入门
3.iOS或者安卓开发语言和编辑器基本使用
还有一点我觉得有必要先声明一下,由于本人的文字能力有限,有些地方语言表达可能不太清楚,文章排版可能不太清晰,但是这又有什么关系呢,再大的困难也挡不住大家的热情啊!由于内容很长而本人时间有限,只能在工作之余写一些东西,所以打算不定时更新,不便之处还请谅解。好了废话不多说了,开始入正题吧。。。
三.那就开始吧
开发环境:macOS 10.13.4
开发工具:WebStorm 2018.1 Xcode 9.3
本项目采用的是集成的方式,即将 Weex 集成到已有的应用。为什么呢?原因有两点,一:Weex TabBar(标签栏)和NavigationBar(导航栏)不太好用,需要用到第三方的组件,我想与其用第三方的不如直接用原生代码写了。二:本人认为项目中还是需要用原生的代码的,毕竟像Weex这种新生事物,很多地方有待完善,完全依赖未免在有些地方会存在力不从心,所以为了增强代码可控性,我建议使用集成的方式。(个人看法,不喜勿喷)
新建原生工程:
1.新建一个Xcode工程,建立目录结构如下:(里面的类文件暂时先不要建,之后会慢慢的一一说明)2.通过cocoaPods向项目中导入最新版本的WeexSDK,在 Podfile 文件中添加如下内容:(至于cocoaPods怎么使用就在这就不多赘述了,不会的可以去问问度娘)
target 'demo' do
# Uncomment the next line if you're using Swift or would like to use dynamic frameworks
# use_frameworks!
# Pods for demo
pod 'WeexSDK'
target 'demoTests' do
inherit! :search_paths
# Pods for testing
end
target 'demoUITests' do
inherit! :search_paths
# Pods for testing
end
end
打开命令行,切换到你已有项目 Podfile 这个文件存在的目录,执行 pod install,没有出现任何错误表示已经完成环境配置。至此,原生的工程就算大功告成了。
新建Weex工程:
1.新建一个Weex工程,建立目录结构如下:(里面的类文件暂时先不要建,之后会慢慢的一一说明)
啥?你告诉我你不会!那不可能吧,既然都来实战了,我默认你会这些基本的操作了啊。哪有都上阵打仗了不会用枪的道理。。。(不会请看这里)
2.下一步就是进入刚刚创建的文件夹,并且安装依赖,然后执行 npm start:
cd your`s project file
npm install
npm start
然后工具会启动一个本地的 web 服务,监听 8081 端口。
当你出现这种页面的时候,那么恭喜你,你的Weex工程算是新建好了。
开始写代码
1.打开原生工程
(1)创建GlobalDefine文件,里面加1条宏,其值就是Weex工程中index.js文件的路径。这样做的好处就是当我们在Weex项目中修改好代码之后,原生项目只需要重新加载一次js文件就可以同步看到修改之后的效果,不需要每次都拷贝过来,然后在build一次原生项目。
#define HomeJS @"/Users/peter/Desktop/weexCode/weexDemo/dist/index.js"
(2)创建.pch文件,为以后类文件引用做准备。
#import
#import "GlobalDefine.h"
(3)在info.plist中添加Allow Arbitrary Loads并设置值为YES(不会就点我)。如果不设置会无法进行http请求哦,当然也加载不了网络图片咯。
(4)由于weexSDK 目前没有提供图片下载的能力,在WXImgLoaderProtocol 定义了一些获取图片的接口, image 组件正是通过 WXImgLoaderProtocol 获得并展示图片,我们可以实现该 protocol 中的接口方法,这样 image 标签才能正常展示图片。这就需要我们自定义handler并注册了。在WeexCustom目录下创建WXImgLoaderDefaultImpl类,实现WXImgLoaderProtocol协议里面的方法。
@implementation WXImgLoaderDefaultImpl
#pragma mark -
#pragma mark WXImgLoaderProtocol
- (id)downloadImageWithURL:(NSString *)url imageFrame:(CGRect)imageFrame userInfo:(NSDictionary *)userInfo completed:(void(^)(UIImage *image, NSError *error, BOOL finished))completedBlock
{
if ([url hasPrefix:@"//"]) {
url = [@"http:" stringByAppendingString:url];
}
return (id)[[[SDWebImageManager sharedManager] imageDownloader]downloadImageWithURL:[NSURL URLWithString:url] options:0 progress:^(NSInteger receivedSize, NSInteger expectedSize, NSURL * _Nullable targetURL) {
} completed:^(UIImage * _Nullable image, NSData * _Nullable data, NSError * _Nullable error, BOOL finished) {
if (completedBlock) {
completedBlock(image, error, finished);
}
}];
}
@end
(5)在NativeFile下面创建四个Controller分别对应底部四个标签栏。并且自定义TabBarController文件继承系统的UITabBarController作为项目的根控制器。
@implementation TabBarController
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor whiteColor] ;
[self setViewControllers:self.allControllers animated:NO];
}
- (NSArray *)allControllers{
if (_allControllers == nil) {
HomeViewController *home = [[HomeViewController alloc] init] ;
ShopViewController *shop = [[ShopViewController alloc] init] ;
MineViewController *mine = [[MineViewController alloc] init] ;
MoreViewController *more = [[MoreViewController alloc] init] ;
NSArray *array = @[[self navWithRoot:home title:@"首页" image:@"icon_tabbar_homepage" selectedImage:@"icon_tabbar_homepage_selected"],
[self navWithRoot:shop title:@"商家" image:@"icon_tabbar_merchant_normal" selectedImage:@"icon_tabbar_merchant_selected"],
[self navWithRoot:mine title:@"我的" image:@"icon_tabbar_mine" selectedImage:@"icon_tabbar_mine_selected"],
[self navWithRoot:more title:@"更多" image:@"icon_tabbar_misc" selectedImage:@"icon_tabbar_misc_selected"]];
_allControllers = [[NSArray alloc] initWithArray:array];
}
return _allControllers;
}
- (UINavigationController *)navWithRoot:(UIViewController *)vc title:(NSString *)title image:(NSString *)image selectedImage:(NSString *)selectedImage {
UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:vc];
UIImage *imageNormal = [UIImage imageNamed:image];
UIImage *imageSelected = [UIImage imageNamed:selectedImage];
UITabBarItem *tabBarItem = [[UITabBarItem alloc] initWithTitle:title image:[[imageNormal bp_scaleWithSize:CGSizeMake(30, 30)] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal] selectedImage:[[imageSelected bp_scaleWithSize:CGSizeMake(30, 30)] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal]];
tabBarItem.titlePositionAdjustment = UIOffsetMake(0, -2) ;
[tabBarItem setTitleTextAttributes:[NSDictionary dictionaryWithObject:[UIColor orangeColor] forKey:NSForegroundColorAttributeName] forState:UIControlStateSelected] ;
nav.tabBarItem = tabBarItem ;
return nav;
}
@end
(6)在WeexConfig目录下创建WeexSDKManager类,用来对WeexSDK的初始化,以及相关自定义组件的注册都可以放在该类里面(我们前面自定义的图片下载WXImgLoaderDefaultImpl就放在这里面注册)。
+ (void)setup;
{
[self initWeexSDK];
[self loadCustomContain];
}
+ (void)initWeexSDK
{
[WXAppConfiguration setAppGroup:@"AliApp"];
[WXAppConfiguration setAppName:@"WeexDemo"];
[WXAppConfiguration setAppVersion:@"1.8.3"];
[WXAppConfiguration setExternalUserAgent:@"ExternalUA"];
[WXSDKEngine initSDKEnvironment];
#ifdef DEBUG
[WXLog setLogLevel:WXLogLevelLog];
#endif
//自定义组件的注册
[WXSDKEngine registerHandler:[WXImgLoaderDefaultImpl new] withProtocol:@protocol(WXImgLoaderProtocol)];
[WXSDKEngine registerModule:@"HomeViewController" withClass:NSClassFromString(@"HomeViewController")];
[WXSDKEngine registerComponent:@"PeterSwitch" withClass:NSClassFromString(@"PeterSwitch")];
}
+ (void)loadCustomContain
{
[[UIApplication sharedApplication] delegate].window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
[[UIApplication sharedApplication] delegate].window.window.backgroundColor = [UIColor whiteColor];
TabBarController *demo = [[TabBarController alloc] init];
[[UIApplication sharedApplication] delegate].window.rootViewController = demo;
[[[UIApplication sharedApplication] delegate].window makeKeyAndVisible];
}
(7)WeexSDKManager对外提供setup的类方法,在AppDelegate的didFinishLaunchingWithOptions方法里面调用。
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
[WeexSDKManager setup];
return YES;
}
(8)万事俱备,接下来需要我们把WeexSDK用起来啊,这就是使用SDK将打包生成的js文件解析成各平台原生组件的过程。进入HomeViewController(首页),代码如下。
@interface HomeViewController ()
@property (nonatomic, strong) WXSDKInstance *instance;
@property (nonatomic, strong) UIView *weexView;
@end
@implementation HomeViewController
WX_EXPORT_METHOD(@selector(weexRender))
WX_EXPORT_METHOD(@selector(iosRender))
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
//隐藏系统导航栏
[self.navigationController setNavigationBarHidden:YES animated:NO];
[self iosRender];
}
- (void)iosRender
{
CGFloat width = self.view.frame.size.width;
CGFloat height = self.view.frame.size.height;
[_instance destroyInstance];
_instance = [[WXSDKInstance alloc] init];
_instance.viewController = self;
_instance.frame = CGRectMake(0, 0, width, height-49);
__weak typeof(self) weakSelf = self;
_instance.onCreate = ^(UIView *view) {
[weakSelf.weexView removeFromSuperview];
weakSelf.weexView = view;
[weakSelf.view addSubview:weakSelf.weexView];
UIAccessibilityPostNotification(UIAccessibilityScreenChangedNotification, weakSelf.weexView);
};
_instance.onFailed = ^(NSError *error) {
WXLogDebug(@"%@", @"Render onFailed...");
};
_instance.renderFinish = ^(UIView *view) {
WXLogDebug(@"%@", @"Render Finish...");
};
_instance.updateFinish = ^(UIView *view) {
WXLogDebug(@"%@", @"Update Finish...");
};
//这里的HomeJS就是全局的宏定义
NSURL *URL = [NSURL fileURLWithPath:HomeJS];
[_instance renderWithURL:URL options:@{@"bundleUrl":URL.absoluteString} data:nil];
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
//只要点击屏幕就会调用这个方法,重新解析一次js文件,这样做的好处就是不需要重新build项目就能刷新js
[self iosRender];
}
- (UIStatusBarStyle)preferredStatusBarStyle
{ //修改顶部状态栏(电池栏)颜色为白色
return UIStatusBarStyleLightContent;
}
- (void)dealloc
{ //控制器销毁的时候要做相应处理
[_instance destroyInstance];
}
@end
(9)这些完成之后build一下原生项目,之后自动启动Xcode自带模拟器,神奇的一幕出现了。哇!成就感爆棚有木有,之前的一切努力都是值得的,这就是前端开发的魅力所在。
至此我们原生部分代码就可以告一段落了,之后在写“商家”、“我的”和“更多”的时候还需要再回来,接下里我们大部分工作都会在Weex项目中完成。
2.打开Weex项目
(1)在Home目录下创建Home.vue文件,用来写首页。
(2)进入index.vue,将Home.vue引入进来。
//scoped-以表示它的样式作用于当下的模块,很好的实现了样式私有化的目的
(3)新建globalDefine.js文件,放一些全局的变量
exports.apiUrl = {
resUrl:'http://192.168.0.225:8081/images/'
}
首页
1.顶部导航栏:
代码注解:
1.为了简化页面设计和实现, 屏幕的宽度统一为750像素,不同屏幕会按照比例转化为这一尺寸。
2.标准CSS支持很多样式选择器, 但Weex目前只支持单个类的选择器。
3.标准CSS支持很多的长度单位,Weex目前只支持像素,并且px在样式中可以忽略不写, 直接使用对应的数值。
4.标准CSS包含了非常多的样式属性,但Weex只支持了其中的一部分,包括盒模型,flexbox,position等布局属性。以及font-size,color等样式。
5.v-bind动态绑定指令,默认情况下标签自带属性的值是固定的,在为了能够动态的给这些属性添加值,可以使用v-bind:你要动态变化的值="表达式"。
6.v-bind用于绑定属性和数据 ,其缩写为“ : ” 也就是v-bind:src = :src。
7.项目中图片地址均采用基础地址+名称的方式拼接,如果出现图片加载不出来的情况可以在globalDefine.js将resUrl更换成自己本机的ip地址即可。(至于Weex的图片导入方式我建议看一下这篇文章:Weex导入图片)
8.你或许会问为什么我把样式直接写在行内了,个人习惯而已,我喜欢把样式代码比较少的或者不是公共样式采用内联样式,其他的用页内样式。不然一个标签一个class得把我累死。
当我们执行了npm run serve命令之后,我们每一次改变都会自动在Weex Preview渲染,相应的我们点击iOS模拟器重新加载index.js文件会得到最新的页面渲染效果。
2.导航栏做好了接下来就是正文的列表页,整个列表用一个scroller组件包装,里面的每一个cell分开来写,这样可以减轻首页的代码量。
顶部分页视图
{{item.name}}
{{item.name}}
代码注解:
1.由于篇幅的原因我就不把所有代码都截上来了,这里只选取相对重要的部分,需要的童鞋请前去下载完整项目。
2.为什么用slider而不用scroller?slider组件用于在一个页面中展示多个图片,在前端,这种效果被称为轮播图。它支持任意类型的Weex组件作为其子组件,而且它有一个专属子组件—indicator用于显示轮播图指示器效果,这个indicator必须充当slider组件的子组件使用才有效果。
3.@change="onchange",slider的事件,当轮播索引改变时,触发该事件。
4.
循环创建每一个item,注意v-for语句的写法。如果只是一重循环直接v-for="item in items"就可以了,其中item就是items里面的每一个元素,在其子组件中可以直接使用item赋值。
5.indicator作为子组件之间写在slider里面就可以了,他会自动随着slider的滑动而改变指示器。
6.text组件只能包含文本值,你可以使用 {{}} 标记插入变量值作为文本内容。不支持子组件。
首页中间视图
探路组碳烤鱼
¥9.5
再减3元
天天特价
特惠不打烊
一元吃
一元吃美食
代码注解:
此处没啥好说的,常规UI布局,注意Flexbox布局技巧。
首页促销视图
最高立减25
美味享不停,赶快行动吧
1元肯德基
1元能吃肯德基
4月开春大促
领21元红包
新用户专享
小长假美美哒
一元抢吧
爆品抢到手软
首页购物中心
购物中心代码:
homeBottomCommonCell组件代码:
{{leftTitle}}
{{rightTitle}}
homeShopCenterItem组件代码:
{{title}}
{{tagTitle}}
代码注解:
1.头部购物中心由于在很多地方都可以用到,且样式差不多,所以可以单独抽出一个组件来用,这里我觉得有必要注意一下正向传值。正向传值的变量名写在组件的props里面,使用的时候需先在script里面引用该组件,然后在components里声明该组件,然后就可以当做正常标签一样来使用了。给组件赋值的语句写在第一个尖括号里面(如果赋的值是一个变量,则需在前面加:,比如
:rightViewBtttomImage = rightViewBtttomImage)
2.内容部分用横向滚动的,里面每个item采用循环创建的方式填充,所以需写一个item组 。
3.设置的滚动方向,scroll-direction定义了 scroller 的滚动方向,样式表属性 flex-direction 定义了 的布局方向,两个方向必须一致。当需要一个水平方向的 时,使用 scroll-direction:horizontal 和 flex-direction: row。当需要一个竖直方向的 时,由于这两个值均是默认值,这两个值可以不设置。
4.拿本地json数据,在本地建好json文件,在用的时候引用即可(var homeShopCenterData = require('../resource/homeShopCenter')),注意json的格式和路径是否正确。
5.引用路径:看想引用的文件是否和所在文件处在同一文件夹下,如果在是则只需一个点,如果不在则需两个点然后接对应的文件夹名称。
首页热门频道
这里由于没有什么新的东西就不贴代码了,挺占地方的,注意一下布局技巧,需要的去下载下来看就可以了。
首页猜你喜欢
{{shop.title}}
{{shop.topRightInfo}}
{{shop.subTitle}}
{{shop.subMessage}}
{{shop.bottomRightInfo}}
|
代码注解:
1.公共部分采用上面一样的办法,内容部分使用组件。
2.数据来源,这部分的数据来源自网络,因此网络请求是这块比不可少的,好在Weex本身提供网络请求模块(fetch)。首先引入stream(var stream = weex.requireModule('stream')),在methods周期函数里定义getNews方法,然后created周期函数里调用getNews,传入url,这里fetch请求如果在网页端可能会出现跨域的问题,但是在真机就不会。
3.的高度,本来想等
设置内容并布局成功后拿到内容高度来设置
的高度,然而想法是美好的现实是残酷的。搞了半天没成功,最后只能用等高的cell,用cell的高度乘以数量来设置list高度(有哪位大佬知道怎么做麻烦告诉我下哈)。由于这里是动态的改变组件的高度,所以v-bind就必不可少了。在list标签里面绑定高度样式(v-bind:style="{height:listHeight}"),随后在网络数据请求成功后计算好总高度赋值给listHeight就可以动态改变高度了。
4.的滚动事件,在
标签里写上需要监听的事件名称(@scroll="scrollHandler"),然后在methods周期函数重写scrollHandler方法,该方法有一个参数,里面有滚动时的一些属性值。
5.标签里面函数调用,由于数据返回时图片的链接需要我们处理,所以得写一个专门处理图片链接的函数(dealWithImgUrl),在设置image的src是调用,调用格式(:src="dealWithImgUrl(shop.imageUrl)")。
刷新控件
Refreshing ...
methods:{
onrefresh (event) {
if (this.refreshing == false){
modal.toast({ message: 'Refreshing', duration: 0.2 })
this.refreshing = true
setTimeout(() => {
this.refreshing = false;
}, 500)
}
}
}
代码注解:
1.Weex提供了一个刷新组件, 是 、 、
、 、 的子组件,只能在被它们包含时才能被正确渲染。
2.组件里面可以添加子组件,例如可以添加 。
商家
代码注解:
1.这个页面很简单,一个组件搞定,主要是熟悉Weex的web组件是使用, 不支持任何嵌套的子组件,并且必须指定 width 和 height 的样式属性,否则将不起作用。
2.要加载的网页内容的 URL。必须指定一个基于 bundle URL 的相对 URL,它将被重写为真实资源 URL(本地或远程)。
3.支持公共事件,绑定自己特有的事件pagestart、pagefinish、error。详情请查阅组件的使用。
我的
更多
页面就不多说了,这里重点讲一下怎么使用原生控件来自定义组件。
1.先来看原生部分的代码:
//创建一个类,一定要继承自WXComponent
#import "WXComponent.h"
@interface PeterSwitch : WXComponent
@end
#import "PeterSwitch.h"
@interface PeterSwitch ()
//自定义组件的属性,可以在weex里面绑定修改
@property (nonatomic, assign) BOOL isOn ;
@property (nonatomic, strong) UIColor *tintColor ;
@property (nonatomic, strong) UIColor *onTintColor ;
@property (nonatomic, strong) UIColor *thumbTintColor ;
@end
@implementation PeterSwitch
//一个 component 默认对应于一个 view,如果未覆盖 loadView 提供自定义 view, 会使用 WXComponent 基类中的 WXView, WXView 是继承自 UIView 的一个派生 view。
- (UIView *)loadView {
UISwitch *mySwitch = [[UISwitch alloc]init];
[mySwitch addTarget:self action:@selector(switchAction:) forControlEvents:UIControlEventValueChanged];
return mySwitch;
}
//对组件 view 需要做一些配置,比如设置 delegate, 可以在 viewDidLoad 生命周期做,如果当前 view 没有添加 subview 的话,不要设置 view 的 frame,WeexSDK 会根据 style 设置。
- (void)viewDidLoad {
UISwitch *mySwitch = ((UISwitch *)self.view);
//tintColor 关状态下的背景颜色
mySwitch.tintColor = _tintColor;
//onTintColor 开状态下的背景颜色
mySwitch.onTintColor = _onTintColor;
//thumbTintColor 滑块的背景颜色
mySwitch.thumbTintColor = _thumbTintColor;
mySwitch.on = _isOn;
}
//支持自定义事件,点击switch发送事件,可以带参数字典,字典将传导weex页面
- (void)switchAction:(UISwitch *)mySwitch{
[self fireEvent:@"onSwitch" params:@{@"isSwitchOn":@(mySwitch.isOn)} domChanges:nil];
}
//支持自定义属性,在 viewDidLoad 中设置属性
- (instancetype)initWithRef:(NSString *)ref type:(NSString *)type styles:(NSDictionary *)styles attributes:(NSDictionary *)attributes events:(NSArray *)events weexInstance:(WXSDKInstance *)weexInstance {
if(self = [super initWithRef:ref type:type styles:styles attributes:attributes events:events weexInstance:weexInstance]) {
if (attributes[@"tintColor"]) {
_tintColor = [WXConvert UIColor:attributes[@"tintColor"]];
}
if (attributes[@"onTintColor"]) {
_onTintColor = [WXConvert UIColor:attributes[@"onTintColor"]];
}
if (attributes[@"thumbTintColor"]) {
_thumbTintColor = [WXConvert UIColor:attributes[@"thumbTintColor"]];
}
if (attributes[@"isOn"]) {
_isOn = [WXConvert BOOL:attributes[@"isOn"]] ;
}
}
return self;
}
//属性更新
- (void)updateAttributes:(NSDictionary *)attributes
{
if (attributes[@"tintColor"]) {
_tintColor = [WXConvert UIColor:attributes[@"tintColor"]];
((UISwitch *)self.view).tintColor = _tintColor;
}
if (attributes[@"onTintColor"]) {
_onTintColor = [WXConvert UIColor:attributes[@"onTintColor"]];
((UISwitch *)self.view).onTintColor = _onTintColor;
}
if (attributes[@"thumbTintColor"]) {
_thumbTintColor = [WXConvert UIColor:attributes[@"thumbTintColor"]];
((UISwitch *)self.view).thumbTintColor = _thumbTintColor;
}
if (attributes[@"isOn"]) {
_isOn = [WXConvert BOOL:attributes[@"isOn"]];
((UISwitch *)self.view).on = _isOn;
}
}
@end
//记得要在manager里面注册一下
[WXSDKEngine registerComponent:@"PeterSwitch" withClass:NSClassFromString(@"PeterSwitch")];
2.Weex部分的代码:
{{rightTitle}}
代码注解:
1.v-if ,v-else,这是vue的条件语句,如果v-if的条件判断成立就创建if的组件,否则创建v-else组件。
2.给自定义组件< PeterSwitch > 绑定onSwitch方法,在methods里实现,实现方法里改变属性thumbTintColor的值,可以实现原生组件的属性更改。
作者简介: 就职于甜橙金融信息技术部,负责iOS前端开发工作。对于业内的新技术比较感兴趣,在我看来,新的东西必然是在旧的基础上优化而来,这对我们提高开发效率很有帮助。
如需转载,请注明出处,谢谢~~~