开发
整个开发体验力求接近web开发,因此保留了和vue官方项目相同的项目结构
也许你并不需要支持web端,那为啥还要按web的习惯来调,因为浏览器的调试工具远比weex devtool好用
路由
src/router.js为路由文件,暂不支持多个路由文件
写法和web版vue的完全一致,不过不支持name只支持path
router.js中的/entry请不要删除,redirect也请不要改变,要想改变首页地址请参考下一节
设置首页
首先介绍下src/entry.vue
此页面加载时页面会被启动图覆盖,因此这个不是真正的首页
你应该新建一个真正的首页,例如登录页,然后再entry.vue的onLoad事件中写跳转逻辑,跳转到真正的首页
这样给人的感觉就是,从启动图直接到达了真正的首页
内置对象
一共有6个内置对象,掌握它们90%的业务需求都可以搞定了
$navigator(页面跳转)
此对象用于控制导航
主要功能
/**
* @param url 目标页面地址,在router中定义的path(必传)
* @param type (动画方式:'push'(默认,从右往左的动画),'present' (从底部弹出的动画) )(非必传)
* @param param (传到下一页面的参数)(非必传)
* @param animate (是否有动画效果(暂时没有实现无动画的效果))(非必传)
* @param callback (如果下一页面带回了参数,可以在这个回调中接受到)(非必传)
* @param preload (是否启用预加载,默认:true)(非必传)
*/
this.$navigator.push({url:'/index',type:'push',param:{name:'111'},animate:true,preload:true},(res)=>{
//下一个页面回来时触发
}))
2.页面返回
/**
*
* @param param (回调给上一个页面callback的参数,无参数回传可不传)(非必传)
* @param pageId (跨越页面回到指定pageId的页面,实现夸页面返回)(非必传)
* @param animate (是否有动画效果(暂时没有实现无动画的效果))(非必传)
* @param type type (如果push方法type传present,那么这里一定要传dismiss,其它时候可以不传)(非必传)
*/
this.$navigator.back({param:{name:11},pageId:'111',animate:true,'pop'})
3.获取上一个页面传来的参数
let param=this.$navigator.param()
4.设置页面id(跨页面返回时要用)
this.$navigator.setPageId('pageA')
在后面的页面中像这样直接返回到A
this.$navigator.back({pageId:'pageA'})
$http(网络请求)
http请求
/**
* http 请求的方法,包含post,get,json三种
* @param url 地址
* @param param 参数
* @param method 方法(post,get,json)
* @param header 请求头
* @param start 请求开始事件
* @param success 请求成功事件
* @param compelete 请求完成事件
* @param exception 请求异常事件
*/
let p={}
p.url='http:xxx/login.do'
p.param={name:'',pass:''}
p.method='post'
p.header={token:'xxxx'}
p.start=()=>{
//请求开始,可以在这展示loading框
}
p.compelete=()=>{
//请求结束,可以在这隐藏loading框
}
p.exception=()=>{
//请求异常,可以在做异常处理
}
this.$http.fetch(p,(res)=>{
//请求成功
})
文件上传
/**
* 上传文件,web中无法使用
* @param url 上传地址
* @param param //非文件类的参数
* @param header //请求头
* @param path //文件的磁盘地址,sdcard:打头的路径,拍照或者从相册选择后都会返回
* @param start //请求开始事件
* @param success 请求成功事件
* @param compelete 请求完成事件
* @param exception 请请求异常事件
*/
let p={}
p.url='http:xxx/upload.do'
p.param={name:'',pass:''}
p.path={file1:'xxxx.png',file2:'xxxx.png'}
p.method='post'
p.header={token:'xxxx'}
this.$http.upload(p,(res)=>{
})
$sessionStorage(内存存储)
将键值对存在内存中,app关闭后或者网站关闭后自动清除
let value=''//可以是任意类型,存进去是什么类型,取出来就是什么类型无需转换
this.$sessionStorage.set('key1',value)
let v= this.$sessionStorage.get('key1')
//清除键值对
this.$sessionStorage.remove('key1')
$localStorage(磁盘存储)
let value=''//可以是任意类型,存进去是什么类型,取出来就是什么类型无需转换
this.$localStorage.set('key1',value)
let v= this.$localStorage.get('key1')
//清除键值对
this.$localStorage.remove('key1')
$eventBus(跨页面通信)
此模块用于跨页面通信,在A页面注册这样一个事件,在其它任何页面均可触发,例如登录之后,触发相关页面的数据刷新
// 注册
this.$eventBus.regist('key1',(params)=>{
//do something
})
// 触发
this.$eventBus.send('key1',{name:'123'})
$photo(相机相册)
相机相册最常用的一个原生模块,用于获取照片,视频,从相册选或者用相机拍
/**
*
* @param action:camera 相机 ;choose:相册
* @param type:video 视频 ;photo:图片
* @param aspX:裁剪宽度(非必传)
* @param aspY:裁剪高度 (非必传)
* @param maxSize:压缩大小,单位byte
* @param callback 回调
*/
let p={}
// p.action='choose' //相册
p.action='camera' //相机
p.type='photo'
//这两个值不传则不会出现裁剪框
p.aspX=500
p.aspY=500
p.maxSize=1023*1024 //单位byte
this.$photo.open(p,(res)=>{
let ary=res.res
ary.forEach((item)=>{
let path= item.path //图片路径
})
})
生命周期
onLoad
页面加载完成时触发,只会触发一次
该方法有一个参数 ,是从上一个页面传递过来的参数
onShow
页面重新显示时触发,例如从A跳转到B,在从B回到A,这时会触发A页面的onShow
onHide
页面离开时触发,例如从A跳转到B,这时会触发A页面的onHide
onUnload
页面销毁前触发,请勿执行耗时的操作
<template>
<page title="页面的生命周期">
</page>
</template>
<script>
export default {
props: {},
data() {
return {}
},
methods: {
onLoad(param) {
//页面加载完成时触发,只会触发一次
//param 是从上一个页面传递过来的参数
},
onShow() {
//页面重新显示时触发,例如从A到B,在从B回到A,这时会触发A页面的onShow
},
onHide() {
//页面离开时触发
},
onUnload() {
//页面销毁前触发,请勿执行耗时的操作
}
},
created() {
}
}
</script>
<style scoped>
</style>
资源访问
请将所有的资源放在assets文件中
默认已有图片img,字体font和文件file的分类
所有assets中的资源均可通过root:写法访问到
图片使用
<image src="root:img/log.png"></image>
字体使用
注册字体
const font = weex.requireModule('font')
font.addFont('nj','root:font/iconfont.ttf')
其它文件类的访问
以web访问本地静态文件为例
<web src="root:file/index.html"></web>
appBoard(全局引入)
weex官方没有提供这样的机制,着实不方便
src/mixin/main.js在此js全局注册组件,全局对象
可以避免所有页面都要单独注册组件的繁琐,也能减少总的js包体积
例如一个button组件有100kb,原来有100个页面都注册了,那么总体积是100x100=10000kb
现在放在appBoard中注册,仅需注册一次,体积减少99x100=9900kb
需要注意的是,以上是针对将包放在本地的情况,如果将js部署在服务端,那么js的总体积将不再重要
反而单个js的体积要越小越好,如果什么都往appboard
中注册,则会造成将很多非本页面的代码也打进了这个页面,造成单个页面js过大
所以针对部署情况,需要按以下标准来
- 部署在服务端,则页面按需引用注册组件
- 部署在app内部,则将尽可能多的组件在appBoard中注册
WEEXPLUS-UI
weexplus已经为大家内置了一套三端适配的vue组件
创建项目已自带了一套tab模板,方便大家快速开发
以下组件均在src/component下面,大家可以自行改造
并且已在src/mixin/main.js中全局注册,无需每个页面再单独注册
<head>
已适配刘海屏
<template>
<div style="flex: 1;width: 750px">
<head title="标题" :hasBackBtn="true" ></head>
<div style="flex: 1;display: flex;width: 750px">
</div>
</div>
</template>
<script>
export default {
component:{},
props: {
},
data() {
return {}
},
methods: {
},
created() {
}
}
</script>
<style scoped>
</style>
<page>
建议将所有的页面用page做根元素
<template>
<page title="首页" :hasBackBtn="false">
<div class="layout" >
<image class="img" src="root:img/logo.png" ></image>
<text class="text">欢迎使用weexplus!</text>
</div>
</page>
</template>
<script>
export default{
data(){
return {
}
},
props: {},
methods: {
onLoad(px){
//页面加载完成
},
onShow(){
//页面展示
},
onUnload(){
//页面卸载
},
onHide(){
//页面隐藏
},
},
created(){
}
}
</script>
<style scoped>
.layout{
align-items: center;
background-color: #ffffff;
justify-content: center;
flex: 1;
}
.img{
width: 200px;
height: 200px;
margin-top: -100px;
}
.text{
color: black;
margin-top: 30px;
font-size: 70px;
font-weight: bold;
}
</style>
<tabHost>
最佳的tab组件实践
<template>
<tabHost :items="items">
</tabHost>
</template>
<script>
export default {
props: {},
data() {
return {
items: [
{text: '首页', normalImg: '', selectImg: '',component:require('./tab/tab1.vue')},
{text: '新闻', normalImg: '', selectImg: '',component:require('./tab/tab2.vue')},
{text: '我的', normalImg: '', selectImg: '',component:require('./tab/tab3.vue')},
],
index: 0
}
},
methods: {
onLoad(param) {
},
onShow() {
},
onHide() {
},
onUnload() {
},
registFont(){
const font = weex.requireModule('font')
font.addFont('nj','root:font/iconfont.ttf')
}
},
mounted(){
// this.$refs.host.components={tab1,tab2,tab3}
// debugger
// this.log(JSON.stringify(this.components))
},
created() {
this.registFont()
}
}
</script>
<style scoped>
.full {
position: absolute;
top: 0;
bottom: 0;
right: 0;
left: 0;
width: 750px;
}
</style>