HBuilderX

HBuilderX

极客开发工具
uni-app

uni-app

开发一次,多端覆盖
uniCloud

uniCloud

云开发平台
HTML5+

HTML5+

增强HTML5的功能体验
MUI

MUI

上万Star的前端框架

【实战教程】uni-app商城类项目实战视频教程

教程 uniapp 视频教程 uniapp 教程

课程概述

本季度预计220课时,每周三和周六更新,每次更新10课时。

本季度为uni-app实战项目第2季度,将实战开发仿商城类app,其中会包括发布到安卓端app,IOS端app、微信小程序,H5等,另外还会涉及Weex(nvue),Vuex模块化管理,商城支付模块等。

课程学习链接入口:

uni-app实战商城类app和小程序开发视频教程

https://study.163.com/course/courseMain.htm?courseId=1209401825&share=2&shareId=480000001892585

或者进入网易云课堂,搜索uni-app即可看到

课程大纲见以下图!





课程学习链接入口:

uni-app实战商城类app和小程序开发视频教程

https://study.163.com/course/courseMain.htm?courseId=1209401825&share=2&shareId=480000001892585

或者进入网易云课堂,搜索uni-app即可看到

课程目录:(实际参考uni-app实战商城类app和小程序开发视频教程

继续阅读 »

课程概述

本季度预计220课时,每周三和周六更新,每次更新10课时。

本季度为uni-app实战项目第2季度,将实战开发仿商城类app,其中会包括发布到安卓端app,IOS端app、微信小程序,H5等,另外还会涉及Weex(nvue),Vuex模块化管理,商城支付模块等。

课程学习链接入口:

uni-app实战商城类app和小程序开发视频教程

https://study.163.com/course/courseMain.htm?courseId=1209401825&share=2&shareId=480000001892585

或者进入网易云课堂,搜索uni-app即可看到

课程大纲见以下图!





课程学习链接入口:

uni-app实战商城类app和小程序开发视频教程

https://study.163.com/course/courseMain.htm?courseId=1209401825&share=2&shareId=480000001892585

或者进入网易云课堂,搜索uni-app即可看到

课程目录:(实际参考uni-app实战商城类app和小程序开发视频教程

收起阅读 »

获取设备信息(imei、imsi、uuid)的调整使用plus.device.getInfo方法的说明

Device

本功能自HBuilderX 2.0.3+起支持

Android平台各大应用商店已经要求API等级(targetSdkVersion)为26或以上。高版本Android系统完善了授权系统,获取设备信息(如imei)需要经过用户授权确认,弹出获取设备信息的授权提示框:

如果不在manifest里指定,HBuilder的打包默认targetSdkVersion是21,而HBuilderX已经是26了。targetSdkVersion变高就会引发动态权限问题。

目前5+ API获取设备信息是通过以下属性方式读取

为了保证以上属性可用,应用需在启动时进行初始化赋值,原生层这时候就需要申请获取设备信息权限读取imei、imsi等信息。
即使应用没有调用以上API,应用启动时仍然执行此初始化赋值逻辑,导致应用启动时弹出上图所示的设备信息授权提示框。

为了避免应用启动时弹出设备信息授权提示框,新增plus.device.getInfo方法。当应用需要获取设备信息时调用此API,才会触发弹出授权提示框,不获取设备信息就不会弹出设备信息授权提示框。
建议使用5+ API的属性方式获取imei、imsi、uuid信息的代码调整使用plus.device.getInfo方法

至于属性和方法的区别,可能普通程序员看不懂,但做底层的会知道,属性就是启动时就必须初始化的。

原来的plus.device.imei、plus.device.imsi、plus.device.uuid等属性方式的API不推荐使用,后续会逐步废弃。
为了保证向下兼容,目前还可以使用,但不一定可以获取到正确的值。
取决于应用启动前是否已经获取设备信息权限:

  1. 如果应用启动前没有获取设备信息授权(询问或拒绝状态),则无法获取设备信息,按权限被拒绝的逻辑处理。
  2. 如果应用获取设备信息授权,则可以获取设备信息。

注意:调用plus.device.imei、plus.device.imsi、plus.device.uuid不会触发授权提示框

继续阅读 »

本功能自HBuilderX 2.0.3+起支持

Android平台各大应用商店已经要求API等级(targetSdkVersion)为26或以上。高版本Android系统完善了授权系统,获取设备信息(如imei)需要经过用户授权确认,弹出获取设备信息的授权提示框:

如果不在manifest里指定,HBuilder的打包默认targetSdkVersion是21,而HBuilderX已经是26了。targetSdkVersion变高就会引发动态权限问题。

目前5+ API获取设备信息是通过以下属性方式读取

为了保证以上属性可用,应用需在启动时进行初始化赋值,原生层这时候就需要申请获取设备信息权限读取imei、imsi等信息。
即使应用没有调用以上API,应用启动时仍然执行此初始化赋值逻辑,导致应用启动时弹出上图所示的设备信息授权提示框。

为了避免应用启动时弹出设备信息授权提示框,新增plus.device.getInfo方法。当应用需要获取设备信息时调用此API,才会触发弹出授权提示框,不获取设备信息就不会弹出设备信息授权提示框。
建议使用5+ API的属性方式获取imei、imsi、uuid信息的代码调整使用plus.device.getInfo方法

至于属性和方法的区别,可能普通程序员看不懂,但做底层的会知道,属性就是启动时就必须初始化的。

原来的plus.device.imei、plus.device.imsi、plus.device.uuid等属性方式的API不推荐使用,后续会逐步废弃。
为了保证向下兼容,目前还可以使用,但不一定可以获取到正确的值。
取决于应用启动前是否已经获取设备信息权限:

  1. 如果应用启动前没有获取设备信息授权(询问或拒绝状态),则无法获取设备信息,按权限被拒绝的逻辑处理。
  2. 如果应用获取设备信息授权,则可以获取设备信息。

注意:调用plus.device.imei、plus.device.imsi、plus.device.uuid不会触发授权提示框

收起阅读 »

nvue不同编译模式介绍

weex nvue uniapp

HBuilderX2.0.3 版本开始,nvue文件同时支持两种编译模式:

  • weex 模式:老模式,使用 weex组件,写法同weex标准写法。只能在 App 端中运行,部分 uni-app JS Api 不能使用。
  • uni-app 模式:新模式,默认模式,使用 uni-app 基础组件,组件、jsapi写法同uni-app。支持app.vue里的全局样式;支持nvue页面编译H5和小程序端;可以使用绝大部分 uni-app Api 。uni-app模式也可以使用weex里的组件,比如list、refresh、recircle-list。

为什么要提供2个模式?

weex模式的组件、渲染机制是weex官方维护的。它的渲染性能其实与react native是一样的,在性能体验方面足以应付一线互联网公司的苛求。但它有4个问题:

  1. 内置组件较少,或不完善。与小程序的组件相比,weex缺少太多内置组件,比如picker、map。而video等weex已内置的组件,也不够强大
  2. API缺失严重。因为weex只是个渲染器,它调用设备能力或push等三方sdk,都需要原生开发。
  3. 周边生态不完善。weex生态没有什么好的组件和模板。而uni-app的插件市场里众多优秀的组件和模板又无法用于nvue。
  4. nvue无法多端开发,只能用于app。开发者在多端需要维护多套代码。
  5. weex的排版思路和uni-app的vue差异有点多。比如weex不支持rpx。我们希望使用原生渲染,但尽可能多的兼容开发者的习惯。

weex的第二个问题,即能力问题,uni-app通过给nvue补充uni API和plus API,得到了解决。
但剩下的几个问题,需要uni-app的新编译模式才能解决。
我们要把小程序的所有组件,在weex的原生渲染机制上,重新实现一遍,让小程序的组件可以直接用原生来渲染。然后包括uni ui等扩展组件也都将兼容nvue。
现在插件市场的新闻模板,已经支持nvue新编译模式,它可以一套代码编译到App、小程序、H5全端。并且在App上是原生渲染的高性能体验。

之所以仍然存在weex模式,一是为了向下兼容,之前已经使用nvue的weex模式开发的app,不会因为HBuilderX的升级而导致页面错乱;二是为了方便weex的老用户迁移。

对于普通开发者,正常来讲应该选择uni-app编译模式。

注意nvue的uni-app编译模式,仍然是要求写nvue文件。

配置方式--uni-app编译模式或weex编译模式

manifest.json 的源码视图里配置是切换模式, manifest.json -> app-plus -> nvueCompiler 切换编译模式。

nvueCompiler 有两个值:

  • weex
  • uni-app
// manifest.json      
{      
    // ...      
     /* App平台特有配置 */      
    "app-plus": {      
        "nvueCompiler":"uni-app" //是否启用 uni-app 模式    
    }      
}     

差异说明

组件差异

在老的 weex 模式中,我们使用的是 weex组件 遵循的是 weex规范,如果使用 nvue 页面将不能跨端开发,仅能在 App 端运行。如果跨端那么意味着要实现vue 页面和 .nvue 页面两套代码。

代码示例

<template>  
    <div>  
        <text>测试页面</text>  
    </div>  
</template>  

而在 uni-app 模式中,我们将可以在 weex 组件的基础上使用 uni-app 的基础组件,目前已支持部分组件,并支持 .nvue 页面编译到 H5 和小程序端。

代码示例

<template>  
    <view>  
        <text>测试页面</text>  
    </view>  
</template>  

nvue的uni-app编译模式组件使用注意

组件的使用注意事项: 组件 注意事项
text 文字尽量写在text节点,非text节点的文字无法自动更新
rich-text nodes 属性只支持节点列表不支持 HTML String
web-view 必须指定高度,不支持页面通讯和网页内使用Plus API 。但在nvue里可以使用plus.webview.create来创建webview。这样的webview能力上更强大,但注意和原页面会有层级问题

默认页面滚动差异

weex 模式中,我们需要页面滚动,必须使用 <list> 组件或者 <scroller> 组件,这与我们开发小程序或者 web 的习惯并不符合。而在 uni-app 模式中,则可以像 vue 页面一样方便开发,不需要去声明额外的组件进行滚动,只要页面内容高度高于屏幕,就会自动滚动。实际上,在新模式里自动给每个nvue页面的根下套了一个scroller。

单位差异

weex的px是动态单位,并且不支持rpx。这与uni-app的设计不符。
在新模式中,rpx和px分别是动态单位和静态单位,与vue的设计一样。

Tips

注意事项

API 注意事项

.nvue 支持大部分 uni-app API详情

css 注意事项

.nvue 中,有些 css 样式需要注意,与 web 开发中样式写法会有区别。

1、只有text标签可以设置字体大小,字体颜色
2、布局不能使用百分比
3、只能使用 class 选择器


/* 错误 */  
#id {}  
.a .b .c {}  
.a > .b {}  

/* 正确 */  
.class {}  

4、border 不支持简写


/* 错误 */  
.class {  
    border: 1px red solid;  
}  

/* 正确 */  
.class {  
    border-width: 1px;  
    border-style: solid;  
    border-color: red;  
}  

5、background 不支持简写

/* 错误 */  
.class {  
    background: red;  
}  

/* 正确 */  
.class {  
    background-color: red;  
}

6、.nvue 页面的布局排列方向默认为竖排(column),如需改变布局方向,可以在 manifest.json -> app-plus -> nvue -> flex-direction 节点下修改,仅在 uni-app 模式下生效。 详情
7、nvue的uni-app编译模式下,App.vue 中的样式,会编译到每个 nvue文件。非uni-app编译模式不会。对于共享样式,如果有不合法属性控制台会给出警告,可以通过条件编译屏蔽 App 中的警告。

/* 错误 */  
/*  控制台警告:WARNING: `border` is not a standard property name (may not be supported)  */  
.class {  
    border: 1px red solid;  
}  

/* 正确 */  
.class {  
    border-width: 1px;  
    border-style: solid;  
    border-color: red;  
}  

默认逻辑

manifest.json 配置文件中,未明确指定编译模式(即未配置app-plus -> nvueCompiler),在HBuilderX2.4以前,默认值为 weex 模式,2.4起默认值改为 uni-app 模式。

nvue编译为H5、小程序时注意

nvue页面编译为H5、小程序时,会做一件css默认值对齐的工作。
因为weex布局只支持flex,并且默认flex方向是垂直。而H5和小程序端,使用web渲染,web默认不是flex,并且设置display:flex后,它的flex方向默认是水平的。
所以nvue编译为H5、小程序时,会自动把页面默认布局设为flex、方向为垂直。当然开发者手动设置后会覆盖默认设置。

继续阅读 »

HBuilderX2.0.3 版本开始,nvue文件同时支持两种编译模式:

  • weex 模式:老模式,使用 weex组件,写法同weex标准写法。只能在 App 端中运行,部分 uni-app JS Api 不能使用。
  • uni-app 模式:新模式,默认模式,使用 uni-app 基础组件,组件、jsapi写法同uni-app。支持app.vue里的全局样式;支持nvue页面编译H5和小程序端;可以使用绝大部分 uni-app Api 。uni-app模式也可以使用weex里的组件,比如list、refresh、recircle-list。

为什么要提供2个模式?

weex模式的组件、渲染机制是weex官方维护的。它的渲染性能其实与react native是一样的,在性能体验方面足以应付一线互联网公司的苛求。但它有4个问题:

  1. 内置组件较少,或不完善。与小程序的组件相比,weex缺少太多内置组件,比如picker、map。而video等weex已内置的组件,也不够强大
  2. API缺失严重。因为weex只是个渲染器,它调用设备能力或push等三方sdk,都需要原生开发。
  3. 周边生态不完善。weex生态没有什么好的组件和模板。而uni-app的插件市场里众多优秀的组件和模板又无法用于nvue。
  4. nvue无法多端开发,只能用于app。开发者在多端需要维护多套代码。
  5. weex的排版思路和uni-app的vue差异有点多。比如weex不支持rpx。我们希望使用原生渲染,但尽可能多的兼容开发者的习惯。

weex的第二个问题,即能力问题,uni-app通过给nvue补充uni API和plus API,得到了解决。
但剩下的几个问题,需要uni-app的新编译模式才能解决。
我们要把小程序的所有组件,在weex的原生渲染机制上,重新实现一遍,让小程序的组件可以直接用原生来渲染。然后包括uni ui等扩展组件也都将兼容nvue。
现在插件市场的新闻模板,已经支持nvue新编译模式,它可以一套代码编译到App、小程序、H5全端。并且在App上是原生渲染的高性能体验。

之所以仍然存在weex模式,一是为了向下兼容,之前已经使用nvue的weex模式开发的app,不会因为HBuilderX的升级而导致页面错乱;二是为了方便weex的老用户迁移。

对于普通开发者,正常来讲应该选择uni-app编译模式。

注意nvue的uni-app编译模式,仍然是要求写nvue文件。

配置方式--uni-app编译模式或weex编译模式

manifest.json 的源码视图里配置是切换模式, manifest.json -> app-plus -> nvueCompiler 切换编译模式。

nvueCompiler 有两个值:

  • weex
  • uni-app
// manifest.json      
{      
    // ...      
     /* App平台特有配置 */      
    "app-plus": {      
        "nvueCompiler":"uni-app" //是否启用 uni-app 模式    
    }      
}     

差异说明

组件差异

在老的 weex 模式中,我们使用的是 weex组件 遵循的是 weex规范,如果使用 nvue 页面将不能跨端开发,仅能在 App 端运行。如果跨端那么意味着要实现vue 页面和 .nvue 页面两套代码。

代码示例

<template>  
    <div>  
        <text>测试页面</text>  
    </div>  
</template>  

而在 uni-app 模式中,我们将可以在 weex 组件的基础上使用 uni-app 的基础组件,目前已支持部分组件,并支持 .nvue 页面编译到 H5 和小程序端。

代码示例

<template>  
    <view>  
        <text>测试页面</text>  
    </view>  
</template>  

nvue的uni-app编译模式组件使用注意

组件的使用注意事项: 组件 注意事项
text 文字尽量写在text节点,非text节点的文字无法自动更新
rich-text nodes 属性只支持节点列表不支持 HTML String
web-view 必须指定高度,不支持页面通讯和网页内使用Plus API 。但在nvue里可以使用plus.webview.create来创建webview。这样的webview能力上更强大,但注意和原页面会有层级问题

默认页面滚动差异

weex 模式中,我们需要页面滚动,必须使用 <list> 组件或者 <scroller> 组件,这与我们开发小程序或者 web 的习惯并不符合。而在 uni-app 模式中,则可以像 vue 页面一样方便开发,不需要去声明额外的组件进行滚动,只要页面内容高度高于屏幕,就会自动滚动。实际上,在新模式里自动给每个nvue页面的根下套了一个scroller。

单位差异

weex的px是动态单位,并且不支持rpx。这与uni-app的设计不符。
在新模式中,rpx和px分别是动态单位和静态单位,与vue的设计一样。

Tips

注意事项

API 注意事项

.nvue 支持大部分 uni-app API详情

css 注意事项

.nvue 中,有些 css 样式需要注意,与 web 开发中样式写法会有区别。

1、只有text标签可以设置字体大小,字体颜色
2、布局不能使用百分比
3、只能使用 class 选择器


/* 错误 */  
#id {}  
.a .b .c {}  
.a > .b {}  

/* 正确 */  
.class {}  

4、border 不支持简写


/* 错误 */  
.class {  
    border: 1px red solid;  
}  

/* 正确 */  
.class {  
    border-width: 1px;  
    border-style: solid;  
    border-color: red;  
}  

5、background 不支持简写

/* 错误 */  
.class {  
    background: red;  
}  

/* 正确 */  
.class {  
    background-color: red;  
}

6、.nvue 页面的布局排列方向默认为竖排(column),如需改变布局方向,可以在 manifest.json -> app-plus -> nvue -> flex-direction 节点下修改,仅在 uni-app 模式下生效。 详情
7、nvue的uni-app编译模式下,App.vue 中的样式,会编译到每个 nvue文件。非uni-app编译模式不会。对于共享样式,如果有不合法属性控制台会给出警告,可以通过条件编译屏蔽 App 中的警告。

/* 错误 */  
/*  控制台警告:WARNING: `border` is not a standard property name (may not be supported)  */  
.class {  
    border: 1px red solid;  
}  

/* 正确 */  
.class {  
    border-width: 1px;  
    border-style: solid;  
    border-color: red;  
}  

默认逻辑

manifest.json 配置文件中,未明确指定编译模式(即未配置app-plus -> nvueCompiler),在HBuilderX2.4以前,默认值为 weex 模式,2.4起默认值改为 uni-app 模式。

nvue编译为H5、小程序时注意

nvue页面编译为H5、小程序时,会做一件css默认值对齐的工作。
因为weex布局只支持flex,并且默认flex方向是垂直。而H5和小程序端,使用web渲染,web默认不是flex,并且设置display:flex后,它的flex方向默认是水平的。
所以nvue编译为H5、小程序时,会自动把页面默认布局设为flex、方向为垂直。当然开发者手动设置后会覆盖默认设置。

收起阅读 »

基于HBuilder iOS离线打包 oc和js互调

离线打包 HBuilder h5+

本篇文章基于HBuilder iOS离线打包widget方式 oc和js 互调 ps:如果不是离线打包方式代码仅供参考

原理:js调用oc用的是H5+封装好的api,oc调用js 并不是真正的调用js方法,而是注册自定义监听事件,通过监听的方式获取oc传到js里的参数,从而达到oc调用js

js调用原生oc方法

  • js调用oc类方法

    //LoginViewController是oc类 txt是要传的参数  
    plus.ios.importClass("LoginViewController").login("txt“);
  • js调用oc对象方法

    //objectToJsonImage是oc对象方法  massageArray返回值  
    var Massage = plus.ios.importClass("LoginViewController");  
    var massage = new Massage();  
    var massageArray = massage.objectToJsonImage();
  • js调用oc方法可以后的oc的返回值

oc 调用js

  • oc调用js 比较复杂 看代码吧

    (NSMutableArray*)searchViews:(NSArray*)views{  
    
    NSMutableArray *frames = [NSMutableArray array];  
    //遍历view  
    for (UIView *temp in views) {  
    
        if ([temp isMemberOfClass:[PDRCoreAppFrame class]]) {  
    
            [frames addObject:temp];  
        }  
        if ([temp subviews]) {  
    
            NSMutableArray *tempArray = [self searchViews:[temp subviews]];  
    
            for (UIView *tempView in tempArray) {  
    
                if ([tempView isMemberOfClass:[PDRCoreAppFrame class]]) {  
    
                    [frames addObject:tempView];  
                }  
            }  
        }  
    }  
    //返回值 frames 为从该层级中找到的 PDRCoreAppFrame  
    return frames;  
    }  
    (void)evaluatingJavaScriptFromString:(NSString*)string{  
    
    UIWindow *window = [[UIApplication sharedApplication] keyWindow];  
    
    NSArray *views = [[[window rootViewController] view] subviews];  
    
    NSArray *frames = [self searchViews:views];  
    
    for (PDRCoreAppFrame *appFrame in frames) {  
        /*这里需要注意执行异步任务,在block内需要回到主线程来进行JS event的调用,但是如果还是使用  
         dispath_get_main_queue的话会造成调用JS有alert的话线程会死锁,具体原因也不是特别清晰,  
         在stackOverFlow中看到应该是JS和OC不同alert线程的原因  
         */  
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{  
            [appFrame performSelectorOnMainThread:@selector(stringByEvaluatingJavaScriptFromString:) withObject:string waitUntilDone:NO];  
    
        });  
    }  
    }  
    (void)fireEvent:(NSString*)event args:(NSString *)args{  
    NSString *evalStr = nil;  
    
    if (args) {  
        //创建js事件  
        evalStr = [NSString stringWithFormat:@"\  
                   var pathEvent = document.createEvent('HTMLEvents');\  
                   pathEvent.initEvent('%@', true, true);\  
                   pathEvent.eventType = 'message';\  
                   pathEvent.arguments = '%@';\  
                   document.dispatchEvent(pathEvent);",event,args];  
    }else{  
        evalStr = [NSString stringWithFormat:@"\  
                   var pathEvent = document.createEvent('HTMLEvents');\  
                   pathEvent.initEvent('%@', true, true);\  
                   pathEvent.eventType = 'message';\  
                   document.dispatchEvent(pathEvent);",event];  
    }  
    //return evalStr;  
    //调用上述方法  
    [self evaluatingJavaScriptFromString:evalStr];  
    }  
    //通过此代码调用  
    [self fireEvent:@"event_name" args:@"json"];  
    //js端代码  
    document.addEventListener('event_name', function(e) {  
        alert(e.arguments);  
    }, false);
继续阅读 »

本篇文章基于HBuilder iOS离线打包widget方式 oc和js 互调 ps:如果不是离线打包方式代码仅供参考

原理:js调用oc用的是H5+封装好的api,oc调用js 并不是真正的调用js方法,而是注册自定义监听事件,通过监听的方式获取oc传到js里的参数,从而达到oc调用js

js调用原生oc方法

  • js调用oc类方法

    //LoginViewController是oc类 txt是要传的参数  
    plus.ios.importClass("LoginViewController").login("txt“);
  • js调用oc对象方法

    //objectToJsonImage是oc对象方法  massageArray返回值  
    var Massage = plus.ios.importClass("LoginViewController");  
    var massage = new Massage();  
    var massageArray = massage.objectToJsonImage();
  • js调用oc方法可以后的oc的返回值

oc 调用js

  • oc调用js 比较复杂 看代码吧

    (NSMutableArray*)searchViews:(NSArray*)views{  
    
    NSMutableArray *frames = [NSMutableArray array];  
    //遍历view  
    for (UIView *temp in views) {  
    
        if ([temp isMemberOfClass:[PDRCoreAppFrame class]]) {  
    
            [frames addObject:temp];  
        }  
        if ([temp subviews]) {  
    
            NSMutableArray *tempArray = [self searchViews:[temp subviews]];  
    
            for (UIView *tempView in tempArray) {  
    
                if ([tempView isMemberOfClass:[PDRCoreAppFrame class]]) {  
    
                    [frames addObject:tempView];  
                }  
            }  
        }  
    }  
    //返回值 frames 为从该层级中找到的 PDRCoreAppFrame  
    return frames;  
    }  
    (void)evaluatingJavaScriptFromString:(NSString*)string{  
    
    UIWindow *window = [[UIApplication sharedApplication] keyWindow];  
    
    NSArray *views = [[[window rootViewController] view] subviews];  
    
    NSArray *frames = [self searchViews:views];  
    
    for (PDRCoreAppFrame *appFrame in frames) {  
        /*这里需要注意执行异步任务,在block内需要回到主线程来进行JS event的调用,但是如果还是使用  
         dispath_get_main_queue的话会造成调用JS有alert的话线程会死锁,具体原因也不是特别清晰,  
         在stackOverFlow中看到应该是JS和OC不同alert线程的原因  
         */  
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{  
            [appFrame performSelectorOnMainThread:@selector(stringByEvaluatingJavaScriptFromString:) withObject:string waitUntilDone:NO];  
    
        });  
    }  
    }  
    (void)fireEvent:(NSString*)event args:(NSString *)args{  
    NSString *evalStr = nil;  
    
    if (args) {  
        //创建js事件  
        evalStr = [NSString stringWithFormat:@"\  
                   var pathEvent = document.createEvent('HTMLEvents');\  
                   pathEvent.initEvent('%@', true, true);\  
                   pathEvent.eventType = 'message';\  
                   pathEvent.arguments = '%@';\  
                   document.dispatchEvent(pathEvent);",event,args];  
    }else{  
        evalStr = [NSString stringWithFormat:@"\  
                   var pathEvent = document.createEvent('HTMLEvents');\  
                   pathEvent.initEvent('%@', true, true);\  
                   pathEvent.eventType = 'message';\  
                   document.dispatchEvent(pathEvent);",event];  
    }  
    //return evalStr;  
    //调用上述方法  
    [self evaluatingJavaScriptFromString:evalStr];  
    }  
    //通过此代码调用  
    [self fireEvent:@"event_name" args:@"json"];  
    //js端代码  
    document.addEventListener('event_name', function(e) {  
        alert(e.arguments);  
    }, false);
收起阅读 »

HBuilderX editorconfig使用说明

editorconfig editconfig

HBuilderX 2.0.3+起支持

editorconfig是什么?

很多公司都要求各开发成员使用相同的编码风格,比如缩进是空格还是tab。

editorconfig是一套解决这个问题的业内通用规范,通过在项目下存放配置文件.editorconfig,并在这个配置文件中描述规则,然后把这个配置文件和其他代码一起提交git/svn,所有项目成员,都会遵循相同的编码规范。

HBuilderX直接支持该规范,无需下载插件,开箱即用。sublime、vscode支持该规范的话需要先下载插件。

editorconfig的官网是https://editorconfig.org/
editorconfig可以帮助开发者在不同的编辑器和IDE之间定义和维护一致的代码风格。
editorconfig包含一个用于定义代码格式的文件和一批编辑器插件,这些插件可以让编辑器读取配置文件并依此格式化代码。
editorconfig的配置文件十分易读,并且可以在各个操作系统、编辑器下工作。

editorconfig的配置文件是怎样的?

以下是一个用于设置Python和JavaScript行尾和缩进风格的配置文件。

# EditorConfig is awesome: http://EditorConfig.org  

# top-most EditorConfig file  
root = true  

# Unix-style newlines with a newline ending every file  
[*]  
end_of_line = lf  
insert_final_newline = true  

# 4 space indentation  
[*.py]  
indent_style = space  
indent_size = 4  

# Tab indentation (no size specified)  
[*.js]  
indent_style = tab  

# Indentation override for all JS under lib directory  
[lib/**.js]  
indent_style = space  
indent_size = 2  

# Matches the exact files either package.json or .travis.yml  
[{package.json,.travis.yml}]  
indent_style = space  
indent_size = 2

案例

很多开源项目都用到了editorconfig

比如jQuery, jQueryGithub上的.editorconfig配置文件如下:

root = true  

[*]  
indent_style = tab  
end_of_line = lf  
charset = utf-8  
trim_trailing_whitespace = true  
insert_final_newline = true  

[package.json]  
indent_style = space  
indent_size = 2

如上,可以看到,JQuery配置了:编码格式、缩进风格等

在哪里存放配置文件

当打开一个文件时,editorconfig插件会在打开文件的目录和其每一级父目录查找.editorconfig文件,直到有一个配置文件root=true

如果一个工程中出现多个配置文件,EditorConfig配置文件的读取层级是自上而下的,最深层的配置文件,最后读取。配置规则也是 按照读取的顺序来生效,所以路径上离代码最近的配置规则,优先级最高。

相对于其他开发工具(如vscode),HBuilderX对editorconfig更完善。在其他工具中,项目外层如果有editorconfig文件,也会影响这个项目,经常让人莫名其妙。HBuilderX没有这个bug。

文件格式详情

editorconfig文件使用INI格式(译注:请参考维基百科),目的是可以与Python ConfigParser Library兼容,但是允许在分段名(译注:原文是section names)中使用“and”。
分段名是全局的文件路径,格式类似于gitignore。斜杠/作为路径分隔符,#或者;作为注释。注释应该单独占一行。editorconfig文件使用UTF-8格式、CRLFLF作为换行符。

通配符

通配符 说明
* 匹配除/之外的任意字符串
** 匹配任意字符串
匹配任意单个字符
[name] 匹配name字符
[!name] 匹配非name字符
{s1,s3,s3} 匹配任意给定的字符串(0.11.0起支持)

特殊字符可以用\转义,以使其不被认为是通配符。

支持的属性

属性说明 说明
indent_style tab为hard-tabs,space为soft-tabs
indent_size 设置整数表示规定每级缩进的列数和soft-tabs的宽度(译注:空格数)。如果设定为tab,则会使用tab_width的值(如果已指定)
tab_width 设置整数用于指定替代tab的列数。默认值就是indent_size的值,一般无需指定。
end_of_line 定义换行符,支持lf、cr和crlf。
trim_trailing_whitespace 设为true表示会除去换行行首的任意空白字符,false反之
insert_final_newline 设为true表明使文件以一个空白行结尾,false反之
root 表明是最顶层的配置文件,发现设为true时,才会停止查找.editorconfig文件。

注意

  1. 在HBuilderX内, 所有的属性名和属性值对大小写敏感。通常,如果没有明确指定某个属性,则会使用编辑器的配置,而editorconfig不会处理。
  2. 推荐不要指定某些editorconfig属性。比如,tab_width不需要特别指定,除非它与indent_size不同。同样的,当indent_style设为tab时,不需要配置indent_size,这样才方便阅读者使用他们习惯的缩进格式。另外,如果某些属性并没有规范化(比如end_of_line),就最好不要设置它。
  3. 如果你不需要editorconfig的功能,可以在工具-设置中关闭这个功能。

HBuilderX 启用或关闭editorconfig配置

在【设置】中,有个editorconfig开关,您可以自由选择开启与关闭.editorconfig

继续阅读 »

HBuilderX 2.0.3+起支持

editorconfig是什么?

很多公司都要求各开发成员使用相同的编码风格,比如缩进是空格还是tab。

editorconfig是一套解决这个问题的业内通用规范,通过在项目下存放配置文件.editorconfig,并在这个配置文件中描述规则,然后把这个配置文件和其他代码一起提交git/svn,所有项目成员,都会遵循相同的编码规范。

HBuilderX直接支持该规范,无需下载插件,开箱即用。sublime、vscode支持该规范的话需要先下载插件。

editorconfig的官网是https://editorconfig.org/
editorconfig可以帮助开发者在不同的编辑器和IDE之间定义和维护一致的代码风格。
editorconfig包含一个用于定义代码格式的文件和一批编辑器插件,这些插件可以让编辑器读取配置文件并依此格式化代码。
editorconfig的配置文件十分易读,并且可以在各个操作系统、编辑器下工作。

editorconfig的配置文件是怎样的?

以下是一个用于设置Python和JavaScript行尾和缩进风格的配置文件。

# EditorConfig is awesome: http://EditorConfig.org  

# top-most EditorConfig file  
root = true  

# Unix-style newlines with a newline ending every file  
[*]  
end_of_line = lf  
insert_final_newline = true  

# 4 space indentation  
[*.py]  
indent_style = space  
indent_size = 4  

# Tab indentation (no size specified)  
[*.js]  
indent_style = tab  

# Indentation override for all JS under lib directory  
[lib/**.js]  
indent_style = space  
indent_size = 2  

# Matches the exact files either package.json or .travis.yml  
[{package.json,.travis.yml}]  
indent_style = space  
indent_size = 2

案例

很多开源项目都用到了editorconfig

比如jQuery, jQueryGithub上的.editorconfig配置文件如下:

root = true  

[*]  
indent_style = tab  
end_of_line = lf  
charset = utf-8  
trim_trailing_whitespace = true  
insert_final_newline = true  

[package.json]  
indent_style = space  
indent_size = 2

如上,可以看到,JQuery配置了:编码格式、缩进风格等

在哪里存放配置文件

当打开一个文件时,editorconfig插件会在打开文件的目录和其每一级父目录查找.editorconfig文件,直到有一个配置文件root=true

如果一个工程中出现多个配置文件,EditorConfig配置文件的读取层级是自上而下的,最深层的配置文件,最后读取。配置规则也是 按照读取的顺序来生效,所以路径上离代码最近的配置规则,优先级最高。

相对于其他开发工具(如vscode),HBuilderX对editorconfig更完善。在其他工具中,项目外层如果有editorconfig文件,也会影响这个项目,经常让人莫名其妙。HBuilderX没有这个bug。

文件格式详情

editorconfig文件使用INI格式(译注:请参考维基百科),目的是可以与Python ConfigParser Library兼容,但是允许在分段名(译注:原文是section names)中使用“and”。
分段名是全局的文件路径,格式类似于gitignore。斜杠/作为路径分隔符,#或者;作为注释。注释应该单独占一行。editorconfig文件使用UTF-8格式、CRLFLF作为换行符。

通配符

通配符 说明
* 匹配除/之外的任意字符串
** 匹配任意字符串
匹配任意单个字符
[name] 匹配name字符
[!name] 匹配非name字符
{s1,s3,s3} 匹配任意给定的字符串(0.11.0起支持)

特殊字符可以用\转义,以使其不被认为是通配符。

支持的属性

属性说明 说明
indent_style tab为hard-tabs,space为soft-tabs
indent_size 设置整数表示规定每级缩进的列数和soft-tabs的宽度(译注:空格数)。如果设定为tab,则会使用tab_width的值(如果已指定)
tab_width 设置整数用于指定替代tab的列数。默认值就是indent_size的值,一般无需指定。
end_of_line 定义换行符,支持lf、cr和crlf。
trim_trailing_whitespace 设为true表示会除去换行行首的任意空白字符,false反之
insert_final_newline 设为true表明使文件以一个空白行结尾,false反之
root 表明是最顶层的配置文件,发现设为true时,才会停止查找.editorconfig文件。

注意

  1. 在HBuilderX内, 所有的属性名和属性值对大小写敏感。通常,如果没有明确指定某个属性,则会使用编辑器的配置,而editorconfig不会处理。
  2. 推荐不要指定某些editorconfig属性。比如,tab_width不需要特别指定,除非它与indent_size不同。同样的,当indent_style设为tab时,不需要配置indent_size,这样才方便阅读者使用他们习惯的缩进格式。另外,如果某些属性并没有规范化(比如end_of_line),就最好不要设置它。
  3. 如果你不需要editorconfig的功能,可以在工具-设置中关闭这个功能。

HBuilderX 启用或关闭editorconfig配置

在【设置】中,有个editorconfig开关,您可以自由选择开启与关闭.editorconfig

收起阅读 »

JavaScript语法校验

语法校验

eslint-js

如何配置选项?

选项配置文件是.eslintrc.js,选项对应说明如下:

  module.exports = {  
      "plugins": [],          //插件  
      "env": {  
          "browser": true,  
          "node": true  
      },  
      "parser": "esprima",    //指定解析器  
      "parserOptions": {},      
      "rules": {}             //规则  
  };

更多配置说明可以参考options

如何增加规则?

规则简介

官方规则列表

规则设置:

  • "off" 或 0 - 关闭规则
  • "warn" 或 1 - 开启规则,使用警告级别的错误:warn (不会导致程序退出)
  • "error" 或 2 - 开启规则,使用错误级别的错误:error (当被触发的时候,程序会退出)

HBuilderX增加js校验规则

修改.eslintrc.js文件,添加规则,比如:


  module.exports = {  
      "plugins": [  
          "html"  
      ],  
      "parser": "esprima",  
      "parserOptions": {  
          "ecmaVersion": 2018,  
          "sourceType": "module",  
          "ecmaFeatures": {  
              "jsx": true  
          },  
          "allowImportExportEverywhere": false  
      },  
      "rules": {  
          "camelcase": 2,           //强制驼峰法命名,  
          "indent": [2, 4],         //缩进风格  
          "id-match": 0,            //命名检测  
          "init-declarations": 1,   //声明时必须赋初值  
          "no-undef": 1,            //不能有未定义的变量  
      }  
  };  
继续阅读 »

eslint-js

如何配置选项?

选项配置文件是.eslintrc.js,选项对应说明如下:

  module.exports = {  
      "plugins": [],          //插件  
      "env": {  
          "browser": true,  
          "node": true  
      },  
      "parser": "esprima",    //指定解析器  
      "parserOptions": {},      
      "rules": {}             //规则  
  };

更多配置说明可以参考options

如何增加规则?

规则简介

官方规则列表

规则设置:

  • "off" 或 0 - 关闭规则
  • "warn" 或 1 - 开启规则,使用警告级别的错误:warn (不会导致程序退出)
  • "error" 或 2 - 开启规则,使用错误级别的错误:error (当被触发的时候,程序会退出)

HBuilderX增加js校验规则

修改.eslintrc.js文件,添加规则,比如:


  module.exports = {  
      "plugins": [  
          "html"  
      ],  
      "parser": "esprima",  
      "parserOptions": {  
          "ecmaVersion": 2018,  
          "sourceType": "module",  
          "ecmaFeatures": {  
              "jsx": true  
          },  
          "allowImportExportEverywhere": false  
      },  
      "rules": {  
          "camelcase": 2,           //强制驼峰法命名,  
          "indent": [2, 4],         //缩进风格  
          "id-match": 0,            //命名检测  
          "init-declarations": 1,   //声明时必须赋初值  
          "no-undef": 1,            //不能有未定义的变量  
      }  
  };  
收起阅读 »

html语法校验

语法校验

html语法校验插件,需要到插件市场安装。

安装完成后,进入【设置】【插件配置】【htmlhintrc】,点击htmlhintrc, 即可配置相关规则。

如何配置选项?

选项配置文件是.htmlhintrc,目前已有的选项对应说明如下:

选项 说明
tagname-lowercase 标签名是否开启小写; true:启用, false:禁用
attr-lowercase 属性名是否开启小写,true:启用, false:禁用
attr-value-double-quotes 属性值是否必须放在双引号中,true:启用, false:禁用
doctype-first Doctype是否必须是HTML文档的第一行,true:启用, false:禁用
tag-pair 标签是否必须成对,true:启用, false:禁用
spec-char-escape 特殊字符是否必须转义,true:启用, false:禁用
id-unique ID属性是否必须唯一,true:启用, false:禁用
src-not-empty src属性是否为空,true:启用, false:禁用
attr-no-duplication: 同一标签中,属性值是否不可重复, true:启用, false:禁用

详细的配置说明可以参考options

如何增加其它选项?

修改.htmlhintrc文件,添加选项,比如:


  {  
    "attr-value-not-empty": true,     //属性值不可为空  
    "tag-self-close": true,           //标签必须自封闭  
    "title-require": true,            //title标签必须出现在 head 标签中  
    "inline-style-disabled": false,   //可以使用行内样式  
    "id-class-ad-disabled": true,     //ID和 Class一定不可使用ad关键词,使用ad关键词的ID或Class,会被广告拦截软件屏蔽  
    "attr-unsafe-chars": true,        //script标签不该使用在head标签  
  }  
继续阅读 »

html语法校验插件,需要到插件市场安装。

安装完成后,进入【设置】【插件配置】【htmlhintrc】,点击htmlhintrc, 即可配置相关规则。

如何配置选项?

选项配置文件是.htmlhintrc,目前已有的选项对应说明如下:

选项 说明
tagname-lowercase 标签名是否开启小写; true:启用, false:禁用
attr-lowercase 属性名是否开启小写,true:启用, false:禁用
attr-value-double-quotes 属性值是否必须放在双引号中,true:启用, false:禁用
doctype-first Doctype是否必须是HTML文档的第一行,true:启用, false:禁用
tag-pair 标签是否必须成对,true:启用, false:禁用
spec-char-escape 特殊字符是否必须转义,true:启用, false:禁用
id-unique ID属性是否必须唯一,true:启用, false:禁用
src-not-empty src属性是否为空,true:启用, false:禁用
attr-no-duplication: 同一标签中,属性值是否不可重复, true:启用, false:禁用

详细的配置说明可以参考options

如何增加其它选项?

修改.htmlhintrc文件,添加选项,比如:


  {  
    "attr-value-not-empty": true,     //属性值不可为空  
    "tag-self-close": true,           //标签必须自封闭  
    "title-require": true,            //title标签必须出现在 head 标签中  
    "inline-style-disabled": false,   //可以使用行内样式  
    "id-class-ad-disabled": true,     //ID和 Class一定不可使用ad关键词,使用ad关键词的ID或Class,会被广告拦截软件屏蔽  
    "attr-unsafe-chars": true,        //script标签不该使用在head标签  
  }  
收起阅读 »

stylelint插件:css、less、scss语法校验说明

语法校验 css语法校验

HBuilderX中,校验css、less、scss的语法校验插件是stylelint

如何配置选项?

配置文件是.stylelintrc.js

详细的配置说明可以参考

规则配置格式

stylelint有上百条规则,可以分为三类:

  • 用于校对风格的规则 (主要针对空格(比如说冒号附近的空格)、换行、缩进等等)
  • 用于判别代码可维护性的规则 (判断在CSS选择器中是否有使用某个ID,或者在某条声明当中是否应用了!important关键词)
  • 用于判断代码错误的规则 (检测错误的HEX颜色写法或者某条简写属性是否会覆盖其他的声明语句)

    规则属性是一个对象,键是规则的名称,值是规则配置。每个规则配置符合下列格式之一:

  • 单个值(primary option)
  • 一个有两个值的数组([primary option,secondary option])
  • null (关闭规则)

如何增加其它规则?

修改.stylelintrc.js文件,添加选项,比如:


  module.exports = {  
    "extends": "stylelint-config-recommended",  
    "rules":{  
        "unit-no-unknown": false,  
        "indentation": "tab",       //缩进  
        "unit-no-unknown": true,    //禁止未知单位  
        "color-hex-case": [  
          "lower", {  
          "message": "Lowercase letters are easier to distinguish from numbers"  
          }  
        ],  
        "max-empty-lines": 2,  
        "unit-whitelist": ["em", "rem", "%", "s", "px", "upx"],  
        "number-leading-zero": null  
    }  
  }  

详尽的配置规则

  {  
  "rules": {  
    "at-rule-blacklist": string|[],  
    "at-rule-empty-line-before": "always"|"never",  
    "at-rule-name-case": "lower"|"upper",  
    "at-rule-name-newline-after": "always"|"always-multi-line",  
    "at-rule-name-space-after": "always"|"always-single-line",  
    "at-rule-no-unknown": true,  
    "at-rule-no-vendor-prefix": true,  
    "at-rule-semicolon-newline-after": "always",  
    "at-rule-semicolon-space-before": "always"|"never",  
    "at-rule-whitelist": string|[],  
    "block-closing-brace-empty-line-before": "always-multi-line"|"never",  
    "block-closing-brace-newline-after": "always"|"always-single-line"|"never-single-line"|"always-multi-line"|"never-multi-line",  
    "block-closing-brace-newline-before": "always"|"always-multi-line"|"never-multi-line",  
    "block-closing-brace-space-after": "always"|"always-single-line"|"never-single-line"|"always-multi-line"|"never-multi-line",  
    "block-closing-brace-space-before": "always"|"never"|"always-single-line"|"never-single-line"|"always-multi-line"|"never-multi-line",  
    "block-no-empty": true,  
    "block-opening-brace-newline-after": "always"|"always-multi-line"|"never-multi-line",  
    "block-opening-brace-newline-before": "always"|"always-single-line"|"never-single-line"|"always-multi-line"|"never-multi-line",  
    "block-opening-brace-space-after": "always"|"always-single-line"|"never-single-line"|"always-multi-line"|"never-multi-line",  
    "block-opening-brace-space-before": "always"|"always-single-line"|"never-single-line"|"always-multi-line"|"never-multi-line",  
    "color-hex-case": "lower"|"upper",  
    "color-hex-length": "short"|"long",  
    "color-named": "always-where-possible"|"never",  
    "color-no-hex": true,  
    "color-no-invalid-hex": true,  
    "comment-empty-line-before": "always"|"never",  
    "comment-no-empty": true,  
    "comment-whitespace-inside": "always"|"never",  
    "comment-word-blacklist": string|[],  
    "custom-media-pattern": string,  
    "custom-property-empty-line-before": "always"|"never",  
    "custom-property-pattern": string,  
    "declaration-bang-space-after": "always"|"never",  
    "declaration-bang-space-before": "always"|"never",  
    "declaration-block-no-duplicate-properties": true,  
    "declaration-block-no-redundant-longhand-properties": true,  
    "declaration-block-no-shorthand-property-overrides": true,  
    "declaration-block-semicolon-newline-after": "always"|"always-multi-line"|"never-multi-line",  
    "declaration-block-semicolon-newline-before": "always"|"always-multi-line"|"never-multi-line",  
    "declaration-block-semicolon-space-after": "always"|"never"|"always-single-line"|"never-single-line",  
    "declaration-block-semicolon-space-before": "always"|"never"|"always-single-line"|"never-single-line",  
    "declaration-block-single-line-max-declarations": int,  
    "declaration-block-trailing-semicolon": "always"|"never",  
    "declaration-colon-newline-after": "always"|"always-multi-line",  
    "declaration-colon-space-after": "always"|"never"|"always-single-line",  
    "declaration-colon-space-before": "always"|"never",  
    "declaration-empty-line-before": "always"|"never",  
    "declaration-no-important": true,  
    "declaration-property-unit-blacklist": {},  
    "declaration-property-unit-whitelist": {},  
    "declaration-property-value-blacklist": {},  
    "declaration-property-value-whitelist": {},  
    "font-family-name-quotes": "always-where-required"|"always-where-recommended"|"always-unless-keyword",  
    "font-family-no-duplicate-names": true,  
    "font-family-no-missing-generic-family-keyword": true,  
    "font-weight-notation": "numeric"|"named",  
    "function-blacklist": string|[],  
    "function-calc-no-unspaced-operator": true,  
    "function-comma-newline-after": "always"|"always-multi-line"|"never-multi-line",  
    "function-comma-newline-before": "always"|"always-multi-line"|"never-multi-line",  
    "function-comma-space-after": "always"|"never"|"always-single-line"|"never-single-line",  
    "function-comma-space-before": "always"|"never"|"always-single-line"|"never-single-line",  
    "function-linear-gradient-no-nonstandard-direction": true,  
    "function-max-empty-lines": int,  
    "function-name-case": "lower"|"upper",  
    "function-parentheses-newline-inside": "always"|"always-multi-line"|"never-multi-line",  
    "function-parentheses-space-inside": "always"|"never"|"always-single-line"|"never-single-line",  
    "function-url-no-scheme-relative": true,  
    "function-url-quotes": "always"|"never",  
    "function-url-scheme-blacklist": string|[],  
    "function-url-scheme-whitelist": string|[],  
    "function-whitelist": string|[],  
    "function-whitespace-after": "always"|"never",  
    "indentation": int|"tab",  
    "keyframe-declaration-no-important": true,  
    "keyframes-name-pattern": string,  
    "length-zero-no-unit": true,  
    "linebreaks": "unix"|"windows",  
    "max-empty-lines": int,  
    "max-line-length": int,  
    "max-nesting-depth": int,  
    "media-feature-colon-space-after": "always"|"never",  
    "media-feature-colon-space-before": "always"|"never",  
    "media-feature-name-blacklist": string|[],  
    "media-feature-name-case": "lower"|"upper",  
    "media-feature-name-no-unknown": true,  
    "media-feature-name-no-vendor-prefix": true,  
    "media-feature-name-value-whitelist": {},  
    "media-feature-name-whitelist": string|[],  
    "media-feature-parentheses-space-inside": "always"|"never",  
    "media-feature-range-operator-space-after": "always"|"never",  
    "media-feature-range-operator-space-before": "always"|"never",  
    "media-query-list-comma-newline-after": "always"|"always-multi-line"|"never-multi-line",  
    "media-query-list-comma-newline-before": "always"|"always-multi-line"|"never-multi-line",  
    "media-query-list-comma-space-after": "always"|"never"|"always-single-line"|"never-single-line",  
    "media-query-list-comma-space-before": "always"|"never"|"always-single-line"|"never-single-line",  
    "no-descending-specificity": true,  
    "no-duplicate-at-import-rules": true,  
    "no-duplicate-selectors": true,  
    "no-empty-source": true,  
    "no-empty-first-line": true,  
    "no-eol-whitespace": true,  
    "no-extra-semicolons": true,  
    "no-invalid-double-slash-comments": true,  
    "no-missing-end-of-source-newline": true,  
    "no-unknown-animations": true,  
    "number-leading-zero": "always"|"never",  
    "number-max-precision": int,  
    "number-no-trailing-zeros": true,  
    "property-blacklist": string|[],  
    "property-case": "lower"|"upper",  
    "property-no-unknown": true,  
    "property-no-vendor-prefix": true,  
    "property-whitelist": string|[],  
    "rule-empty-line-before": "always"|"never"|"always-multi-line"|"never-multi-line",  
    "selector-attribute-brackets-space-inside": "always"|"never",  
    "selector-attribute-operator-blacklist": string|[],  
    "selector-attribute-operator-space-after": "always"|"never",  
    "selector-attribute-operator-space-before": "always"|"never",  
    "selector-attribute-operator-whitelist": string|[],  
    "selector-attribute-quotes": "always"|"never",  
    "selector-class-pattern": string,  
    "selector-combinator-blacklist": string|[],  
    "selector-combinator-space-after": "always"|"never",  
    "selector-combinator-space-before": "always"|"never",  
    "selector-combinator-whitelist": string|[],  
    "selector-descendant-combinator-no-non-space": true,  
    "selector-id-pattern": string,  
    "selector-list-comma-newline-after": "always"|"always-multi-line"|"never-multi-line",  
    "selector-list-comma-newline-before": "always"|"always-multi-line"|"never-multi-line",  
    "selector-list-comma-space-after": "always"|"never"|"always-single-line"|"never-single-line",  
    "selector-list-comma-space-before": "always"|"never"|"always-single-line"|"never-single-line",  
    "selector-max-attribute": int,  
    "selector-max-class": int,  
    "selector-max-combinators": int,  
    "selector-max-compound-selectors": int,  
    "selector-max-empty-lines": int,  
    "selector-max-id": int,  
    "selector-max-pseudo-class": int,  
    "selector-max-specificity": string,  
    "selector-max-type": int,  
    "selector-max-universal": int,  
    "selector-nested-pattern": string,  
    "selector-no-qualifying-type": true,  
    "selector-no-vendor-prefix": true,  
    "selector-pseudo-class-blacklist": string|[],  
    "selector-pseudo-class-case": "lower"|"upper",  
    "selector-pseudo-class-no-unknown": true,  
    "selector-pseudo-class-parentheses-space-inside": "always"|"never",  
    "selector-pseudo-class-whitelist": string|[],  
    "selector-pseudo-element-blacklist": string|[],  
    "selector-pseudo-element-case": "lower"|"upper",  
    "selector-pseudo-element-colon-notation": "single"|"double",  
    "selector-pseudo-element-no-unknown": true,  
    "selector-pseudo-element-whitelist": string|[],  
    "selector-type-case": "lower"|"upper",  
    "selector-type-no-unknown": true,  
    "shorthand-property-no-redundant-values": true,  
    "string-no-newline": true,  
    "string-quotes": "single"|"double",  
    "time-min-milliseconds": int,  
    "unit-blacklist": string|[],  
    "unit-case": "lower"|"upper",  
    "unit-no-unknown": true,  
    "unit-whitelist": string|[],  
    "value-keyword-case": "lower"|"upper",  
    "value-list-comma-newline-after": "always"|"always-multi-line"|"never-multi-line",  
    "value-list-comma-newline-before": "always"|"always-multi-line"|"never-multi-line",  
    "value-list-comma-space-after": "always"|"never"|"always-single-line"|"never-single-line",  
    "value-list-comma-space-before": "always"|"never"|"always-single-line"|"never-single-line",  
    "value-list-max-empty-lines": int,  
    "value-no-vendor-prefix": true  
    }  
  }

规则参考列表(中文)

2018-10-16 翻译官网

Possible errors

Color 颜色

  • color-no-invalid-hex: 禁止无效的十六进制颜色

Font family 字体系列

  • font-family-no-duplicate-names: Disallow duplicate font family names.
  • font-family-no-missing-generic-family-keyword: Disallow missing generic families in lists of font family names.

Function 函数

  • function-calc-no-unspaced-operator: 禁止在 calc 函数内的运算符间省略空格
  • function-linear-gradient-no-nonstandard-direction: 禁止在 linear-gradient() 内使用不符合标准语法的值

String 字符串

  • string-no-newline: 不允许字符串(非转义)换行

Unit

  • unit-no-unknown: 不允许未知的单位

Property 属性

  • property-no-unknown: 不允许未知属性

Keyframe declaration

  • keyframe-declaration-no-important: 不允许!important在关键帧声明

Declaration block 声明块

  • declaration-block-no-duplicate-properties: 禁止在声明块内出现重复属性
  • declaration-block-no-shorthand-property-overrides: 禁止使用速记属性重写相关属性

Block

  • block-no-empty: 不允许空块

Selector

  • selector-pseudo-class-no-unknown: 不允许未知的伪类选择器
  • selector-pseudo-element-no-unknown: 不允许未知的伪元素选择器
  • selector-type-no-unknown: 不允许未知类型选择器

Media feature

  • media-feature-name-no-unknown: 不允许未知的媒体功能的名字

At-rule

  • at-rule-no-unknown: 不允许at-rules不明

Comment

  • comment-no-empty: 不允许空注释

General / Sheet

  • no-descending-specificity:不允许选择器之后覆盖选择器的低特异性更高的特异性
  • no-duplicate-at-import-rules: Disallow duplicate @import rules within a stylesheet.
  • no-duplicate-selectors: 不允许重复的选择器
  • no-empty-source: 不允许空的来源
  • no-extra-semicolons: 不允许额外的分号
  • no-invalid-double-slash-comments: 不允许双斜杠注释(/ /…)不支持的CSS

Limit language features

color 颜色

  • color-named: 在特定的情况下不允许使用命名的颜色值
  • color-no-hex: 禁止使用十六进制的颜色

Function 函数

  • function-blacklist: 指定一个不允许使用函数的黑名单
  • function-url-no-scheme-relative: 不允许文档相对的URL
  • function-url-scheme-blacklist: 指定允许URL方案的黑名单
  • function-url-scheme-whitelist: 指定允许URL方案的白名单
  • function-whitelist: 指定允许的功能的白名单

Keyframes

  • keyframes-name-pattern: Specify a pattern for keyframe names.

Number 数值

  • number-max-precision: 限制数值的小数位数

Time

  • time-min-milliseconds: Specify the minimum number of milliseconds for time values.

Unit

  • unit-blacklist: 指定不允许使用单位的黑名单
  • unit-whitelist: 指定允许单位的白名单

Shorthand property

  • shorthand-property-no-redundant-values: 不允许在简写属性冗余值

Value 值

  • value-no-vendor-prefix: 禁止值添加供应商前缀值

Custom property 自定义属性

  • custom-property-pattern: 指定自定义属性的模式

Property 属性

  • property-blacklist: 指定一个不允许使用属性的黑名单
  • property-no-vendor-prefix: 禁止属性添加供应商前缀
  • property-whitelist: 指定一个允许使用属性的白名单

Declaration 声明

  • declaration-block-no-redundant-longhand-properties: 不允许手写属性,可以组合成一个简写属性
  • declaration-no-important: 不允许!important声明
  • declaration-property-unit-blacklist: 指定一个黑名单内不允许声明属性
  • declaration-property-unit-whitelist: 指定一个白名单内允许声明属性
  • declaration-property-value-blacklist:指定一个黑名单,不允许在声明属性和值对
  • declaration-property-value-whitelist: 指定一个允许属性和值对声明的白名单

Declaration block 声明块

  • declaration-block-single-line-max-declarations: 在单行声明块中限制声明的数量

Selector 选择器

  • selector-attribute-operator-blacklist: 指定一个黑名单不允许属性的操作符
  • selector-attribute-operator-whitelist: 指定一个属性允许运营商的白名单
  • selector-class-pattern: 指定类选择器的模式(模式指的是正则表达式)
  • selector-combinator-blacklist: Specify a blacklist of disallowed combinators.
  • selector-combinator-whitelist: Specify a whitelist of allowed combinators.
  • selector-id-pattern: 指定id选择器的模式
  • selector-max-attribute: Limit the number of attribute selectors in a selector.
  • selector-max-class: Limit the number of classes in a selector.
  • selector-max-combinators: Limit the number of combinators in a selector.
  • selector-max-compound-selectors: 在一个选择器里面限制复合选择器的数量
  • selector-max-empty-lines: 限制内相邻的空行选择器的数量
  • selector-max-id: Limit the number of ID selectors in a selector.
  • selector-max-pseudo-class: Limit the number of pseudo-classes in a selector.
  • selector-max-specificity: 限制选择器的特异性
  • selector-max-type: Limit the number of type in a selector.
  • selector-max-universal: Limit the number of universal selectors in a selector.
  • selector-nested-pattern: 指定一个模式选择器的规则嵌套规则
  • selector-no-qualifying-type: 不允许符合条件的选择器的类型
  • selector-no-vendor-prefix: 不允许选择器的前缀
  • selector-pseudo-class-blacklist: 指定一个黑名单禁止伪类选择器
  • selector-pseudo-class-whitelist: 指定一个白名单禁止伪类选择器
  • selector-pseudo-element-blacklist: Specify a blacklist of disallowed pseudo-element selectors.
  • selector-pseudo-element-whitelist: Specify a whitelist of allowed pseudo-element selectors.

Media feature 媒体特性

  • media-feature-name-blacklist: Specify a blacklist of disallowed media feature names.
  • media-feature-name-no-vendor-prefix: 禁止媒体特性属性名添加供应商前缀
  • media-feature-name-value-whitelist: Specify a whitelist of allowed media feature name and value pairs.
  • media-feature-name-whitelist: Specify a whitelist of allowed media feature names.

Custom media 自定义媒体

  • custom-media-pattern: 指定自定义媒体查询的名称模式

At-rule AT规则

  • at-rule-blacklist: 不允许at-rules,指定一个黑名单。
  • at-rule-no-vendor-prefix: 禁止AT规则 添加供应商前缀
  • at-rule-whitelist:指定允许at-rules的白名单

Comment 注释

  • comment-word-blacklist: 指定一个黑名单内不允许的话评论

General / Sheet

  • max-nesting-depth: 限制的深度嵌套
  • no-unknown-animations: 不允许动画名称不对应@keyframes声明

Stylistic issues

颜色

  • color-hex-case: 指定十六进制颜色的大小写
  • color-hex-length: 指定十六进制颜色的长度

Font family 字体系列

  • font-family-name-quotes: 指定字体系列不应用于单双引号内

Font weight 字体粗细

  • font-weight-notation: 要求一致的数值或命名作为 font-weight 的值

Function 函数

  • function-comma-newline-after: 在函数的逗号后指定一个换行符或禁止留有空格
  • function-comma-newline-before: 在函数的逗号前指定一个换行符或禁止留有空格
  • function-comma-space-after: 在函数的逗号后指定一个空格或禁止留有空格
  • function-comma-space-before: 在函数的逗号前指定一个空格或禁止留有空格
  • function-max-empty-lines: Limit the number of adjacent empty lines within functions (Autofixable).
  • function-name-case: Specify lowercase or uppercase for function names (Autofixable).
  • function-parentheses-newline-inside: 在函数括号内指定一个换行符或禁止留有空格
  • function-parentheses-space-inside: 在函数括号内指定一个空格或禁止留有空格
  • function-url-quotes: 为urls指定单引或双引号
  • function-whitespace-after: 在函数后指定一个空格或禁止留有空格

Number 数值

  • number-leading-zero: 要求或不允许数值小于 1 的数字前面添加 0
  • number-no-trailing-zeros: 禁止在数值内尾随 0

String 字符串

  • string-quotes: 为字符串指定单引或双引号

Length 长度

  • length-zero-no-unit: 禁止单位零长度

Unit 单位

  • unit-case: 指定大写或小写的单位

Value 值

  • value-keyword-case: 指定大写或小写关键字的值

Value list 值列表

  • value-list-comma-newline-after: 在值列表的逗号后指定一个换行符或禁止留有空格
  • value-list-comma-newline-before: 在值列表的逗号前指定一个换行符或禁止留有空格
  • value-list-comma-space-after: 在值列表的逗号后指定一个空格或禁止留有空格
  • value-list-comma-space-before: 在值列表的逗号前指定一个空格或禁止留有空格
  • value-list-max-empty-lines: 限制相邻的数量值列表内空行

Custom property 自定义属性

  • custom-property-empty-line-before: 自定义属性之前equire或不允许空行

Property 属性

  • property-case: 为属性指定小写或大写

Declaration

  • declaration-bang-space-after: bang声明之后需要一个空格或者不允许空白
  • declaration-bang-space-before: bang声明之前需要一个空格或者不允许空白
  • declaration-colon-newline-after: 冒号后的声明需要一个换行符或不允许空白
  • declaration-colon-space-after: 冒号后的声明需要一个空格或不允许空白
  • declaration-colon-space-before: 冒号之前的声明需要一个空格或不允许空白
  • declaration-empty-line-before: 要求声明前不允许空一行

Declaration block

  • declaration-block-semicolon-newline-after: 要求一个换行符或不允许空白块分号后
  • declaration-block-semicolon-newline-before: 要求一个换行符或不允许空白块分号之前的声明
  • declaration-block-semicolon-space-after: 要求一个空间或不允许空白块分号后的声明
  • declaration-block-semicolon-space-before: 要求一个空间或不允许空白块分号之前的声明
  • declaration-block-trailing-semicolon: 要求或不允许在声明块后面的分号

Block 块

  • block-closing-brace-empty-line-before: 要求或不允许关闭括号前空一行
  • block-closing-brace-newline-after: 在块的右大括号后指定一个换行符或禁止留有空格
  • block-closing-brace-newline-before: 在块的右大括号前指定一个换行符或禁止留有空格
  • block-closing-brace-space-after: 在块的右大括号后指定一个空格或禁止留有空格
  • block-closing-brace-space-before: 在块的右大括号前指定一个空格或禁止留有空格
  • block-opening-brace-newline-after: 在块的左大括号后制定一个换行符
  • block-opening-brace-newline-before: 在块的左大括号前指定一个换行符或禁止留有空格
  • block-opening-brace-space-after: 在块的左大括号后指定一个空格或禁止留有空格
  • block-opening-brace-space-before: 在块的左大括号前指定一个空格或禁止留有空格

Selector 选择器

  • selector-attribute-brackets-space-inside: 在括号里的属性选择器需要一个空格或者不允许空白
  • selector-attribute-operator-space-after: 需要一个空间或不允许空格后运营商在属性选择器
  • selector-attribute-operator-space-before: 需要一个空间或不允许空格内运营商之前属性选择器
  • selector-attribute-quotes: 需要或不允许引用属性值
  • selector-combinator-space-after: 在复合选择器之后要求或不允许留有一个空格
  • selector-combinator-space-before: 在复合选择器之前要求或不允许留有一个空格
  • selector-descendant-combinator-no-non-space: 不允许的字符的后代组合子选择器进行技术改造
  • selector-pseudo-class-case: 为伪类选择器指定小写或大写
  • selector-pseudo-class-parentheses-space-inside: 需要一个空格或不允许空格在括号里面的伪类选择器
  • selector-pseudo-element-case: 为伪元素选择器指定小写或大写
  • selector-pseudo-element-colon-notation: 为适用的伪元素指定单引号或双冒号符号
  • selector-type-case: 指定小写或大写类型选择器

Selector list 选择器列表

  • selector-list-comma-newline-after: 在选择器列表的逗号后指定一个换行符或禁止留有空格
  • selector-list-comma-newline-before: 在选择器列表的逗号前指定一个换行符或禁止留有空格
  • selector-list-comma-space-after: 在选择器列表的逗号后指定一个空格或禁止留有空格
  • selector-list-comma-space-before: 在选择器列表的逗号前指定一个空格或禁止留有空格

Rule 规则

  • rule-empty-line-before: 不允许rules前空一行

Media feature 媒体特性

  • media-feature-colon-space-after: 在媒体特性的冒号后指定一个空格或禁止留有空格
  • media-feature-colon-space-before: 在媒体特性的冒号前指定一个空格或禁止留有空格
  • media-feature-name-case: 为媒体特性名称指定小写或大写
  • media-feature-parentheses-space-inside: 需要一个空间或不允许空格在括号里面的媒体功能
  • media-feature-range-operator-space-after: 需要一个空间或不允许空白范围运算符后媒体的特性
  • media-feature-range-operator-space-before: 之前需要一个空间或不允许空格符范围在媒体功能

Media query list 媒体查询列表

  • media-query-list-comma-newline-after: 需要一个换行符或不允许空格后媒体查询的逗号分隔列表
  • media-query-list-comma-newline-before: 需要一个换行符或不允许空格之前媒体查询的逗号分隔列表
  • media-query-list-comma-space-after: 需要一个空间或不允许空格后媒体查询的逗号分隔列表
  • media-query-list-comma-space-before:需要一个空间或不允许空格之前媒体查询的逗号分隔列表

At-rule AT规则

  • at-rule-empty-line-before: 在 AT规则 前要求或不允许留有空行
  • at-rule-name-case: 指定at-rules小写或大写的名字
  • at-rule-name-newline-after: at-rule名称后需要一个换行符
  • at-rule-name-space-after: 需要一个空格后at-rule名称
  • at-rule-semicolon-newline-after: 需要一个换行符之后at-rules的分号
  • at-rule-semicolon-space-before: 需要一个空格之后at-rules的分号

Comment 注释

  • comment-empty-line-before: 要求或不允许注释前面留有一个空格
  • comment-whitespace-inside: 要求或不允许注释内留有一个空格

General / Sheet 常用样式

  • indentation: 指定缩进
  • linebreaks: Specify unix or windows linebreaks (Autofixable).
  • max-empty-lines: 限制相邻的空行数
  • max-line-length: 限制每行的长度
  • no-eol-whitespace: 禁止行尾留有空白
  • no-missing-end-of-source-newline: 不允许丢失end-of-source换行
  • no-empty-first-line: Disallow empty first lines. (Autofixable)
继续阅读 »

HBuilderX中,校验css、less、scss的语法校验插件是stylelint

如何配置选项?

配置文件是.stylelintrc.js

详细的配置说明可以参考

规则配置格式

stylelint有上百条规则,可以分为三类:

  • 用于校对风格的规则 (主要针对空格(比如说冒号附近的空格)、换行、缩进等等)
  • 用于判别代码可维护性的规则 (判断在CSS选择器中是否有使用某个ID,或者在某条声明当中是否应用了!important关键词)
  • 用于判断代码错误的规则 (检测错误的HEX颜色写法或者某条简写属性是否会覆盖其他的声明语句)

    规则属性是一个对象,键是规则的名称,值是规则配置。每个规则配置符合下列格式之一:

  • 单个值(primary option)
  • 一个有两个值的数组([primary option,secondary option])
  • null (关闭规则)

如何增加其它规则?

修改.stylelintrc.js文件,添加选项,比如:


  module.exports = {  
    "extends": "stylelint-config-recommended",  
    "rules":{  
        "unit-no-unknown": false,  
        "indentation": "tab",       //缩进  
        "unit-no-unknown": true,    //禁止未知单位  
        "color-hex-case": [  
          "lower", {  
          "message": "Lowercase letters are easier to distinguish from numbers"  
          }  
        ],  
        "max-empty-lines": 2,  
        "unit-whitelist": ["em", "rem", "%", "s", "px", "upx"],  
        "number-leading-zero": null  
    }  
  }  

详尽的配置规则

  {  
  "rules": {  
    "at-rule-blacklist": string|[],  
    "at-rule-empty-line-before": "always"|"never",  
    "at-rule-name-case": "lower"|"upper",  
    "at-rule-name-newline-after": "always"|"always-multi-line",  
    "at-rule-name-space-after": "always"|"always-single-line",  
    "at-rule-no-unknown": true,  
    "at-rule-no-vendor-prefix": true,  
    "at-rule-semicolon-newline-after": "always",  
    "at-rule-semicolon-space-before": "always"|"never",  
    "at-rule-whitelist": string|[],  
    "block-closing-brace-empty-line-before": "always-multi-line"|"never",  
    "block-closing-brace-newline-after": "always"|"always-single-line"|"never-single-line"|"always-multi-line"|"never-multi-line",  
    "block-closing-brace-newline-before": "always"|"always-multi-line"|"never-multi-line",  
    "block-closing-brace-space-after": "always"|"always-single-line"|"never-single-line"|"always-multi-line"|"never-multi-line",  
    "block-closing-brace-space-before": "always"|"never"|"always-single-line"|"never-single-line"|"always-multi-line"|"never-multi-line",  
    "block-no-empty": true,  
    "block-opening-brace-newline-after": "always"|"always-multi-line"|"never-multi-line",  
    "block-opening-brace-newline-before": "always"|"always-single-line"|"never-single-line"|"always-multi-line"|"never-multi-line",  
    "block-opening-brace-space-after": "always"|"always-single-line"|"never-single-line"|"always-multi-line"|"never-multi-line",  
    "block-opening-brace-space-before": "always"|"always-single-line"|"never-single-line"|"always-multi-line"|"never-multi-line",  
    "color-hex-case": "lower"|"upper",  
    "color-hex-length": "short"|"long",  
    "color-named": "always-where-possible"|"never",  
    "color-no-hex": true,  
    "color-no-invalid-hex": true,  
    "comment-empty-line-before": "always"|"never",  
    "comment-no-empty": true,  
    "comment-whitespace-inside": "always"|"never",  
    "comment-word-blacklist": string|[],  
    "custom-media-pattern": string,  
    "custom-property-empty-line-before": "always"|"never",  
    "custom-property-pattern": string,  
    "declaration-bang-space-after": "always"|"never",  
    "declaration-bang-space-before": "always"|"never",  
    "declaration-block-no-duplicate-properties": true,  
    "declaration-block-no-redundant-longhand-properties": true,  
    "declaration-block-no-shorthand-property-overrides": true,  
    "declaration-block-semicolon-newline-after": "always"|"always-multi-line"|"never-multi-line",  
    "declaration-block-semicolon-newline-before": "always"|"always-multi-line"|"never-multi-line",  
    "declaration-block-semicolon-space-after": "always"|"never"|"always-single-line"|"never-single-line",  
    "declaration-block-semicolon-space-before": "always"|"never"|"always-single-line"|"never-single-line",  
    "declaration-block-single-line-max-declarations": int,  
    "declaration-block-trailing-semicolon": "always"|"never",  
    "declaration-colon-newline-after": "always"|"always-multi-line",  
    "declaration-colon-space-after": "always"|"never"|"always-single-line",  
    "declaration-colon-space-before": "always"|"never",  
    "declaration-empty-line-before": "always"|"never",  
    "declaration-no-important": true,  
    "declaration-property-unit-blacklist": {},  
    "declaration-property-unit-whitelist": {},  
    "declaration-property-value-blacklist": {},  
    "declaration-property-value-whitelist": {},  
    "font-family-name-quotes": "always-where-required"|"always-where-recommended"|"always-unless-keyword",  
    "font-family-no-duplicate-names": true,  
    "font-family-no-missing-generic-family-keyword": true,  
    "font-weight-notation": "numeric"|"named",  
    "function-blacklist": string|[],  
    "function-calc-no-unspaced-operator": true,  
    "function-comma-newline-after": "always"|"always-multi-line"|"never-multi-line",  
    "function-comma-newline-before": "always"|"always-multi-line"|"never-multi-line",  
    "function-comma-space-after": "always"|"never"|"always-single-line"|"never-single-line",  
    "function-comma-space-before": "always"|"never"|"always-single-line"|"never-single-line",  
    "function-linear-gradient-no-nonstandard-direction": true,  
    "function-max-empty-lines": int,  
    "function-name-case": "lower"|"upper",  
    "function-parentheses-newline-inside": "always"|"always-multi-line"|"never-multi-line",  
    "function-parentheses-space-inside": "always"|"never"|"always-single-line"|"never-single-line",  
    "function-url-no-scheme-relative": true,  
    "function-url-quotes": "always"|"never",  
    "function-url-scheme-blacklist": string|[],  
    "function-url-scheme-whitelist": string|[],  
    "function-whitelist": string|[],  
    "function-whitespace-after": "always"|"never",  
    "indentation": int|"tab",  
    "keyframe-declaration-no-important": true,  
    "keyframes-name-pattern": string,  
    "length-zero-no-unit": true,  
    "linebreaks": "unix"|"windows",  
    "max-empty-lines": int,  
    "max-line-length": int,  
    "max-nesting-depth": int,  
    "media-feature-colon-space-after": "always"|"never",  
    "media-feature-colon-space-before": "always"|"never",  
    "media-feature-name-blacklist": string|[],  
    "media-feature-name-case": "lower"|"upper",  
    "media-feature-name-no-unknown": true,  
    "media-feature-name-no-vendor-prefix": true,  
    "media-feature-name-value-whitelist": {},  
    "media-feature-name-whitelist": string|[],  
    "media-feature-parentheses-space-inside": "always"|"never",  
    "media-feature-range-operator-space-after": "always"|"never",  
    "media-feature-range-operator-space-before": "always"|"never",  
    "media-query-list-comma-newline-after": "always"|"always-multi-line"|"never-multi-line",  
    "media-query-list-comma-newline-before": "always"|"always-multi-line"|"never-multi-line",  
    "media-query-list-comma-space-after": "always"|"never"|"always-single-line"|"never-single-line",  
    "media-query-list-comma-space-before": "always"|"never"|"always-single-line"|"never-single-line",  
    "no-descending-specificity": true,  
    "no-duplicate-at-import-rules": true,  
    "no-duplicate-selectors": true,  
    "no-empty-source": true,  
    "no-empty-first-line": true,  
    "no-eol-whitespace": true,  
    "no-extra-semicolons": true,  
    "no-invalid-double-slash-comments": true,  
    "no-missing-end-of-source-newline": true,  
    "no-unknown-animations": true,  
    "number-leading-zero": "always"|"never",  
    "number-max-precision": int,  
    "number-no-trailing-zeros": true,  
    "property-blacklist": string|[],  
    "property-case": "lower"|"upper",  
    "property-no-unknown": true,  
    "property-no-vendor-prefix": true,  
    "property-whitelist": string|[],  
    "rule-empty-line-before": "always"|"never"|"always-multi-line"|"never-multi-line",  
    "selector-attribute-brackets-space-inside": "always"|"never",  
    "selector-attribute-operator-blacklist": string|[],  
    "selector-attribute-operator-space-after": "always"|"never",  
    "selector-attribute-operator-space-before": "always"|"never",  
    "selector-attribute-operator-whitelist": string|[],  
    "selector-attribute-quotes": "always"|"never",  
    "selector-class-pattern": string,  
    "selector-combinator-blacklist": string|[],  
    "selector-combinator-space-after": "always"|"never",  
    "selector-combinator-space-before": "always"|"never",  
    "selector-combinator-whitelist": string|[],  
    "selector-descendant-combinator-no-non-space": true,  
    "selector-id-pattern": string,  
    "selector-list-comma-newline-after": "always"|"always-multi-line"|"never-multi-line",  
    "selector-list-comma-newline-before": "always"|"always-multi-line"|"never-multi-line",  
    "selector-list-comma-space-after": "always"|"never"|"always-single-line"|"never-single-line",  
    "selector-list-comma-space-before": "always"|"never"|"always-single-line"|"never-single-line",  
    "selector-max-attribute": int,  
    "selector-max-class": int,  
    "selector-max-combinators": int,  
    "selector-max-compound-selectors": int,  
    "selector-max-empty-lines": int,  
    "selector-max-id": int,  
    "selector-max-pseudo-class": int,  
    "selector-max-specificity": string,  
    "selector-max-type": int,  
    "selector-max-universal": int,  
    "selector-nested-pattern": string,  
    "selector-no-qualifying-type": true,  
    "selector-no-vendor-prefix": true,  
    "selector-pseudo-class-blacklist": string|[],  
    "selector-pseudo-class-case": "lower"|"upper",  
    "selector-pseudo-class-no-unknown": true,  
    "selector-pseudo-class-parentheses-space-inside": "always"|"never",  
    "selector-pseudo-class-whitelist": string|[],  
    "selector-pseudo-element-blacklist": string|[],  
    "selector-pseudo-element-case": "lower"|"upper",  
    "selector-pseudo-element-colon-notation": "single"|"double",  
    "selector-pseudo-element-no-unknown": true,  
    "selector-pseudo-element-whitelist": string|[],  
    "selector-type-case": "lower"|"upper",  
    "selector-type-no-unknown": true,  
    "shorthand-property-no-redundant-values": true,  
    "string-no-newline": true,  
    "string-quotes": "single"|"double",  
    "time-min-milliseconds": int,  
    "unit-blacklist": string|[],  
    "unit-case": "lower"|"upper",  
    "unit-no-unknown": true,  
    "unit-whitelist": string|[],  
    "value-keyword-case": "lower"|"upper",  
    "value-list-comma-newline-after": "always"|"always-multi-line"|"never-multi-line",  
    "value-list-comma-newline-before": "always"|"always-multi-line"|"never-multi-line",  
    "value-list-comma-space-after": "always"|"never"|"always-single-line"|"never-single-line",  
    "value-list-comma-space-before": "always"|"never"|"always-single-line"|"never-single-line",  
    "value-list-max-empty-lines": int,  
    "value-no-vendor-prefix": true  
    }  
  }

规则参考列表(中文)

2018-10-16 翻译官网

Possible errors

Color 颜色

  • color-no-invalid-hex: 禁止无效的十六进制颜色

Font family 字体系列

  • font-family-no-duplicate-names: Disallow duplicate font family names.
  • font-family-no-missing-generic-family-keyword: Disallow missing generic families in lists of font family names.

Function 函数

  • function-calc-no-unspaced-operator: 禁止在 calc 函数内的运算符间省略空格
  • function-linear-gradient-no-nonstandard-direction: 禁止在 linear-gradient() 内使用不符合标准语法的值

String 字符串

  • string-no-newline: 不允许字符串(非转义)换行

Unit

  • unit-no-unknown: 不允许未知的单位

Property 属性

  • property-no-unknown: 不允许未知属性

Keyframe declaration

  • keyframe-declaration-no-important: 不允许!important在关键帧声明

Declaration block 声明块

  • declaration-block-no-duplicate-properties: 禁止在声明块内出现重复属性
  • declaration-block-no-shorthand-property-overrides: 禁止使用速记属性重写相关属性

Block

  • block-no-empty: 不允许空块

Selector

  • selector-pseudo-class-no-unknown: 不允许未知的伪类选择器
  • selector-pseudo-element-no-unknown: 不允许未知的伪元素选择器
  • selector-type-no-unknown: 不允许未知类型选择器

Media feature

  • media-feature-name-no-unknown: 不允许未知的媒体功能的名字

At-rule

  • at-rule-no-unknown: 不允许at-rules不明

Comment

  • comment-no-empty: 不允许空注释

General / Sheet

  • no-descending-specificity:不允许选择器之后覆盖选择器的低特异性更高的特异性
  • no-duplicate-at-import-rules: Disallow duplicate @import rules within a stylesheet.
  • no-duplicate-selectors: 不允许重复的选择器
  • no-empty-source: 不允许空的来源
  • no-extra-semicolons: 不允许额外的分号
  • no-invalid-double-slash-comments: 不允许双斜杠注释(/ /…)不支持的CSS

Limit language features

color 颜色

  • color-named: 在特定的情况下不允许使用命名的颜色值
  • color-no-hex: 禁止使用十六进制的颜色

Function 函数

  • function-blacklist: 指定一个不允许使用函数的黑名单
  • function-url-no-scheme-relative: 不允许文档相对的URL
  • function-url-scheme-blacklist: 指定允许URL方案的黑名单
  • function-url-scheme-whitelist: 指定允许URL方案的白名单
  • function-whitelist: 指定允许的功能的白名单

Keyframes

  • keyframes-name-pattern: Specify a pattern for keyframe names.

Number 数值

  • number-max-precision: 限制数值的小数位数

Time

  • time-min-milliseconds: Specify the minimum number of milliseconds for time values.

Unit

  • unit-blacklist: 指定不允许使用单位的黑名单
  • unit-whitelist: 指定允许单位的白名单

Shorthand property

  • shorthand-property-no-redundant-values: 不允许在简写属性冗余值

Value 值

  • value-no-vendor-prefix: 禁止值添加供应商前缀值

Custom property 自定义属性

  • custom-property-pattern: 指定自定义属性的模式

Property 属性

  • property-blacklist: 指定一个不允许使用属性的黑名单
  • property-no-vendor-prefix: 禁止属性添加供应商前缀
  • property-whitelist: 指定一个允许使用属性的白名单

Declaration 声明

  • declaration-block-no-redundant-longhand-properties: 不允许手写属性,可以组合成一个简写属性
  • declaration-no-important: 不允许!important声明
  • declaration-property-unit-blacklist: 指定一个黑名单内不允许声明属性
  • declaration-property-unit-whitelist: 指定一个白名单内允许声明属性
  • declaration-property-value-blacklist:指定一个黑名单,不允许在声明属性和值对
  • declaration-property-value-whitelist: 指定一个允许属性和值对声明的白名单

Declaration block 声明块

  • declaration-block-single-line-max-declarations: 在单行声明块中限制声明的数量

Selector 选择器

  • selector-attribute-operator-blacklist: 指定一个黑名单不允许属性的操作符
  • selector-attribute-operator-whitelist: 指定一个属性允许运营商的白名单
  • selector-class-pattern: 指定类选择器的模式(模式指的是正则表达式)
  • selector-combinator-blacklist: Specify a blacklist of disallowed combinators.
  • selector-combinator-whitelist: Specify a whitelist of allowed combinators.
  • selector-id-pattern: 指定id选择器的模式
  • selector-max-attribute: Limit the number of attribute selectors in a selector.
  • selector-max-class: Limit the number of classes in a selector.
  • selector-max-combinators: Limit the number of combinators in a selector.
  • selector-max-compound-selectors: 在一个选择器里面限制复合选择器的数量
  • selector-max-empty-lines: 限制内相邻的空行选择器的数量
  • selector-max-id: Limit the number of ID selectors in a selector.
  • selector-max-pseudo-class: Limit the number of pseudo-classes in a selector.
  • selector-max-specificity: 限制选择器的特异性
  • selector-max-type: Limit the number of type in a selector.
  • selector-max-universal: Limit the number of universal selectors in a selector.
  • selector-nested-pattern: 指定一个模式选择器的规则嵌套规则
  • selector-no-qualifying-type: 不允许符合条件的选择器的类型
  • selector-no-vendor-prefix: 不允许选择器的前缀
  • selector-pseudo-class-blacklist: 指定一个黑名单禁止伪类选择器
  • selector-pseudo-class-whitelist: 指定一个白名单禁止伪类选择器
  • selector-pseudo-element-blacklist: Specify a blacklist of disallowed pseudo-element selectors.
  • selector-pseudo-element-whitelist: Specify a whitelist of allowed pseudo-element selectors.

Media feature 媒体特性

  • media-feature-name-blacklist: Specify a blacklist of disallowed media feature names.
  • media-feature-name-no-vendor-prefix: 禁止媒体特性属性名添加供应商前缀
  • media-feature-name-value-whitelist: Specify a whitelist of allowed media feature name and value pairs.
  • media-feature-name-whitelist: Specify a whitelist of allowed media feature names.

Custom media 自定义媒体

  • custom-media-pattern: 指定自定义媒体查询的名称模式

At-rule AT规则

  • at-rule-blacklist: 不允许at-rules,指定一个黑名单。
  • at-rule-no-vendor-prefix: 禁止AT规则 添加供应商前缀
  • at-rule-whitelist:指定允许at-rules的白名单

Comment 注释

  • comment-word-blacklist: 指定一个黑名单内不允许的话评论

General / Sheet

  • max-nesting-depth: 限制的深度嵌套
  • no-unknown-animations: 不允许动画名称不对应@keyframes声明

Stylistic issues

颜色

  • color-hex-case: 指定十六进制颜色的大小写
  • color-hex-length: 指定十六进制颜色的长度

Font family 字体系列

  • font-family-name-quotes: 指定字体系列不应用于单双引号内

Font weight 字体粗细

  • font-weight-notation: 要求一致的数值或命名作为 font-weight 的值

Function 函数

  • function-comma-newline-after: 在函数的逗号后指定一个换行符或禁止留有空格
  • function-comma-newline-before: 在函数的逗号前指定一个换行符或禁止留有空格
  • function-comma-space-after: 在函数的逗号后指定一个空格或禁止留有空格
  • function-comma-space-before: 在函数的逗号前指定一个空格或禁止留有空格
  • function-max-empty-lines: Limit the number of adjacent empty lines within functions (Autofixable).
  • function-name-case: Specify lowercase or uppercase for function names (Autofixable).
  • function-parentheses-newline-inside: 在函数括号内指定一个换行符或禁止留有空格
  • function-parentheses-space-inside: 在函数括号内指定一个空格或禁止留有空格
  • function-url-quotes: 为urls指定单引或双引号
  • function-whitespace-after: 在函数后指定一个空格或禁止留有空格

Number 数值

  • number-leading-zero: 要求或不允许数值小于 1 的数字前面添加 0
  • number-no-trailing-zeros: 禁止在数值内尾随 0

String 字符串

  • string-quotes: 为字符串指定单引或双引号

Length 长度

  • length-zero-no-unit: 禁止单位零长度

Unit 单位

  • unit-case: 指定大写或小写的单位

Value 值

  • value-keyword-case: 指定大写或小写关键字的值

Value list 值列表

  • value-list-comma-newline-after: 在值列表的逗号后指定一个换行符或禁止留有空格
  • value-list-comma-newline-before: 在值列表的逗号前指定一个换行符或禁止留有空格
  • value-list-comma-space-after: 在值列表的逗号后指定一个空格或禁止留有空格
  • value-list-comma-space-before: 在值列表的逗号前指定一个空格或禁止留有空格
  • value-list-max-empty-lines: 限制相邻的数量值列表内空行

Custom property 自定义属性

  • custom-property-empty-line-before: 自定义属性之前equire或不允许空行

Property 属性

  • property-case: 为属性指定小写或大写

Declaration

  • declaration-bang-space-after: bang声明之后需要一个空格或者不允许空白
  • declaration-bang-space-before: bang声明之前需要一个空格或者不允许空白
  • declaration-colon-newline-after: 冒号后的声明需要一个换行符或不允许空白
  • declaration-colon-space-after: 冒号后的声明需要一个空格或不允许空白
  • declaration-colon-space-before: 冒号之前的声明需要一个空格或不允许空白
  • declaration-empty-line-before: 要求声明前不允许空一行

Declaration block

  • declaration-block-semicolon-newline-after: 要求一个换行符或不允许空白块分号后
  • declaration-block-semicolon-newline-before: 要求一个换行符或不允许空白块分号之前的声明
  • declaration-block-semicolon-space-after: 要求一个空间或不允许空白块分号后的声明
  • declaration-block-semicolon-space-before: 要求一个空间或不允许空白块分号之前的声明
  • declaration-block-trailing-semicolon: 要求或不允许在声明块后面的分号

Block 块

  • block-closing-brace-empty-line-before: 要求或不允许关闭括号前空一行
  • block-closing-brace-newline-after: 在块的右大括号后指定一个换行符或禁止留有空格
  • block-closing-brace-newline-before: 在块的右大括号前指定一个换行符或禁止留有空格
  • block-closing-brace-space-after: 在块的右大括号后指定一个空格或禁止留有空格
  • block-closing-brace-space-before: 在块的右大括号前指定一个空格或禁止留有空格
  • block-opening-brace-newline-after: 在块的左大括号后制定一个换行符
  • block-opening-brace-newline-before: 在块的左大括号前指定一个换行符或禁止留有空格
  • block-opening-brace-space-after: 在块的左大括号后指定一个空格或禁止留有空格
  • block-opening-brace-space-before: 在块的左大括号前指定一个空格或禁止留有空格

Selector 选择器

  • selector-attribute-brackets-space-inside: 在括号里的属性选择器需要一个空格或者不允许空白
  • selector-attribute-operator-space-after: 需要一个空间或不允许空格后运营商在属性选择器
  • selector-attribute-operator-space-before: 需要一个空间或不允许空格内运营商之前属性选择器
  • selector-attribute-quotes: 需要或不允许引用属性值
  • selector-combinator-space-after: 在复合选择器之后要求或不允许留有一个空格
  • selector-combinator-space-before: 在复合选择器之前要求或不允许留有一个空格
  • selector-descendant-combinator-no-non-space: 不允许的字符的后代组合子选择器进行技术改造
  • selector-pseudo-class-case: 为伪类选择器指定小写或大写
  • selector-pseudo-class-parentheses-space-inside: 需要一个空格或不允许空格在括号里面的伪类选择器
  • selector-pseudo-element-case: 为伪元素选择器指定小写或大写
  • selector-pseudo-element-colon-notation: 为适用的伪元素指定单引号或双冒号符号
  • selector-type-case: 指定小写或大写类型选择器

Selector list 选择器列表

  • selector-list-comma-newline-after: 在选择器列表的逗号后指定一个换行符或禁止留有空格
  • selector-list-comma-newline-before: 在选择器列表的逗号前指定一个换行符或禁止留有空格
  • selector-list-comma-space-after: 在选择器列表的逗号后指定一个空格或禁止留有空格
  • selector-list-comma-space-before: 在选择器列表的逗号前指定一个空格或禁止留有空格

Rule 规则

  • rule-empty-line-before: 不允许rules前空一行

Media feature 媒体特性

  • media-feature-colon-space-after: 在媒体特性的冒号后指定一个空格或禁止留有空格
  • media-feature-colon-space-before: 在媒体特性的冒号前指定一个空格或禁止留有空格
  • media-feature-name-case: 为媒体特性名称指定小写或大写
  • media-feature-parentheses-space-inside: 需要一个空间或不允许空格在括号里面的媒体功能
  • media-feature-range-operator-space-after: 需要一个空间或不允许空白范围运算符后媒体的特性
  • media-feature-range-operator-space-before: 之前需要一个空间或不允许空格符范围在媒体功能

Media query list 媒体查询列表

  • media-query-list-comma-newline-after: 需要一个换行符或不允许空格后媒体查询的逗号分隔列表
  • media-query-list-comma-newline-before: 需要一个换行符或不允许空格之前媒体查询的逗号分隔列表
  • media-query-list-comma-space-after: 需要一个空间或不允许空格后媒体查询的逗号分隔列表
  • media-query-list-comma-space-before:需要一个空间或不允许空格之前媒体查询的逗号分隔列表

At-rule AT规则

  • at-rule-empty-line-before: 在 AT规则 前要求或不允许留有空行
  • at-rule-name-case: 指定at-rules小写或大写的名字
  • at-rule-name-newline-after: at-rule名称后需要一个换行符
  • at-rule-name-space-after: 需要一个空格后at-rule名称
  • at-rule-semicolon-newline-after: 需要一个换行符之后at-rules的分号
  • at-rule-semicolon-space-before: 需要一个空格之后at-rules的分号

Comment 注释

  • comment-empty-line-before: 要求或不允许注释前面留有一个空格
  • comment-whitespace-inside: 要求或不允许注释内留有一个空格

General / Sheet 常用样式

  • indentation: 指定缩进
  • linebreaks: Specify unix or windows linebreaks (Autofixable).
  • max-empty-lines: 限制相邻的空行数
  • max-line-length: 限制每行的长度
  • no-eol-whitespace: 禁止行尾留有空白
  • no-missing-end-of-source-newline: 不允许丢失end-of-source换行
  • no-empty-first-line: Disallow empty first lines. (Autofixable)
收起阅读 »

Vue语法校验

vue语法校验

vue语法校验需要安装eslint-plugins-vue插件

插件安装完成后,进入【插件配置】,即可找到刚才安装插件。它的对应的配置文件是.eslintrc.js,选项对应说明如下:

  module.exports = {  
      "extends": "plugin:vue/essential",  
      "parserOptions": {},      
      "rules": {}             //规则  
  };

更多配置说明可以参考options

规则简介

官方规则列表

规则设置:

  • "off" 或 0 - 关闭规则
  • "warn" 或 1 - 开启规则,使用警告级别的错误:warn (不会导致程序退出)
  • "error" 或 2 - 开启规则,使用错误级别的错误:error (当被触发的时候,程序会退出)

增加或修改vue校验规则

修改.eslintrc.js文件,添加规则,比如:

  module.exports = {  
      "extends": "plugin:vue/base",  
      parserOptions: {  
          ecmaVersion: 2017,  
          sourceType: 'module'  
      },  
      "rules":{  
          //在computed properties中禁用异步actions  
          'vue/no-async-in-computed-properties': 'error',  
          //不允许重复的keys  
          'vue/no-dupe-keys': 'error',  
          //不允许重复的attributes  
          'vue/no-duplicate-attributes': 'error',  
          //在 <template> 标签下不允许解析错误  
          'vue/no-parsing-error': ['error',{  
              'x-invalid-end-tag': false,  
          }],  
          //不允许覆盖保留关键字  
          'vue/no-reserved-keys': 'error',  
          //强制data必须是一个带返回值的函数  
          // 'vue/no-shared-component-data': 'error',  
          //不允许在computed properties中出现副作用。  
          'vue/no-side-effects-in-computed-properties': 'error',  
          //<template>不允许key属性  
          'vue/no-template-key': 'error',  
          //在 <textarea> 中不允许mustaches  
          'vue/no-textarea-mustache': 'error',  
          //不允许在v-for或者范围内的属性出现未使用的变量定义  
          'vue/no-unused-vars': 'error',  
          //<component>标签需要v-bind:is属性  
          'vue/require-component-is': 'error',  
          // render 函数必须有一个返回值  
          'vue/require-render-return': 'error',  
          //保证 v-bind:key 和 v-for 指令成对出现  
          'vue/require-v-for-key': 'error',  
          // 检查默认的prop值是否有效  
          'vue/require-valid-default-prop': 'error',  
          // 保证computed属性中有return语句   
          'vue/return-in-computed-property': 'error',  
          // 强制校验 template 根节点  
          'vue/valid-template-root': 'error',  
          // 强制校验 v-bind 指令  
          'vue/valid-v-bind': 'error',  
          // 强制校验 v-cloak 指令  
          'vue/valid-v-cloak': 'error',  
          // 强制校验 v-else-if 指令  
          'vue/valid-v-else-if': 'error',  
          // 强制校验 v-else 指令   
          'vue/valid-v-else': 'error',  
          // 强制校验 v-for 指令  
          'vue/valid-v-for': 'error',  
          // 强制校验 v-html 指令  
          'vue/valid-v-html': 'error',  
          // 强制校验 v-if 指令  
          'vue/valid-v-if': 'error',  
          // 强制校验 v-model 指令  
          'vue/valid-v-model': 'error',  
          // 强制校验 v-on 指令  
          'vue/valid-v-on': 'error',  
          // 强制校验 v-once 指令  
          'vue/valid-v-once': 'error',  
          // 强制校验 v-pre 指令  
          'vue/valid-v-pre': 'error',  
          // 强制校验 v-show 指令  
          'vue/valid-v-show': 'error',  
          // 强制校验 v-text 指令  
          'vue/valid-v-text': 'error'  
      }  
  };  
继续阅读 »

vue语法校验需要安装eslint-plugins-vue插件

插件安装完成后,进入【插件配置】,即可找到刚才安装插件。它的对应的配置文件是.eslintrc.js,选项对应说明如下:

  module.exports = {  
      "extends": "plugin:vue/essential",  
      "parserOptions": {},      
      "rules": {}             //规则  
  };

更多配置说明可以参考options

规则简介

官方规则列表

规则设置:

  • "off" 或 0 - 关闭规则
  • "warn" 或 1 - 开启规则,使用警告级别的错误:warn (不会导致程序退出)
  • "error" 或 2 - 开启规则,使用错误级别的错误:error (当被触发的时候,程序会退出)

增加或修改vue校验规则

修改.eslintrc.js文件,添加规则,比如:

  module.exports = {  
      "extends": "plugin:vue/base",  
      parserOptions: {  
          ecmaVersion: 2017,  
          sourceType: 'module'  
      },  
      "rules":{  
          //在computed properties中禁用异步actions  
          'vue/no-async-in-computed-properties': 'error',  
          //不允许重复的keys  
          'vue/no-dupe-keys': 'error',  
          //不允许重复的attributes  
          'vue/no-duplicate-attributes': 'error',  
          //在 <template> 标签下不允许解析错误  
          'vue/no-parsing-error': ['error',{  
              'x-invalid-end-tag': false,  
          }],  
          //不允许覆盖保留关键字  
          'vue/no-reserved-keys': 'error',  
          //强制data必须是一个带返回值的函数  
          // 'vue/no-shared-component-data': 'error',  
          //不允许在computed properties中出现副作用。  
          'vue/no-side-effects-in-computed-properties': 'error',  
          //<template>不允许key属性  
          'vue/no-template-key': 'error',  
          //在 <textarea> 中不允许mustaches  
          'vue/no-textarea-mustache': 'error',  
          //不允许在v-for或者范围内的属性出现未使用的变量定义  
          'vue/no-unused-vars': 'error',  
          //<component>标签需要v-bind:is属性  
          'vue/require-component-is': 'error',  
          // render 函数必须有一个返回值  
          'vue/require-render-return': 'error',  
          //保证 v-bind:key 和 v-for 指令成对出现  
          'vue/require-v-for-key': 'error',  
          // 检查默认的prop值是否有效  
          'vue/require-valid-default-prop': 'error',  
          // 保证computed属性中有return语句   
          'vue/return-in-computed-property': 'error',  
          // 强制校验 template 根节点  
          'vue/valid-template-root': 'error',  
          // 强制校验 v-bind 指令  
          'vue/valid-v-bind': 'error',  
          // 强制校验 v-cloak 指令  
          'vue/valid-v-cloak': 'error',  
          // 强制校验 v-else-if 指令  
          'vue/valid-v-else-if': 'error',  
          // 强制校验 v-else 指令   
          'vue/valid-v-else': 'error',  
          // 强制校验 v-for 指令  
          'vue/valid-v-for': 'error',  
          // 强制校验 v-html 指令  
          'vue/valid-v-html': 'error',  
          // 强制校验 v-if 指令  
          'vue/valid-v-if': 'error',  
          // 强制校验 v-model 指令  
          'vue/valid-v-model': 'error',  
          // 强制校验 v-on 指令  
          'vue/valid-v-on': 'error',  
          // 强制校验 v-once 指令  
          'vue/valid-v-once': 'error',  
          // 强制校验 v-pre 指令  
          'vue/valid-v-pre': 'error',  
          // 强制校验 v-show 指令  
          'vue/valid-v-show': 'error',  
          // 强制校验 v-text 指令  
          'vue/valid-v-text': 'error'  
      }  
  };  
收起阅读 »

uniapp直接调用安卓自定义方法

uniapp

在研究离线打包,和三方插件之后的一天,发现uniapp可以直接调用安卓里写的方法,之前完全是自己想复杂了,主要还是h5+ 的开发没那么熟悉。

此处基于uniapp在Android Studio离线打包成功后部分。

1.因为之前离线打包,安卓下的项目java里面的全部都删除了,现在新增一个自定义的包在下面新增一个java类。为了测试功能,写了个简单的加法。

package com.hji.test;  

public class AddCount {  
    public int add(int a, int b) {  
        return a + b;  
    }  
}  

在uniapp vue下,新增一个按钮,和方法

add2(){  
            var AddCount = plus.android.importClass('com.hji.test.AddCount');  
            var addCount = new AddCount();  
            this.result1 = addCount.add(1,2);  
        },

本地打包后,替换掉www下文件。运行就可以

简单哭了,我想的也太复杂了T T
为了测试调用安卓上页面,也写了个简单的拍照;
在自定义的包下新建一个java类

package com.hji.test;  

import android.content.Intent;  
import android.graphics.Bitmap;  
import android.os.Bundle;  
import android.provider.MediaStore;  
import android.support.v7.app.AppCompatActivity;  
import android.view.View;  
import android.widget.ImageView;  

import com.example.mytest.R;  

public class TakePhotoActivity extends AppCompatActivity {  
    private ImageView imageView;  

    @Override  
    protected void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState);  
        setContentView(R.layout.activity_take_photo);  

        imageView = findViewById(R.id.imageView);  

    }  

    static final int REQUEST_IMAGE_CAPTURE = 1;  

    public void takePhoto(View view) {  
        dispatchTakePictureIntent();  
    }  

    private void dispatchTakePictureIntent() {  
        Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);  
        if (takePictureIntent.resolveActivity(getPackageManager()) != null) {  
            startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);  
        }  
    }  

    @Override  
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {  
        if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK) {  
            Bundle extras = data.getExtras();  
            Bitmap imageBitmap = (Bitmap) extras.get("data");  
            imageView.setImageBitmap(imageBitmap);  
        }  
    }  

}  

在res下layout新增一个拍照页面

<?xml version="1.0" encoding="utf-8"?>  
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"  
    xmlns:app="http://schemas.android.com/apk/res-auto"  
    xmlns:tools="http://schemas.android.com/tools"  
    android:layout_width="match_parent"  
    android:layout_height="match_parent"  
    tools:context="com.hji.test.TakePhotoActivity">  

    <ImageView  
        android:id="@+id/imageView"  
        android:layout_width="342dp"  
        android:layout_height="360dp"  
        android:layout_marginStart="16dp"  
        android:layout_marginLeft="16dp"  
        android:layout_marginTop="17dp"  
        app:layout_constraintStart_toStartOf="parent"  
        app:layout_constraintTop_toBottomOf="@+id/button2"  
        tools:srcCompat="@tools:sample/avatars" />  

    <Button  
        android:id="@+id/button2"  
        style="@style/Widget.AppCompat.Button.Small"  
        android:layout_width="101dp"  
        android:layout_height="48dp"  
        android:layout_marginStart="63dp"  
        android:layout_marginLeft="63dp"  
        android:layout_marginTop="16dp"  
        android:onClick="takePhoto"  
        android:text="拍 照"  
        android:textColor="@android:color/holo_green_dark"  
        android:textSize="14sp"  
        android:typeface="normal"  
        android:visibility="visible"  
        app:layout_constraintStart_toStartOf="parent"  
      />  
</android.support.constraint.ConstraintLayout>

在uniapp下使用

    takePhoto() {  
            var main = plus.android.runtimeMainActivity();  
            var Intent = plus.android.importClass('android.content.Intent');  
            var MyActivity = plus.android.importClass('com.hji.test.TakePhotoActivity');  
            var intent = new Intent(main, MyActivity.class);  
            main.startActivity(intent);  
        },

写个按钮直接调用,本地打包后,运行。就OK了 = =

根据要求,新增安卓项目目录截图。

没想到会有这么多人需要结合原生开发。可能会遇到各种各样的问题;
留下demo代码。需要的可以下载测试下。
https://github.com/sunshine-jing/uniapp-AndroidTest
test是uniapp项目;
mytest是安卓项目

今天仔细看了下demo,红色是之前用插件的形式调试出来的;
绿色的是之后发现可以直接调用到addcout方法。
demo第一个测试出现 test123,是插件出来的,name和value是uniapp内传过去后,返回到界面上的。

继续阅读 »

在研究离线打包,和三方插件之后的一天,发现uniapp可以直接调用安卓里写的方法,之前完全是自己想复杂了,主要还是h5+ 的开发没那么熟悉。

此处基于uniapp在Android Studio离线打包成功后部分。

1.因为之前离线打包,安卓下的项目java里面的全部都删除了,现在新增一个自定义的包在下面新增一个java类。为了测试功能,写了个简单的加法。

package com.hji.test;  

public class AddCount {  
    public int add(int a, int b) {  
        return a + b;  
    }  
}  

在uniapp vue下,新增一个按钮,和方法

add2(){  
            var AddCount = plus.android.importClass('com.hji.test.AddCount');  
            var addCount = new AddCount();  
            this.result1 = addCount.add(1,2);  
        },

本地打包后,替换掉www下文件。运行就可以

简单哭了,我想的也太复杂了T T
为了测试调用安卓上页面,也写了个简单的拍照;
在自定义的包下新建一个java类

package com.hji.test;  

import android.content.Intent;  
import android.graphics.Bitmap;  
import android.os.Bundle;  
import android.provider.MediaStore;  
import android.support.v7.app.AppCompatActivity;  
import android.view.View;  
import android.widget.ImageView;  

import com.example.mytest.R;  

public class TakePhotoActivity extends AppCompatActivity {  
    private ImageView imageView;  

    @Override  
    protected void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState);  
        setContentView(R.layout.activity_take_photo);  

        imageView = findViewById(R.id.imageView);  

    }  

    static final int REQUEST_IMAGE_CAPTURE = 1;  

    public void takePhoto(View view) {  
        dispatchTakePictureIntent();  
    }  

    private void dispatchTakePictureIntent() {  
        Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);  
        if (takePictureIntent.resolveActivity(getPackageManager()) != null) {  
            startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);  
        }  
    }  

    @Override  
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {  
        if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK) {  
            Bundle extras = data.getExtras();  
            Bitmap imageBitmap = (Bitmap) extras.get("data");  
            imageView.setImageBitmap(imageBitmap);  
        }  
    }  

}  

在res下layout新增一个拍照页面

<?xml version="1.0" encoding="utf-8"?>  
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"  
    xmlns:app="http://schemas.android.com/apk/res-auto"  
    xmlns:tools="http://schemas.android.com/tools"  
    android:layout_width="match_parent"  
    android:layout_height="match_parent"  
    tools:context="com.hji.test.TakePhotoActivity">  

    <ImageView  
        android:id="@+id/imageView"  
        android:layout_width="342dp"  
        android:layout_height="360dp"  
        android:layout_marginStart="16dp"  
        android:layout_marginLeft="16dp"  
        android:layout_marginTop="17dp"  
        app:layout_constraintStart_toStartOf="parent"  
        app:layout_constraintTop_toBottomOf="@+id/button2"  
        tools:srcCompat="@tools:sample/avatars" />  

    <Button  
        android:id="@+id/button2"  
        style="@style/Widget.AppCompat.Button.Small"  
        android:layout_width="101dp"  
        android:layout_height="48dp"  
        android:layout_marginStart="63dp"  
        android:layout_marginLeft="63dp"  
        android:layout_marginTop="16dp"  
        android:onClick="takePhoto"  
        android:text="拍 照"  
        android:textColor="@android:color/holo_green_dark"  
        android:textSize="14sp"  
        android:typeface="normal"  
        android:visibility="visible"  
        app:layout_constraintStart_toStartOf="parent"  
      />  
</android.support.constraint.ConstraintLayout>

在uniapp下使用

    takePhoto() {  
            var main = plus.android.runtimeMainActivity();  
            var Intent = plus.android.importClass('android.content.Intent');  
            var MyActivity = plus.android.importClass('com.hji.test.TakePhotoActivity');  
            var intent = new Intent(main, MyActivity.class);  
            main.startActivity(intent);  
        },

写个按钮直接调用,本地打包后,运行。就OK了 = =

根据要求,新增安卓项目目录截图。

没想到会有这么多人需要结合原生开发。可能会遇到各种各样的问题;
留下demo代码。需要的可以下载测试下。
https://github.com/sunshine-jing/uniapp-AndroidTest
test是uniapp项目;
mytest是安卓项目

今天仔细看了下demo,红色是之前用插件的形式调试出来的;
绿色的是之后发现可以直接调用到addcout方法。
demo第一个测试出现 test123,是插件出来的,name和value是uniapp内传过去后,返回到界面上的。

收起阅读 »