文章目录
1.modal模块
//modal模块
var modal = weex.requireModule('modal')
1.modal.toast(options)
例:
modal.toast({
message: 'This is a toast', //展示内容
duration: 0.3 //展示时间
})
2.modal.alert()弹窗
例:
modal.alert({
message:'你的密码输入有误,请重新输入',
okTitle:'是的,谢谢'
},res=>{ //回调 注意:无参数
}
如果你使用默认的okTitle你可以这样写
modal.alert({message:'你的密码输入有误'})
modal.confirm(options,callback) //有确定或取消得弹出
例:
modal.confirm({
message:'你是美女吗',
okTitle:"是的",
cancelTitle:'差一点点'
},res=>{
if(res=="是的"){ //回调函数的参数 result 是确定按钮上的文字信息字符串
}else if (res=="差一点点"){
}
})
如果你使用系统默认的okTitle和cancelTtitle你可以这样写
3.modal.confirm({
message:'你是美女吗'
},res=>{
if(res=="Ok"){
}else if (res=="Cancle"){
}
})
//带有输入框得弹框
4.modal.prompt({
message:'请输入你的昵称',
okTitle:'确定',
cancelTitle:'取消'
},res=>{
if(res.result=='确定'){
}else if (res.result=='取消'){
}
})
2.web
//可以使用web标签引入
<web class="page" src="http://baidu.com" ref='web'></web>
注意:必须设置宽高
控制前进 后退 刷新
const webview = weex.requireModule('webview')
后退 webview.goBack(this.$refs.web)
刷新 webview.reload(this.$refs.web)
支持的事件:
appear disappear 同时支持:
页面开始加载事件(pagestart)
页面加载完成事件(pagefinish)
页面失败事件(error)
3.image
<image ref="poster" @load="onImageLoad" placeholder="" src="http://ww2.sinaimg.cn/large/006tKfTcgy1fez04i56w5j31hc0kuwhz.jpg" class="image" resize='stretch'></image>
//placeholder:占位符路径
注意:必须设置宽高
仅支持网络图片
resize属性:stretch(默认值) contain cover
//save方法 保存图片到相册
const $image = this.$refs.poster
$image.save(result => {
if (result.success) {
//成功回调
} else {
console.log(result.errorDesc)
// 失败回调
}
})
//load 图片加载事件
onImageLoad (event) {
if (event.success) {
// Do something to hanlde success
}
}
4.list列表
注意:不允许同方向的list和scroller组件相互嵌套
//子组件 cell
header (可以吸附到顶部)
refresh 下拉刷新 @refresh 下拉松手触发 @pullingdown 下拉行为触发
loading 上拉加载 @loading
事件:
laodmore:列表内容超出屏幕 下拉到底部触发的事件 @loadmore 需要设置loadmoreoffset属性>0
重置loadmore this.$refs["list"].resetLoadmore();
示例:
<template>
<div class="page">
<list class="list" ref="list" loadmoreoffset="20">
<refresh @pullingdown="pullingdown" :display="showLoading" @refresh="onrefresh" class="refresh">
<text>下拉刷新</text>
</refresh>
<cell class="cell" v-for='(item,index) in list' :key="index">
<image :src="item.src" class="poster"></image>
<text class="title">{{item.title}}</text>
</cell>
<loading @loading="onloading" :display="showLoading" class="loading">
<loading-indicator class="indicator"></loading-indicator>
<text>加载更多</text>
</loading>
</list>
</div>
</template>
<script>
export default{
data(){
return{
list:[
{src:'https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1493829745671&di=68c663b03f829420e4f37c35d95d42b6&imgtype=0&src=http%3A%2F%2Fimg2.downza.cn%2Fapple%2Fipad%2Fyyyl-332%2F2016-04-22%2F0a60729df8603efa34de212ec67564ab.png',title:"优酷视频"},
{src:'https://ss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=228407861,2241632908&fm=23&gp=0.jpg',title:'爱奇艺'},
{src:'https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=3665454193,1922651319&fm=23&gp=0.jpg',title:'腾讯视频'},
{src:'https://ss0.bdstatic.com/70cFuHSh_Q1YnxGkpoWK1HF6hhy/it/u=2924906978,3545987802&fm=23&gp=0.jpg',title:'土豆视频'},
{src:'https://ss1.bdstatic.com/70cFuXSh_Q1YnxGkpoWK1HF6hhy/it/u=1502096116,2161980529&fm=23&gp=0.jpg',title:'芒果TV'},
]
}
}
}
</script>
<style>
.poster{
width:750px;
height: 300px;
}
.title{
position:absolute;
bottom: 20px;
left:0px;
right:0px;
height: 88px;
color:white;
line-height: 88px;
text-align: center;
font-size: 40px;
background-color: rgba(0,0,0,0.5);
}
</style>
5.scroller列表
//可以使用任意子组件 除了cell
基本同list列表组件
横向滚动 使用 scroll-direction="horizontal" 和 flex-direction: row;
<scroller class="scroller" scroll-direction="horizontal" show-scrollbar="false" style="flex-direction: row;overflow-x: scroll;overflow-y: hidden;" ></scroller>
属性:show-scrollbar 是否显示滚动条 布尔值
6.slider轮播图
属性:interval:轮播时长 number(毫秒)
auto-play:自动轮播 true/false
子组件:
indicator 指示器(小圆点) :
item-color这是指示器没被选中的颜色
item-selected-color设置指示器被选中的颜色
item-size指示器的圆点大小
检测轮播到哪一张图 可以使用 @change事件 有一个event参数(默认)
<template>
<div>
<slider class="slider" interval="3000" auto-play="true">
<image :src="src" v-for='(src,index) in images' @click='click(index)' class="image"> </image>
<indicator class="indicator"></indicator>
</slider>
</div>
</template>
<script>
export default{
data(){
return{
images:['https://gd2.alicdn.com/bao/uploaded/i2/T14H1LFwBcXXXXXXXX_!!0-item_pic.jpg',
"https://gd1.alicdn.com/bao/uploaded/i1/TB1PXJCJFXXXXciXFXXXXXXXXXX_!!0-item_pic.jpg",
"https://gd3.alicdn.com/bao/uploaded/i3/TB1x6hYLXXXXXazXVXXXXXXXXXX_!!0-item_pic.jpg" ]
}
}
}
</script>
<style>
.slider{
width:750px;
height: 300px;
background-color: green;
}
.image{
width:750px;
height: 300px;
}
//需要设置绝对定位
.indicator{
position:absolute;
left:20px;
bottom:40px;
width:100px;
height: 44px;
item-color:red;
item-selected-color:green;
item-size:20px;
}
</style>
7.通用事件
clcik点击事件
appear 出现事件 给组件绑定
disappear 消失事件 给组件绑定
longpress长按事件
viewappear 给根组件 页面显示触发
viewdisappear 给根组件 页面隐藏触发
默认都携带了
target: 触发点击事件的目标组件
timestamp: 触发点击事件时的时间戳
8.switch开关
<switch class="switch" checked="true" disabled="false" @change="change"> </switch>
属性:
checked: 开关状态
disabled:禁用状态
样式无法修改
change 事件 //按钮状态改变触发
9.storage模块
const storage = weex.requireModule('storage')
//存储数据:
storage.setItem(key, value, callback)
//示例:
storage.setItem('cache',this.inputValue,res=>{
if(res.result=='success'){
// 数据缓存成功
}
})
//读取数据:
getItem(key, callback)
storage.getItem('cache',res=>{
if(res.result=='success'){
this.inputValue=res.data
}
})
//清除缓存:
removeItem(key, callback)
storage.removeItem('cache',res=>{
if(res.result=='success'){
modal.toast({message:'清除完成',duration:1})
}
})
//获取存储的键值对数量:
length(callback)
storage.length(res=>{
if(res.result='success'){
this.length = res.data
}
})
//获取存储的所有键名数组
getAllKeys(callback)
storage.getAllKeys(res=>{
if(res.result=='success'){
this.inputValue = res.data.toString()
}
})
10.布局
//必须使用flex布局 且默认flex
display:flex 设置root // 标签的子标签的布局方式为flex 弹性布局
flex-direction:column //子标签排列的方式为垂直排列
align-items: center; //子标签沿着y轴居中对齐
justify-content:flex-start //子标签的对齐方式,从开始的位置以此布局
11.dom模块
//用法:
const dom = weex.requireModule('dom')
<cell ref='item0'></cell>//静态
<cell :ref="item+'index'">//动态
const el = this.$refs.item0[0]
dom.scrollToElement(el, {}) // 默认动画true 偏移量为0
获取组件的信息
getComponentRect(ref, callback)
callback参数:
{
result: true,
size: {
bottom: 60,
height: 15,
left: 0,
right: 353,
top: 45,
width: 353
}
}
const el = this.$refs.item0[0]
const result = dom.getComponentRect(this.ref, option => {
console.log('getComponentRect:', option)
})
//示例:
<template>
<scroller scroll-direction="horizontal" style="height:500px;width:750px;flex-direction:row">
<div style="width:100px;height:100px;background-color:red;border-color:black;border-style:solid;border-width:2px" :ref="'items'+item" @click="scrollToLeft(item)" v-for="item in list" :key="item"></div>
<!-- <div :ref="item+'index'">//动态 -->
</scroller>
</template>
<script>
const dom = weex.requireModule("dom");
export default {
data() {
return {
list: [1,2,3,4,5,6,7,8,10,11,12,13,14,15,16,17,18,19,20],
};
},
mounted() {
},
methods: {
//点击向左移动
scrollToLeft(item) {
const el = this.$refs[`items${item}`][0];
console.log(el);
dom.scrollToElement(el, { offseleft: -100 });
},
},
};
</script>
<style scoped>
</style>
12.navigator模块
//把一个weex页面URL压入导航堆栈中
push({
url :"" //要压入的 Weex 页面的 URL
animated:"" //"true" 示意为页面压入时需要动画效果,"false" 则不需要,默认值为 "true"。注意,一定要是字符串类型的,千万不能写成布尔类型
}, callback(){
//回调
})
//把当前Weex页面弹出导航堆栈中
pop({
animated:"" //"true" 示意为页面压入时需要动画效果,"false" 则不需要,默认值为 "true"。注意,一定要是字符串类型的,千万不能写成布尔类型
}, callback(){
//回调
})
13.weex页面跳转传值的优雅方式
weex使用navigator进行页面跳转,这种方式是使用的url传参,刚开始使用的时候一直都是用下面这种方法传值:
navigator.push({
url: config.getWeexIp() + '/app/main.js?account=123456&name=jelly'
})
url中?后面便是携带的参数,ccount=123456&name=jelly就是代表两个参数,一个account,一个name。
在跳转后的页面通过获取url地址,便可以得到这两个值。但和android不同的是,在ios系统中,是不支持中文的,也就是说如果url是'/app/main.js?account=123456&name=杰尼',便会获取不到name数据,所以在最开始拼接url时需要encodeURIComponent方法转码,在拿到数据后在使用decodeURIComponent方法解码拿到正确的数据。
上面这种方法在需要传递的数据较少时很方便,但是实际开发中,数据往往都是一个json对象,需要传递的参数也很多,这样一来,url的拼接往往会变得很繁琐,因为需要将json对象中的数据单独一个一个提取出来传递.例:
假如有一个json对象格式如下:
data:{
account : 123456,
name : 杰尼,
}
url就会变成:
'/app/main.js?account='+data.account+'&name='+ encodeURIComponent(data.name)
获取到url地址后需要执行下面两条语句拿到数据:
account=url.account
name=decodeURIComponent(url.name) //解码
这只是两条数据,如果数据有十条以上,代码会变得很冗余,出错概率也会变大。
在写项目《XXXX》时开始思考能不能和原生Android一样,将一整个对象打包传递。之后,我找到了两个函数方法:
JSON.stringify() //将对象转换为json字符串
JSON.parse() //将json字符串转换为对象
虽然url不支持拼接对象,但是支持字符串啊,所以我可以把url写成:
'/app/main.js?data='+JSON.stringify(data)
获取数据时:
data=JSON.parse(url.data)
传递数据时,把对象转成json字符串传过去,在第二个页面获取到json字符串后,再转成对象,这样就完成了对象的传递。
需要使用account数据时,可以直接充data对象中拿:data.account
这种方法,代码量很少,同时也可以减少出错的概率,因为去除了抽取对象数据进行传递的步骤,避免出现参数名编写错误等bug。
但是仅仅这样也还不行,因为对象转成的json字符串中也是有可能出现中文的,比如data.name这个数据。所以同样需要做转码解码处理,
//最终的url:
'/app/main.js?data='+encodeURIComponent(JSON.stringify(data))
获取对象数据:
data= decodeURIComponent(JSON.parse(url.data))
整个传参过程就这两行核心代码。
作者:IAmFox
链接:https://www.jianshu.com/p/8946f202e848
14.weex左滑置顶删除事件
//封装子组件 可以直接复用
<!--列表侧滑操作组件-->
<template>
<div class="cell" :style="cell_style" ref="cell" @swipe="handleSwipe">
<slot name="cell_content" >
</slot>
<div class="rightItems" @click="itemClick(item)" v-for="item in rightItems"
:style="{backgroundColor:item.backgroundColor,width:item.width}">
<text :style="item.textStyle">{{item.text}}</text>
</div>
</div>
</template>
<script>
var animation=weex.requireModule('animation');
var modal=weex.requireModule('modal');
const domModule = weex.requireModule('dom')
export default {
name: "swip-cell",
props:{
//操作项配置
rightItems:{
default:[
{
backgroundColor:"#FF0000",
textStyle:{
color:"#ffffff",
fontSize:30
},
width:100,
text:"删除",
icon:"root:img/logo.png"
}
],
type:Array
},
//整体宽度
width:{
default:750,
type:Number,
},
},
data(){
return{
cell_style:{
width:750
},
rightItems_height:0
}
},
created(){
let self=this;
this.cell_style={width:this.width+this.getRightWidth()};
},
mounted(){
},
methods:{
handleSwipe(e){
let self=this;
let cell=this.$refs.cell.ref;
if(e.direction=='left'){
//动态获取右侧操作项的高度
this.rightItems_height=domModule
.getComponentRect(this.$refs.cell, function (res) {
self.rightItems_height=res.size.height;
});
this.move(cell,-this.getRightWidth());
}else {
this.move(cell,0);
}
},
move(ref,position){
animation.transition(ref,{
styles: {
transform:`translateX(${position})`,
},
duration: 300, //ms
timingFunction: 'ease-out',
needLayout:false,
delay: 0 //ms
},function (res) {
})
},
getRightWidth(){
let right_w=0;
this.rightItems.forEach(item=>{
right_w+=item.width;
});
return right_w;
},
itemClick(item){
let cell=this.$refs.cell.ref;
this.move(cell,0);
this.$emit("swipe_item_click",item);
}
}
}
</script>
<style scoped>
.rightItems{
align-items: center;
justify-content: center;
height: 136px!important;
/* width: 136px; */
margin-top: 10px;
}
.cell{
flex-direction: row;
/* background-color: aqua; */
}
</style>
//父组件使用
<template>
<div class="container" :style="{ height:' 100% '}">
<div style=" width: 750px;height: 40px; background-color: #f85039;"></div>
<wxc-minibar class="navBar" background-color="#f85039" @wxcMinibarLeftButtonClicked="minibarLeftButtonClick" @wxcMinibarRightButtonClicked="minibarRightButtonClick">
<div slot="middle">
<div style="flex-direction:row;align-items:center">
<text style="color:#fff;margin-right:20px;font-size:36px">消息({{5}})</text>
<div class="yuan" @click="clear">
<text class="iconfont " style="font-size:36px;color:#fff"></text>
</div>
</div>
</div>
<div slot="left">
<text class="iconfont back">返回</text>
</div>
<div slot="right">
<text class="iconfont set" @click="goSettings"></text>
</div>
</wxc-minibar>
<!-- 通知栏 -->
<div class="open">
<div style="width:31px;height:31px;margin-left:30px;">
<text class="iconfont" style="color:#F75B0C;font-size:31px"></text>
</div>
<div>
<text style="
margin-left:21px;
margin-right:50px;
font-size: 26px;
font-family: PingFang SC;
font-weight: 500;
color: #F75B0C;
line-height: 36px;" @click="toOpen">开启消息推送权限,不错过关键词提醒!</text>
</div>
<text class="toOpen" style="margin-right:29px;">去开启</text>
<text class="iconfont" style="color:#F75B0C;font-size:31px;margin-right:29px"></text>
</div>
<list>
<cell class="cell" v-for="item in list" :key="item">
<!-- <div class="devideLine"></div> -->
<swip-cell class="cellItem" width="710" @swipe_item_click="itemClick($event,item)" :rightItems="rightItems">
<div slot="cell_content" class="cell_content">
<div class="box">
<!-- 左侧盒子 -->
<div class="leftBox"></div>
<!-- 右侧盒子 -->
<div class="rightBox">
<text class="topBox" style="font-size:30px">{{item}}</text>
<text class="timeBox" style="color:#999">今天 08:11</text>
<text class="bottomBox" style="font-size:26px">长江五桥通啦</text>
<image class="miandarao" style="width:22px;height:24px;" src="https://m.mynj.cn:11100/messagepush/image/miandarao.png"></image>
</div>
</div>
<!-- <text style="font-size: 34px;">{{item}}</text> -->
</div>
</swip-cell>
<!-- <div class="devideLine"></div> -->
</cell>
</list>
<text style="margin-top:30px;margin-left:100px;font-size:40px;width:400px;height:100px" @click="$router.push('/goods')">点击进入测试页面</text>
<text style="margin-top:30px;margin-left:100px;font-size:40px;width:400px;height:100px" @click="$router.push('/operate')">点击进入详情页面</text>
<text style="margin-top:30px;margin-left:100px;font-size:40px;width:400px;height:100px" @click="$router.push('/noResult')">点击进入无消息页面</text>
</div>
</template>
<script>
import { WxcMinibar, WxcIcon } from "weex-ui";
import SwipCell from "../components/swipCell.vue";
const modal = weex.requireModule("modal");
export default {
name: "News",
components: { WxcMinibar, WxcIcon, SwipCell },
data() {
return {
list: ["aaaaaa", "vvvvvvv", "bbbbbbb"],
rightItems: [
{
backgroundColor: "#AFAFAF",
textStyle: {
color: "#ffffff",
fontSize: 26,
},
width: 136,
text: "置顶",
},
{
backgroundColor: "#FFB545",
textStyle: {
color: "#ffffff",
fontSize: 26,
},
width: 136,
text: "标为已读",
},
{
backgroundColor: "#FA6251",
textStyle: {
color: "#ffffff",
fontSize: 26,
},
width: 136,
text: "删除",
},
],
};
},
beforeCreate() {
let domModule = weex.requireModule("dom");
domModule.addRule("fontFace", {
fontFamily: "toutiao",
src:
weex.config.env == "iOS"
? "url('htttp://at.alicdn.com/t/font_2446435_fh7tj8kfb0q.woff')"
: "url('http://at.alicdn.com/t/font_2446435_fh7tj8kfb0q.ttf')",
});
},
created() {
var value = weex.config.userid;
console.log(value);
},
mounted() {},
methods: {
minibarLeftButtonClick() {},
minibarRightButtonClick() {
modal.toast({ message: "click rightButton!", duration: 1 });
},
goSettings() {
this.$router.push("/newsSettings");
},
//左滑后的点击事件
itemClick($event, item) {
if ($event.text == "置顶") {
var index = this.list.indexOf(item);
this.list.splice(index, 1);
this.list.unshift(item);
}
if ($event.text == "标为已读") {
}
if ($event.text == "删除") {
var index = this.list.indexOf(item);
this.list.splice(index, 1);
}
},
// 一键清除角标
clear() {
},
// 开启消息推送权限
toOpen() {
},
},
};
</script>
<style scoped>
.iconfont {
font-family: toutiao;
}
.back {
font-size: 30px;
color: #fff;
}
.set {
font-size: 40px;
color: #fff;
}
.navBar {
width: 750px;
height: 88px;
background-color: #f85039;
}
.yuan {
width: 40px;
height: 40px;
background-color: rgba(255, 255, 255, 0.18);
align-items: center;
justify-content: center;
border-radius: 50%;
}
.open {
width: 750px;
height: 70px;
background-color: #fefcec;
flex-direction: row;
align-items: center;
overflow: hidden;
}
.toOpen {
width: 92px;
font-size: 26px;
border-style: solid;
border-width: 1px;
border-color: #f75b0c;
border-top-left-radius: 8px;
border-top-right-radius: 8px;
border-bottom-left-radius: 8px;
border-bottom-right-radius: 8px;
padding-top: 2px;
padding-bottom: 2px;
text-align: center;
color: #f75b0c;
}
.box {
width: 750px;
height: 136px;
display: flex;
flex-direction: row;
margin-top: 10px;
position: relative;
}
.leftBox {
width: 80px;
height: 80px;
background-color: blueviolet;
margin: 30px 20px 30px 30px;
}
.timeBox {
font-size: 22px;
position: absolute;
top: 36px;
right: 29px;
}
.miandarao {
font-size: 22px;
position: absolute;
top: 80px;
right: 29px;
}
.rightBox {
width: 620px;
height: 137px;
padding: 32px 0 32px 0;
overflow: hidden;
}
.topBox {
margin-bottom: 12px;
}
</style>
15.page事件
//在created中调用页面显示事件
if(weex.config.env.platform==='web'){
this.onShow()
}
1.viewappear事件
页面显示触发
@viewappear='onShow'
2.viewdisappear事件
页面隐藏触发
@viewdisappear='onHide'
16.navigator跳转
navigator.push(
url:"", //此处移动端为js web端为html
animated:'true'
)
//返回
navigator.pop(
animated:'true'
)
新建tuils.js(三端通用)
export function getEntryUrl(name){
//如果是H5 web端
if(weex.config.env==='web'){
return './'+name+'.html'
}else{
//如果是移动端
let arr=weex.config.bundleUrl.split('/')
arr.pop() //删除 xx.html
arr.push(name+'.js') //以js结尾
return arr.join('/') //重组成完整路径
}
}
17.weex中的坑
子绝父相,超出默认隐藏,且修改无效
解决办法:父级盒子写大点
weex.config相关配置只能写在js中,不可以在结构中直接进行判断
例如:<div v-if="weex.config.env.platform==='iOS'"></div> //错误
仅支持ios与安卓,web下需要单独调用
//在created中调用页面显示事件
if(weex.config.env.platform==='web'){
this.onShow()
}
1.viewappear事件
页面显示触发
@viewappear='onShow'
2.viewdisappear事件
页面隐藏触发
@viewdisappear='onHide'
16.navigator跳转
navigator.push(
url:"", //此处移动端为js web端为html
animated:'true'
)
//返回
navigator.pop(
animated:'true'
)
新建tuils.js(三端通用)
export function getEntryUrl(name){
//如果是H5 web端
if(weex.config.env==='web'){
return './'+name+'.html'
}else{
//如果是移动端
let arr=weex.config.bundleUrl.split('/')
arr.pop() //删除 xx.html
arr.push(name+'.js') //以js结尾
return arr.join('/') //重组成完整路径
}
}
17.weex中的坑
子绝父相,超出默认隐藏,且修改无效
解决办法:父级盒子写大点
weex.config相关配置只能写在js中,不可以在结构中直接进行判断
例如:<div v-if="weex.config.env.platform==='iOS'"></div> //错误