阅读 327

前端也能开发APP -- Weex 基础使用指南

这是我参与8月更文挑战的第13天,活动详情查看:8月更文挑战

Weex 基础开发指南为大家带来~ 本篇中的相关知识点都是之前小编在学习 Weex 中一点点纪磊下来的,Weex相关开发文档很少,希望能对大家的开发有所帮助。

浏览Weex官方文档后阅读此文更佳。

更多文章在我的github及个人公众号【全栈道路】上,欢迎观赏【前端知识点】,如有受益,不要钱,小手点个Star

阅读本文您将收获

  • Weex 的差异化
  • 如何使用 Weex 开始开发
  • Weex 的语法差异

差异化

Weex 和 传统Web 的平台差异

  • Weex 是跨平台解决方案,web 仅是作为一个开发环境
  • Weex 不存在 DOM
    • 没有 Element , Event 等对象
    • 只有 有限的事件类型 和 native 端常用事件类型,如 Longpress, Appear
  • Weex 不存在BOM
    • 没有 document , window 等对象
    • 提供自身对象获取设备部分数据 WXEnvironment
  • Weex 的运行环境以原生应用为主,在 AndroidiOS 环境中渲染出来的是原生的组件,而不是 DOM元素。
  • Weex 提供了原生设备调用 API

weex-toolkit 和 weexpack 的区别

  • weex-toolkit 初始化的项目是针对开发单个 Weex 页面而设计的,也就是说这样的项目只包括单个页面开发需要的东西,比如前端页面源文件、webpack 配置、npm 脚本等。项目产生的输出就是一个 JS Bundle 文件,可以自由的进行部署。
  • weexpack 是初始化一个完整的 App 工程,包括 AndroidiOS 的整个 App 起步,前端页面只是其中的一部分。这样的项目最终产出是一个 Android App 和一个 iOS App

必要条件

  • 开发环境
    • nodeJS
    • Android 开发环境
    • IOS 开发环境
  • 开发工具
    • Sublime Text
    • Android studio
    • Xcode
  • 代码管理
    • Github

快速开始

安装相关开发环境

  • 安装 node 开发环境
  • 安装 Android & IOS 开发环境

安装 weex-cli

  • npm install weex-toolkit -g

使用weex-cli创建项目

  • weex create demo-project
  • 填写相关配置信息

下载项目依赖包

  • 进入项目后 npm install

预览项目

浏览器端预览

  • npm start
  • 执行指令后会自动打开浏览器的页面窗口,但是建议使用真机进行预览,部分样式和代码 web 端与 native 端差距较大

native 端预览

  • 编译成 JS Bundle 文件
    • weex compile <源码目录或文件> <打包文件存放目录或文件>
  • 压缩编译
    • weex compile <源码目录或文件> <打包文件存放目录或文件> -m
  • 配置 Nginx
  • 移动应用客户端访问

开发

运行过程

  • 本地编写 Vue 代码,生成 web 页面
  • Weex 形成 JS bundle
  • 在云端,通过网络请求或预下发的方式将 JS bundle 传递到用户的 移动应用客户端
  • 在移动应用客户端里,WeexSDK 会准备好一个 JavaScript 引擎,并且在用户打开一个 Weex 页面时执行相应的 JS bundle
  • 各种命令发送到 native 端进行界面渲染或数据存储、网络通信、调用设备功能、用户交互响应

文件结构

  • |- src // 源码目录
  • |- node_modules // 依赖包
  • |- dist // 存放编译好的 js 文件
  • |- build // 存放npm build 时的 js 文件,可在 package.json 文件中配置
  • |- package.json // 项目的配置和依赖库文件
  • |- webpack.config.js // webpack 打包配置文件
  • |- config.js // 项目的相关配置文件,你可以在这个文件中配置切换不同的环境

导航方式

Vue-Router

  • 与 Vue 同

weex-navigator

  • 借用 IOS/Android navigator 模块

  • 使用方式

    • 把一个weex页面URL压入导航堆栈中
    push({
        url :""        // 要压入的 Weex 页面的 URL
        animated:""    // "true" 示意为页面压入时需要动画效果,"false" 则不需要,默认值为 "true"。注意,一定要是字符串类型的,千万不能写成布尔类型
    }, callback(){ 
        //回调
    })
    复制代码
    • 把当前Weex页面弹出导航堆栈中
    pop({
        animated:""    // "true" 示意为页面压入时需要动画效果,"false" 则不需要,默认值为 "true"。注意,一定要是字符串类型的,千万不能写成布尔类型
    }, callback(){
        //回调
    })
    复制代码

数据传递

Vue的方式

  • props
  • this.$emit('fun', data)

storage

  • 永久保存,在 H5/web 端 实际采用的是 HTML5 LocalStorage API
  • 限制:
    • H5/web 端 体积最大为5M
    • Android 和 IOS 端没有限制
  • 相关API
    • setItem(key, value, callback)
    • getItem(key, callback)
    • removeItem(key, callback)
    • length(callback)
    • getAllKeys(callback)

地址拼接

  • 利用 weex.config.bundleUrl
  • 使用方式
// 路由携带方式
navigator.push({
  url: 'http://192.168.xxx.xxx:8081/tmp/detail.js?id=1',
  animated: 'true'
})
// 获取参数
getUrlParam() {
  let name, value;
  let str = weex.config.bundleUrl; //取得整个地址栏
  let num = str.indexOf("?");
  str = str.substr(num + 1); //取得所有参数   

  let arr = str.split("&"); //各个参数放到数组里
  for (var i = 0; i < arr.length; i++) {
    num = arr[i].indexOf("=");
    if (num > 0) {
      name = arr[i].substring(0, num);
      value = arr[i].substr(num + 1);
      this.paramsDic[name] = value;
    }
  }
}
复制代码

BroadcastChannel

  • 源码定义
declare interface BroadcastChannel = {
  name: string,  // 频道名称
  postMessage: (message: any) => void;  // 广播消息
  onmessage: (event: MessageEvent) => void;  // 接收消息
  close: () => void;  // 关闭通信
}
复制代码
  • 通信过程

BroadcastChannel.png

  • 使用方式
// 广播消息
const broadcast = new BroadcastChannel('testChannel')
broadcast.postMessage('this is amessage.')
modal.toast({ message: '消息已发送' })

// 接收消息
let self = this
const broadcast = new BroadcastChannel('testChannel')
broadcast.onmessage = function(event) {
	modal.toast({ message: '消息已接收' })
	self.testData = event.data
}
复制代码

借用 native 做中转桥

  • vue -> native -> vue

数据通信 stream模块

请求过程

  • weex中发送fetch请求时,会先经过native内置的stream模块,并由stream模块向服务器发送请求。

请求实例 fetch(options, callback, progressCallback)

  • @options, 请求的配置选项,支持以下配置
    • method: string, HTTP 请求方法,值为 GET/POST/PUT/DELETE/PATCH/HEAD
    • url: string, 请求的 URL | string
    • headers: string, HTTP 请求头
    • type: string, 响应类型:json,text 或是 jsonp(在 native 原生实现中其实与 json 相同)
    • body: string, HTTP 请求体, 仅支持string类型的数据,不支持JSON,GET仅支持URL传参,Body的格式 'param1=p1&param2=p2'
  • 默认 Content-Typeapplication/x-www-form-urlencoded
  • @callback, 响应结果回调,回调函数将收到如下的 response 对象:
    • status: number, 返回的状态码
    • ok: boolean, 如果状态码在 200-299 之间就为 true
    • statusText: string, 状态描述文本
    • data: string, 返回的数据,如果请求类型是 json 和 jsonp,则它就是一个 object ,否则是一个 string。
    • headers: object, HTTP 响应头
  • @progressCallback , function, 请求过程中的请求进度.
    • readyState: number, 当前状态,1: 请求连接中;2: 返回响应头中;3: 正在加载返回数据
    • status: number, 返回的状态码
    • length: number, 已经接受到的数据长度. 你可以从响应头中获取总长度
    • statusText: string, 状态描述文本
    • headers: object, HTTP 响应头

使用示例

  • GET
let self = this
stream.fetch({
	method: 'GET',
	url: GET_URL,
	type:'json'
}, function(req) {
	if(!req.ok){
		self.getResult = "request failed";
	}else{
		console.log('get:'+req);
		self.getResult = JSON.stringify(req.data);
	}
},function(response){
	console.log('get in progress:'+response.length);
	self.getResult = "bytes received:"+response.length;
});
复制代码
  • POST
let self = this
stream.fetch({
	method: 'POST',
	url: POST_URL,
	type:'json',
	body: stringData
}, function(req) {
if(!req.ok){
	self.postResult = "request failed";
}else{
	console.log('get:'+JSON.stringify(req));
	self.postResult = JSON.stringify(req.data);
}
},function(response){
	console.log('get in progress:'+response.length);
	self.postResult = "bytes received:"+response.length;
});
复制代码

语法差异

HTML 标签

  • 遵循weex官方文档,部分标签样式在weex真机中不保证能够正常使用
    • <span>
  • weex 标签真正解析后会解析成不同的标签
    • <text> -> <p>
  • 结构不支持不规范嵌套
    • 如:<text> 嵌套 <text>
  • <div> 在 weex 中不可滚动,需要使用 滚动标签 <list> 或者 <scroller> 或者 <waterfall>
  • 部分详细的约束
    • <a> 不可直接添加文字,需要用 <text> 来显示文字
    • <input> 禁用须设置 disabled=true 不能简写
    • <input> 两个属性不同 maxlength 数值类型 max-length 输入字符串内容,测试失效,并且按照输入内容计算,不是字节
    • <div> 内直接添加文本,css和双向绑定会失效
    • <web> 用于在weex页面中嵌入一张网页内容,和HTML中的 <iframe> 作用类似。

CSS样式

  • 支持 pxwx 长度单位
  • 支持 行内样式 和 class类名 ,不支持设置 id名 ,真机失效
  • 不支持样式继承
  • 不支持行内样式,用 flex 布局解决
  • 不支持层级 z-index, 层级叠加根据书写顺序展示
  • 不支持 box-shadow
  • 不支持 css 三角形
  • 不支持 样式缩写
  • 部分支持伪类样式
    • Weex 支持四种伪类:active, focus, disabled, enabled
    • 所有组件都支持 active
    • 只有 <input> 组件和 <textarea> 组件支持 focus , enabled, diabled
  • 标准 CSS 中的空格和回车问题在真机中也会存在
  • 部分详细约束
    • <textarea> 须设置 rows,默认值为2,否则只展示两行
    • <textarea> 属性 placeholder-color 设置 placeholder 颜色
    • <image> 必须设置 width 和 height 属性才可以展示
    • <image> width 宽度撑满 750px;
    • <image> 按图片宽高比撑满 flex:1;
    • <list><scroller> 不支持同一方向的嵌套列表或滚动条
    • <text> css样式 lines:1; 设置超出隐藏显示省略号部分失效
    • position 的新属性 stiky, 用于滚动的header固定

JavaScript

  • weex 中不支持 Promisefinally() 方法,支持 then()catch()
  • v-if 支持 v-show 不支持
  • 冒泡机制
    • weex 中冒泡机制默认不开启,需要手动书写 bubble = true
    • 阻止冒泡 event.stopPropagation();
  • 支持手势操作监听

写在最后

如果你觉得这篇文章对你有益,烦请点赞以及分享给更多需要的人!

欢迎关注【全栈道路】及微信公众号【全栈道路】,获取更多好文及免费书籍!
有需要【百度】&【字节跳动】&【京东】&【猿辅导】内推的也请留言哦,你将享受VIP级极速内推服务~

往期好文

微信 JS API 支付的实现

创建个性化的 Github 个人主页

面试官问你<img>是什么元素时你怎么回答

特殊的JS 浮点数的存储与计算

[万字长文]百度和好未来面试经含答案 | 掘金技术征文

前端实用正则表达式&小技巧,一股脑全丢给你🏆 掘金技术征文|双节特别篇

冷门的 HTML tabindex 详解

几行代码教你解决微信生成海报及二维码

Vue3.0 响应式数据原理:ES6 Proxy

[前端面试]前端缓存问题看这篇,让面试官爱上你

如何优雅地画一条细线

[三分钟小文]前端性能优化-HTML、CSS、JS部分

[三分钟小文]前端性能优化-页面加载速度优化

[三分钟小文]前端性能优化-网络传输层优化

文章分类
前端
文章标签