http://localhost:8081/index.android.bundle?platform=android
1.环境配置
1.下载安装node
检验安装成功:
node -v
2.在cmd中安装npm
检验安装成功:
npm -v
3.下载git并安装
检验安装成功:git -v
4.在cmd中安装webpack:安装命令:npm install webpack -g
检验安装成功:webpack -v
2.创建weex项目
1.使用命令weex -v先检查是否安装了weex
2.使用命令weex create firstWeexDemo(firstWeexDemo是工程名,自定义)注意的是:在接下来创建工程名时不要出现大写字母,否则会创建失败
3.创建完成之后,使用命令 npm install安装npm解析器
4.安装完成之后先cd到创建完成的工程目录在使用命令weex platform add android将创建的工程加入android项目平台
5.打开androidStudio->选择打开一个已经存在的工程->选择platform下的andriod目录导入
6.导入完成之后,添加虚拟设备,create virtual device 创建对应的屏幕尺寸等
3.weex常用命令和热更新
1.先将创建好的工程拉入vscode
2.打开package.json,进入cmd 先cd到创建的目录之下,使用命令npm run dev命令运行项目文件
3.在打开一个终端,输入npm run serve,如果配置没有问题就会自己跳转到浏览器界面
4.weex支持热更新,所以在src/index.vue中改变,但是页面并不会随之改变
5.在打开一个终端,使用webpack进行打包,打完包之后就可以随时进行热更新了 注:如果之前没有安装webpack,还需要根据提示安装webpack-cli脚手架
注:每次更改完成之后,都要记得使用webpack打包到dist目录下(每次会自动打包到dist目录下),才能实现实时的页面更新
但是添加监控之后,只要刷新界面就会起到更新作用:
监控设置:在package.json文件中build改为这种: "build": "webpack --env.NODE_ENV=common",
4.Android Studio 开发设置以及weex init创建一个前端使用的weex项目
1.每次启动之前应该先开启两个服务:一个是npm run build(用于开启打包的监控服务)
npm run serve(用于在浏览器界面运行项目)
2.实时预览的浏览地址:http://192.168.239.1:8082/webpack-dev-server/web/
3.先在vscode中将dist目录下的index.js的内容copy到androidStudio中的app目录下的assets下的index.js中(注:如果有两个index.js,那就全部都copy)
4.更改应用图标:在androidStudio中,res/mipmap下就存放着图标
5.打包生成apk文件,build->Build Bundles/apk->bulid apk
如果打包成功,就会出现打包成功的提示,如果失败,就按照提示进行修改
6.weex init 创建的project主要用于前端人员的开发
weex create 创建的项目主要用于专门开发架构的人员进行开发
7.先切换到创建工程对应的目录,使用weex init projectName创建一个工程
8.创建完成之后,cd到新创建的工程目录,在进行npm install
9.把创建的项目使用vscode打开
10.使用指令 npm run serve打开对应的项目页面
5.weex和vue之间的联系
weex与vue之间的不同:
1.布局不同:在html或者Vue中我们可以使用浮动布局,但是weex并不支持,所以请不要使用。
2.不支持百分数:html中布局,经常使用百分比进行布局,这种布局可以适应不同屏幕,但是你用weex布局时百分比是不支持的。
3.不支持综合写法:比如html中支持border:1px solid red;但是weex就不支持
4.weex的像素只支持px,不支持em rem pt
6.自定义组件和Text组件
1.在src目录下先创建一个vue,里面用于写你自定义的内容
自定义的vue内容:
<!--html-->
<template>
<!--最外层必须用div包裹-->
<div class="topHeader">
<!--文字必须用text包裹-->
<text class="top_text">你好,weex</text>
</div>
</template>
<!--js-->
<script>
export default {
}
</script>
<!--css-->
<style scoped>
.topHeader{
background-color: red;
padding: 10px;
}
.top_text{
color: #fff;
font-size: 46px;
text-align: center;
lines:1;
}
</style>
在显示的主页面(index.vue)引用:
在<script></script>中进行引用:import topHeader from './topHeader.vue';
在<script></script>中定义一个components,并且进行声明:
components:{
topHeader
}
定义完成之后就可以直接在template中定义使用了
下面讲一下text组件:注:只有weex可以使用text组件: 详情参考此网址:https://weex.apache.org/cn/references/components/text.html
在css样式中定义lines属性:lines=n,那么引用这个css样式之后的text中的内容就以n行显示 注:lines只能在css样式中定义
7.Input组件和初识内建模块
1.注意点一:
我们在weex中<input />标签必须写成闭合形式,如果不闭合在手机或者模拟器中是渲染不出来的,会一直显示加载。
2.使用init创建的工程打包方式:
使用命令:npm run build会在dist目录下生成两个文件:生成的两个文件名字会在最后提示,将index.web.js中的文件打开复制粘贴到androidStudio打开
的文件assets/index.js文件中(注意是直接复制替换)
下面讲一下内建模块:
在主页面index.vue的<script>部分声明对内建模块的定义:
var modal=weex.requireModule("modal");//参数必须是model
接下来定义内建模块的声明周期:
created(){
modal.toast({
message:'页面初始化成功',//用于提醒的字段
duration:3//内建模块持续的秒数
});
}
8.Image和video组件
1.image组件及其对应的属性:
<template></template>内容:
<!--resize="stretch":重新定义图片尺寸,其中resize属性有:stretch默认值,指定图片按照容器拉伸,有可能使图片产生形变。
cover:指定图片可以被调整到容器,以使图片完全覆盖背景区域,图片有可能被剪裁。
contain:指定可以不用考虑容器的大小,把图像扩展至最大尺寸,以使其宽度和高度完全适应内容区域。
-->
<image class="testImage" resize="cover"
src="https://img-blog.csdnimg.cn/2022010617505325844.jpeg"></image>
对应的<script></script>内容:无;
对应的<style></style>内容:
.testImage{
/*
720px=100%
1250px=100%
*/
width:720px;
height:300px;
}
注:image是weex独有的属性
2.video组件:
<template></template>内容:
<video class="video" :src="src" autoplay controls
v-on:start="onstart" v-on:pause="onpause" v-on:finish="onfinish" v-on:fail="onfail"></video>
<script></script>中的内容:
export default {
name: 'App',
data () {
return {
src:'https://www.youtube.com/watch?v=wn12uL6pYIc'
}
},
methods:{
onstart (event) {
this.state = 'onstart'
},
onpause (event) {
this.state = 'onpause'
},
onfinish (event) {
this.state = 'onfinish'
},
onfail (event) {
this.state = 'onfinish'
}
}
对应的<style></style>样式:
.video {
width: 630px;
height: 350px;
margin-top: 60px;
margin-left: 60px;
}
所有的代码:
<template>
<div >
<text class="text">Hello Word</text>
<div>
<input type="text" placeholder="输入姓名" class="textInput" :autofocus=true />
</div>
<!--resize="stretch":重新定义图片尺寸,其中resize属性有:stretch是让图片按照容器的尺寸进行拉伸
cover:以中间为基准进行裁切
contain:不用考虑容器尺寸,直接显示图片能够显示的最大尺寸
-->
<image class="testImage" resize="cover"
src="https://img-blog.csdnimg.cn/2022010617505325844.jpeg"></image>
<video class="video" :src="src" autoplay controls
v-on:start="onstart" v-on:pause="onpause" v-on:finish="onfinish" v-on:fail="onfail"></video>
</div>
</template>
<script>
import topHeader from './topHeader.vue';
var modal=weex.requireModule("modal");//参数必须是model
export default {
name: 'App',
data () {
return {
logo:
'data:image/jpeg;base64,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',
src:'https://www.youtube.com/watch?v=wn12uL6pYIc'
}
},
components:{
topHeader
},
created(){
modal.toast({
message:'页面初始化成功',//用于提醒的字段
duration:3//内建模块持续的秒数
});
},
methods:{
onstart (event) {
this.state = 'onstart'
},
onpause (event) {
this.state = 'onpause'
},
onfinish (event) {
this.state = 'onfinish'
},
onfail (event) {
this.state = 'onfinish'
}
}
}
</script>
<style scoped>
.wrapper {
justify-content: center;
align-items: center;
}
.logo {
width: 424px;
height: 200px;
}
.greeting {
text-align: center;
font-size: 50px;
color: #41B883;
background: rgb(90, 114, 1)
}
.message {
margin: 30px;
font-size: 32px;
color: #727272;
}
.text{
text-align:center;
}
.textInput{
border-bottom-width:1px;
}
.testImage{
/*
720px=100%
1250px=100%
*/
width:720px;
height:300px;
}
.video {
width: 630px;
height: 350px;
margin-top: 60px;
margin-left: 60px;
}
</style>
9.制作列表
1.先看一下loadmore组件的功能代码:用于上拉加载
<template>
<div >
<!--list相当于html中的ul
ceil相当于html中的li
注:list和ceil都不能进行样式的编写
-------------------------------------------------------------------------------------------------------------------
loadmore:在移动端中上拉加载是经常使用的一个功能,weex中要实现这个功能需要使用一个loadmore属性,从英文单词中可以看出,
就是加载更多的意思。我们在中加入loadmore属性,并绑定一个fetch方法
注:loadmore必须写在list里面,要不然就不起作用
loadmoreoffset:是加载列偏移的意思
-->
<list v-on:loadmore="fetch" loadmoreoffset="10">
<cell v-for="rum in lists">
<!--weex要想遍历数组,必须使用text,但是text组件应该单独放在div中-->
<div class="panel">
<text class="text">{{rum}}</text>
</div>
</cell>
</list>
</div>
</template>
<script>
//声明一个内联模块
var modal=weex.requireModule("modal");//参数必须是model
export default {
data () {
return {
lists:[1,2,3,4,5]
}
},
methods:{
//fetch(event):用于检测所有的事件
fetch(event){
/*使用内联模块
duration:1 1:指的是1秒
*/
modal.toast({message:'loadmore',duration:1});
/*用于实现模拟下拉菜单的功能
setTimeout方法解析:包含function delay code
(注:code 这是一个替代语法,你可以使用字符串代替function ,在delay毫秒之后执行字符串
(使用该语法是不推荐的, 原因和使用 eval()一样,有安全风险)。)
function 是你想要在delay毫秒之后执行的函数(function这个单词不一定要显示出来,不写function 直接写函数体也行)
延迟的毫秒数 (一秒等于1000毫秒),函数的调用会在该延迟之后发生。如果省略该参数,delay取默认值0。实际的延迟时间可能会比 delay 值长
*/
setTimeout(()=>{
const length = this.lists.length;
for(let i=length;i<length+4;i++){
//给数组lists不停地添加新元素
this.lists.push(i+1);
}
},800);//此处的800指的是毫秒
}
}
}
</script>
<style scoped>
.panel{
width:600px;
height:250px;
margin-left:75px;
margin-top:35px;
margin-bottom:35px;
flex-direction: column;
justify-content: center;
border-width: 2px;
border-style: solid;
border-color:rgb(162,217,192);
background-color:rgba(162, 217, 192, 0.2)
}
.text{
font-size:50px;
text-align: center;
color:#41B883;
}
</style>
2.loading组件的使用:用于下拉加载的组件
<loading>组件 要使用<loading>组件你需要先去<list>组件上的loadmore和loadmoreoffset属性,并在list中加入<loading>组件
代码详情:
<template>
<div>
<list>
<cell v-for="rum in lists">
<div class="panel">
<text class="text">{{rum}}</text>
</div>
</cell>
<!--loading必须写在list里面
display:用于设置显示loading
-->
<loading class="loading" v-on:loading="onloading" :display="showLoading">
<text class="indicator">Loading...</text>
</loading>
</list>
</div>
</template>
<script>
//声明一个内联模块
var modal=weex.requireModule("modal");//参数必须是model
export default {
data () {
return {
lists:[1,2,3,4,5]
}
},
methods:{
onloading(event) {
modal.toast({ message: 'loading', duration: 1 });
//用于设置loading是否显示
this.showLoading = 'show';
setTimeout(() => {
const length = this.lists.length;
for (let i = length; i < length + 4; i++) {
this.lists.push(i + 1);
}
//每次加载完之后就让loading消失,否则loading就会一直进行
this.showLoading = 'hide';
}, 1500)
}
}
}
</script>
<style scoped>
.panel{
width:600px;
height:250px;
margin-left:75px;
margin-top:35px;
margin-bottom:35px;
flex-direction: column;
justify-content: center;
border-width: 2px;
border-style: solid;
border-color:rgb(162,217,192);
background-color:rgba(162, 217, 192, 0.2)
}
.text{
font-size:50px;
text-align: center;
color:#41B883;
}
</style>
3.<refresh>组件
实际开发中还需要刷新页面,weex在列表中也为我们想好了,提供了 <refresh>组件,它的作用就是在上拉时进行刷新页面
<template>
<div>
<!--refresh:用于粗略的刷新监控界面
pullingdown:能够细致的监控界面,能够返回你下拉了多少像素
-->
<refresh class="refresh" v-on:refresh="onrefresh" v-on:pullingdown="onpullingdown" :display="refreshing">
<text class="indicator">Refreshing ...</text>
</refresh>
<list>
<cell v-for="rum in lists">
<div class="panel">
<text class="text">{{rum}}</text>
</div>
</cell>
<!--loading必须写在list里面
display:用于设置显示loading
-->
<loading class="loading" v-on:loading="onloading" :display="showLoading">
<text class="indicator">Loading...</text>
</loading>
</list>
</div>
</template>
<script>
//声明一个内联模块
var modal = weex.requireModule("modal"); //参数必须是model
export default {
data() {
return {
lists: [1, 2, 3, 4, 5],
showLoading: "hide",
refreshing: "hide"
};
},
methods: {
//下拉加载
onloading(event) {
modal.toast({ message: "loading", duration: 1 });
//用于设置loading是否显示
this.showLoading = "show";
setTimeout(() => {
const length = this.lists.length;
for (let i = length; i < length + 4; i++) {
this.lists.push(i + 1);
}
//每次加载完之后就让loading消失,否则loading就会一直进行
this.showLoading = "hide";
}, 1500);
},
onrefresh(event) {
modal.toast({ message: "refresh", duration: 1 });
this.refreshing = "show";
setTimeout(() => {
this.lists = [1, 2, 3, 4, 5];
this.refreshing = "hide";
}, 2000);
},
onpullingdown(event) {
modal.toast({ message: "pulling down", duration: 1 });
}
}
};
</script>
<style scoped>
.panel {
width: 600px;
height: 250px;
margin-left: 75px;
margin-top: 35px;
margin-bottom: 35px;
flex-direction: column;
justify-content: center;
border-width: 2px;
border-style: solid;
border-color: rgb(162, 217, 192);
background-color: rgba(162, 217, 192, 0.2);
}
.text {
font-size: 50px;
text-align: center;
color: #41b883;
}
</style>
10.从后端服务器上获取数据
1.stream的引入
要想使用stream,必须使用weex来进行引入。
stream.fetch(options, callback[,progressCallback]):
options {Object}:请求的一些选项 包含:
method {string}:HTTP 方法 GET 或是 POST
url {string}:请求的 URL
headers {Object}:HTTP 请求头
type {string}:响应类型, json,text 或是 jsonp {在原生实现中其实与 json 相同)
body {string}:HTTP 请求体。
注意:
body 参数仅支持 string 类型的参数,请勿直接传递 JSON,必须先将其转为字符串。
GET 请求不支持 body 方式传递参数,请使用 url 传参。
callback:回调函数
测试代码:
<template>
<div>
<list>
<cell v-for="news in lists">
<div class="panel">
<text class="text">{{news.newsTitle}}</text>
<text class="content">{{news.newsContent}}</text>
<text class="content">{{news}}</text>
</div>
<div class="panel">
<text class="title">method = GET</text>
<text class="count">{{getResult}}</text>
</div>
</cell>
</list>
</div>
</template>
<script>
const modal = weex.requireModule('modal');
//要想使用stream,必须使用weex来进行引入stream模块。stream主要是用于接收json字符串
const stream = weex.requireModule('stream');
export default {
data() {
return {
lists: [],
}
},
/*钩子函数------在组件实例化完成之后就会执行这个函数,但是页面还未显示
组件实例化之前先请求json数据
*/
created(){
let url='http://jsfiddle.net/echo/jsonp/?callback=anything&result=content_in_response';
//调用getNews方法
this.getNews(url,res=>{
modal.toast({message:'请求成功',duration:1});
//把获取的data数据赋值给lists
this.lists=res.data;
console.log("jsonData="+res.data);
});
},
methods: {
getNews(url,callback){
//此处是stream的fetch方法
return stream.fetch({
//使用get的方式请求
method:'GET',
//请求的数据是json格式
type:'json',
url:url
//callback是回调函数,也就是请求之后调用的函数
},callback);
}
}
}
</script>
<style scoped>
.panel {
width: 650px;
height: 250px;
margin-left: 50px;
margin-top: 35px;
margin-bottom: 35px;
flex-direction: column;
padding-top:15px;
padding-left:10px;
padding-right:10px;
border-width: 2px;
border-style: solid;
border-color: rgb(162, 217, 192);
background-color: rgba(162, 217, 192, 0.2)
}
.text {
font-size: 36px;
text-align: center;
color: #41B883;
}
.content{
lines:5;
font-size: 28px;
}
</style>
详细的stream使用代码:
<template>
<scroller>
<div class="panel">
<text class="title">method = GET</text>
<text class="content">{{getResult}}</text>
</div>
<div class="panel">
<text class="title">method = GET / type = jsonp</text>
<text class="content">{{getJsonpResult}}</text>
</div>
<div class="panel">
<text class="title">method = POST</text>
<text class="content">{{postResult}}</text>
</div>
<div class="panel">
<text class="title">method = PUT</text>
<text class="content">{{putResult}}</text>
</div>
<div class="panel">
<text class="title">method = DELETE</text>
<text class="content">{{deleteResult}}</text>
</div>
<div class="panel">
<text class="title">method = HEAD</text>
<text class="content">{{headResult}}</text>
</div>
<div class="panel">
<text class="title">method = PATCH</text>
<text class="content">{{patchResult}}</text>
</div>
</scroller>
</template>
<script>
var stream = weex.requireModule('stream');
module.exports = {
data: function () {
return {
getJsonpResult: 'loading...',
getResult: 'loading...',
postResult: 'loading...',
putResult: 'loading...',
deleteResult: 'loading...',
headResult: 'loading...',
patchResult: 'loading...'
}
},
created: function() {
var me = this;
var GET_URL_JSONP = 'http://jsfiddle.net/echo/jsonp/?callback=anything&result=content_in_response';
var GET_URL = 'http://httpbin.org/get';
var POST_URL = 'http://httpbin.org/post';
var PUT_URL = 'http://httpbin.org/put';
var DELETE_URL = 'http://httpbin.org/delete';
var HEAD_URL = 'http://httpbin.org/status/418';
var PATCH_URL = 'http://httpbin.org/patch';
stream.fetch({
method: 'GET',
url: GET_URL_JSONP,
type:'jsonp'
}, function(ret) {
if(!ret.ok){
me.getJsonpResult = "request failed";
}else{
console.log('get:'+ret);
me.getJsonpResult = JSON.stringify(ret.data);
}
},function(response){
console.log('get jsonp in progress:'+response.length);
me.getJsonpResult = "bytes received:"+response.length;
});
stream.fetch({
method: 'GET',
url: GET_URL,
type:'json'
}, function(ret) {
if(!ret.ok){
me.getResult = "request failed";
}else{
console.log('get:'+ret);
me.getResult = JSON.stringify(ret.data);
}
},function(response){
console.log('get in progress:'+response.length);
me.getResult = "bytes received:"+response.length;
});
stream.fetch({
method: 'POST',
url: POST_URL,
type:'json'
}, function(ret) {
if(!ret.ok){
me.postResult = "request failed";
}else{
console.log('get:'+JSON.stringify(ret));
me.postResult = JSON.stringify(ret.data);
}
},function(response){
console.log('get in progress:'+response.length);
me.postResult = "bytes received:"+response.length;
});
stream.fetch({
method: 'PUT',
url: PUT_URL,
type:'json'
}, function(ret) {
if(!ret.ok){
me.putResult = "request failed";
}else{
console.log('get:'+JSON.stringify(ret));
me.putResult = JSON.stringify(ret.data);
}
},function(response){
console.log('get in progress:'+response.length);
me.putResult = "bytes received:"+response.length;
});
stream.fetch({
method: 'DELETE',
url: DELETE_URL,
type:'json'
}, function(ret) {
if(!ret.ok){
me.deleteResult = "request failed";
}else{
console.log('get:'+JSON.stringify(ret));
me.deleteResult = JSON.stringify(ret.data);
}
},function(response){
console.log('get in progress:'+response.length);
me.deleteResult = "bytes received:"+response.length;
});
stream.fetch({
method: 'HEAD',
url: HEAD_URL,
type:'json'
}, function(ret) {
if(ret.statusText !== 'I\'m a teapot'){
me.headResult = "request failed";
}else{
console.log('get:'+JSON.stringify(ret));
me.headResult = ret.statusText;
}
},function(response){
console.log('get in progress:'+response.length);
me.headResult = "bytes received:"+response.length;
});
stream.fetch({
method: 'PATCH',
url: PATCH_URL,
type:'json'
}, function(ret) {
if(!ret.ok){
me.patchResult = "request failed";
}else{
console.log('get:'+JSON.stringify(ret));
me.patchResult = JSON.stringify(ret.data);
}
},function(response){
console.log('get in progress:'+response.length);
me.patchResult = "bytes received:"+response.length;
});
}
};
</script>
<style scoped>
.panel {
width: 650px;
height: 250px;
margin-left: 50px;
margin-top: 35px;
margin-bottom: 35px;
flex-direction: column;
padding-top:15px;
padding-left:10px;
padding-right:10px;
border-width: 2px;
border-style: solid;
border-color: rgb(162, 217, 192);
background-color: rgba(162, 217, 192, 0.2)
}
.text {
font-size: 36px;
text-align: center;
color: #41B883;
}
.content{
lines:5;
font-size: 28px;
}
</style>
11.作轮播图片效果
<template>
<div>
<!--
slider:是实现轮滑的组件,这个是weex的内置组件
interval:以毫秒为单位,表示多久更换一次图片 但是要想使用自动轮播,必须配合另一个属性auto-play
auto-play是自动播放,设置为true就可以实现自动播放
infinite:用于循环播放,默认值为true
indicator:是slider的子组件,用于显示书签效果 必须充当 组件的子组件使用
-->
<slider class="slider" interval="3000" auto-play="true" infinite="true">
<div class="frame" v-for="img in imageList">
<image class="image" resize="cover" :src="img.src"></image>
</div>
<!--由于indicator是slider的子组件,绝对不允许写在div中-->
<indicator class="indicator"></indicator>
</slider>
</div>
</template>
<script>
export default {
data () {
return {
imageList: [
{ src: 'https://gd2.alicdn.com/bao/uploaded/i2/T14H1LFwBcXXXXXXXX_!!0-item_pic.jpg'},
{ src: 'https://gd1.alicdn.com/bao/uploaded/i1/TB1PXJCJFXXXXciXFXXXXXXXXXX_!!0-item_pic.jpg'},
{ src: 'https://gd3.alicdn.com/bao/uploaded/i3/TB1x6hYLXXXXXazXVXXXXXXXXXX_!!0-item_pic.jpg'}
]
}
}
}
</script>
<style scoped>
.image {
width: 700px;
height: 700px;
}
.slider {
margin-top: 25px;
margin-left: 25px;
width: 700px;
height: 700px;
border-width: 2px;
border-style: solid;
border-color: #41B883;
}
.frame {
width: 700px;
height: 700px;
position: relative;
}
.indicator{
height:700px ;
width:700px ;
/*
item-color:是indicator独有的样式,它是用于定义书签圆点的颜色
item-selected-color:是indicator独有的样式,它是用于设置被选中时的颜色
*/
item-color:#ffff;
item-selected-color:red;
/*
此处的设置是用于设置真实的运行时圆点标签的产生效果
*/
position: absolute;
}
</style>
12.a组件和web组件
使用<a>组件时需要和我们html中的<a>标签区分,html中的<a>标签是用来链接html页面的,而weex中的<a>组件是用来链接weex格式的js文件的
判断是否可以访问到你所创建的文件:
先cd到创建的目录之下,使用命令ipconfig查看ipv4的地址
比如我的是192.168.239.1
后面添加端口号8080或者8081等。
访问地址http://192.168.239.1:8081/slider.js(slider.js就是你要判断是否可以访问的文件)
如果可以访问那么就会显示这个文件里面的内容,如果未显示,说明不能进行访问
index.vue中的主要代码如下:
<template>
<div class="wrapper">
<!--href如果是要访问连接,必须把地址路径写完整-->
<a class="button" href="http://192.168.239.1:8081/slider.js">
<text class="text">跳转轮播图</text>
</a>
</div>
</template>
下面讲一下web组件 在原生的软件中嵌入网站页面
<template>
<div class="wrapper">
<!--直接引用web组件,在原生的软件中嵌入网站页面
pagestart:<web>组件开始加载时此事件触发。
pagefinish:<web>组件完成加载时此事件触发。
error:如果<web>组件出现错误,会发送此事件消息。
-->
<web src="https://www.baidu.com/" class="web" v-on:pagestart="start" v-on:pagefinish="finish" v-on:error="error"></web>
</div>
</template>
<script>
/*使用声明周期----钩子函数
先定义一个modal
*/
const modal = weex.requireModule("modal");
export default {
data() {
return {};
},
methods: {
start() {
modal.toast({
message: "页面开始调用", //用于提醒的字段
duration: 3 //内建模块持续的秒数
});
},
finish() {
modal.toast({
message: "页面结束调用", //用于提醒的字段
duration: 3 //内建模块持续的秒数
});
},
error() {
modal.toast({
message: "页面调用错误", //用于提醒的字段
duration: 3 //内建模块持续的秒数
});
}
}
};
</script>
<style scoped>
.wrapper {
flex-direction: column;
justify-content: center;
}
.web {
margin-left: 75px;
width: 600px;
height: 750px;
border-width: 2px;
border-style: solid;
border-color: #41b883;
}
</style>
13.通用事件和动画模块
1.先描述一些常见的事件:
<1>longpress(长按事件):如果一个组件被绑定了 longpress 事件,那么当用户长按这个组件时,该事件将会被触发。
<2>Appear(屏幕内事件):如果一个位于某个可滚动区域内的组件被绑定了 appear 事件,那么当这个组件的状态变为在屏幕上可见时,
该事件将被触发。
<3>Disappear(屏幕外事件):如果一个位于某个可滚动区域内的组件被绑定了 disappear 事件,
那么当这个组件被滑出屏幕变为不可见状态时,该事件将被触发。
2.动画效果:
<template>
<div class="wrapper">
<!--ref:ref 被用来给元素或子组件注册引用信息,引用信息将会注册在父组件的 $refs 对象上。
如果在普通的 DOM 元素上使用,引用指向的就是DOM 元素;如果用在子组件上,引用就指向组件实例。-->
<div ref="test" v-on:click="move" class="box"></div>
</div>
</template>
<script>
const modal = weex.requireModule('modal');
//引入动画模块
const animation =weex.requireModule('animation');
export default {
data () {
return {
}
},
methods:{
move () {
// 使用$refs属性可以通过test来引用和操作这个div
var testEl = this.$refs.test;
animation.transition(testEl, {
//styles样式必须加在引号里,否则就是无效
styles: {
color: '#FF0000',
//过渡方式:让动画以何种方式进行过渡,translate(250px, 100px):表示横轴移动250px,纵轴移动100px;
transform: 'translate(250px, 100px)',
//transformOrigin:移动的中心点
transformOrigin: 'center center'
},
//duration:动画进行的秒数pick(options, callback[options])
duration: 800, //ms
//timingFunction:缓动,缓动的方式有ease ease-in ease-out
timingFunction: 'ease ',
//延迟动画
delay: 1000 //ms
//此处的function是动画完成之后的回调函数
}, function () {
modal.toast({ message: 'animation finished.' ,
uration: 3 //内建模块持续的秒数
}
)
})
}
}
}
</script>
<style scoped>
.box{
width:250px;
height:250px;
background-color:#DDD;
}
</style>
14.weex的时间选取模块picker
1.pick(options1, callback {function (ret)})
options1:index {number}:默认选中的选项
items {array}:picker 数据源
textColor {color}:picker中文字的颜色
selectionColor {color}:picker中选中item的背景色
confirmTitle {string}:确认按钮的文案
cancelTitle {string}:取消按钮的文案
confirmTitleColor {color}:确认按钮的文字颜色
cancelTitleColor {color}:取消按钮的文字颜色
title {string}:对话框的标题
titleColor {color}:对话框标题的文字颜色
titleBackgroundColor {color}:对话框标题的背景色
callback {function (ret)}:执行完读取操作后的回调函数。ret {Object} 为 callback 函数的参数,
有两个属性:result {string}:结果三种类型 success, cancel, error
data {number}:选择的选项,仅成功确认时候存在。time 格式为 HH:mm, 仅成功确认的时候存在。
代码详情:
<template>
<div class="wrapper">
<div class="group">
<text class="label">Time: </text>
<text class="title">{{value}}</text>
</div>
<div class="group">
<text class="button" v-on:click="pickTime">Pick Time</text>
</div>
</div>
</template>
<script>
//引用picker组件
const picker = weex.requireModule('picker')
export default {
data () {
return {
value: ''
}
},
methods: {
pickTime () {
picker.pickTime({
value: this.value
}, event => {
//调用回调函数,如果返回的结果是success,那么说明调用pickdate成功
if (event.result === 'success') {
this.value = event.data
}
})
}
}
}
</script>
<style scoped>
.wrapper {
flex-direction: column;
justify-content: center;
}
.group {
flex-direction: row;
justify-content: center;
margin-bottom: 40px;
align-items: center;
}
.label {
font-size: 40px;
color: #888888;
}
.title {
font-size: 80px;
color: #41B883;
}
.button {
font-size: 36px;
width: 280px;
color: #41B883;
text-align: center;
padding-top: 25px;
padding-bottom: 25px;
border-width: 2px;
border-style: solid;
border-color: rgb(162, 217, 192);
background-color: rgba(162, 217, 192, 0.2);
}
</style>
15.weex的粘贴模块clipboard
1.我们可以通过 clipboard 模块的 getString()、setString() 接口从系统的粘贴板获取内容或者设置内容。
但是需要注意的是clipboard仅支持文本拷贝,而且出于安全考虑和平台限制,只支持 Android 和 iOS,不支持 html5。
下面先看一下getString(callback)功能:用于从系统粘贴板读取内容
callback 函数的参数,有两个属性:
ret.data:获取到的文本内容;
ret.result:返回状态,可能为 success 或 fail。
再看一下setString(text):用于将一段文本复制到剪切板,相当于手动复制文本。
参数text {string}:要复制到剪切板的字符串。
代码详情:
<template>
<div>
<div class="div">
<text class="text" v-on:click="onItemClick">{{message}}</text>
</div>
<div class="div">
<text class="text" v-on:click="setContent">Click to copy: {{tobecopied}}</text>
</div>
</div>
</template>
<script>
//引入clipboard模块
const clipboard = weex.requireModule('clipboard')
export default {
data () {
return {
tobecopied: 'yay!',
message: 'nothing.'
}
},
methods: {
setContent () {
clipboard.setString(this.tobecopied)
},
onItemClick () {
this.message = 'please click the next table! '
clipboard.getString(ret => {
this.message = 'text from clipboard:' + ret.data
})
}
}
}
</script>
<style scoped>
.div {
flex-direction: row;
justify-content: space-between;
align-items: center;
width: 750px;
height: 90px;
padding-left: 30px;
padding-right: 30px;
border-bottom-width: 1px;
border-style: solid;
border-color: #DDDDDD;
}
.text {
width: 750px;
height: 90px;
}
</style>
16.weex的Navigator和webview模块
1.先看一下Naviator模块:
这个就是原生系统上的前进和后退,里边的方法也很简单。只有两个方法。
push:把一个weex页面URL压入导航堆栈中,可指定在页面跳转时是否需要动画,以及操作完成后需要执行的回调函数
pop:把一个 Weex 页面 URL 弹出导航堆栈中,可指定在页面弹出时是否需要动画,以及操作完成后需要执行的回调函数。
详细代码如下:
<template>
<div class="wrapper">
<text class="button" @click="jump">Jump</text>
</div>
</template>
<script>
const modal = weex.requireModule("modal");
//引入Naviator模块
const navigator = weex.requireModule("navigator");
export default {
data() {
return {};
},
methods: {
jump(event) {
navigator.push(
{
//url是指我们要前进到哪里
url: "http://192.168.239.1:8081/slider.js",
//animated表示是否调用动画效果,为true表示开启动画效果,为false表示关闭动画效果
animated: true
},
//event是事件点击时的回调函数
event => {
modal.toast({ message: "callback:" + event ,
duration:3 //内建模块持续的秒数
});
}
);
}
}
};
</script>
<style scoped>
.wrapper {
/*
flex-direction:指定如何柔性物品被放置在所述柔性容器限定主轴线和方向(正常或反向)
row:Flex容器的主轴定义为与文本方向相同。所述主起动和主端点是一样的内容方向。
row-reverse:行为相同row但主要起点和主要点都是置换的。
column:Flex容器的主轴与块轴相同。在主启动和主结束点是一样的之前和之后的写作模式的要点。
column-reverse:行为相同,column但主开始和主要端是置换的。
*/
flex-direction: column;
justify-content: center;
}
.button {
font-size: 60px;
width: 450px;
text-align: center;
margin-top: 30px;
margin-left: 150px;
padding-top: 20px;
padding-bottom: 20px;
border-width: 2px;
border-style: solid;
color: #666666;
border-color: #dddddd;
background-color: #f5f5f5;
}
</style>
2.webview模块
webview是一系列的操作,必须和web组件配合使用。包括goback,goForward,reload。注意的是webview必须和组件共用。
它有三个方法需要我们掌握:
goBack:相当于浏览器里的后退。
goForward:相当于浏览器里的前进。
reload:刷新页面。
对应的详细代码:
<template>
<div class="wrapper">
<div class="group">
<input class="input" v-model="value" ref="input" type="url" autofocus="false"></input>
</div>
<div class="group">
<!--loadURL就是将input中输入的网址进行渲染到我们的界面中,一点击按钮就会触发loadURL事件-->
<text class="button" @click="loadURL">LoadURL</text>
<text class="button" @click="reload">reload</text>
</div>
<!--上面的LoadURL以及reload都是对web组件的操作
要使用web组件,必须搭配web,使用ref进行连接,才能使用
-->
<web ref="webview" :src="url" class="webview" @pagestart="start" @pagefinish="finish" @error="error"></web>
</div>
</template>
<script>
const webview = weex.requireModule('webview')
const modal = weex.requireModule('modal')
export default {
data () {
return {
url : 'https://m.alibaba.com',
value: 'https://m.alibaba.com'
}
},
methods: {
loadURL (event) {
this.url = this.value
modal.toast({ message: 'load url:' + this.url })
//10s钟之后就会执行setTimeout中的回调函数
setTimeout(() => {
console.log('will go back.')
modal.toast({ message: 'will go back' })
//webview组件中的回退方法
webview.goBack(this.$refs.webview)
}, 10000)//ms
},
reload (event) {
console.log('will reload webview')
modal.toast({ message: 'reload' })
webview.reload(this.$refs.webview)
},
//start finish error都是web组件中的方法
start (event) {
console.log('pagestart', event)
modal.toast({ message: 'pagestart' })
},
finish (event) {
console.log('pagefinish', event)
modal.toast({ message: 'pagefinish' })
},
error (event) {
console.log('error', event)
modal.toast({ message: 'error' })
}
}
}
</script>
<style scoped>
.group {
flex-direction: row;
justify-content: space-around;
margin-top: 20px;
}
.input {
width: 600px;
font-size: 36px;
padding-top: 15px;
padding-bottom: 15px;
border-width: 2px;
border-style: solid;
border-color: #BBBBBB;
}
.button {
width: 225px;
text-align: center;
background-color: #D3D3D3;
padding-top: 15px;
padding-bottom: 15px;
margin-bottom: 30px;
font-size: 30px;
}
.webview {
margin-left: 75px;
width: 600px;
height: 750px;
border-width: 2px;
border-style: solid;
border-color: #41B883;
}
</style>
17.weex的vue-router的使用
1.路由的三个模式:hash,history,abstract只有我们的abstract是可以使用的,其它使用都会出现问题。
router-link不能再使用 以前在写vue时,我们经常使用<router-link>标签进行连接跳转
<router-link>中的用法:
<!-- 只能在 Web 中使用,Native 环境不支持! -->
<template>
<div>
<router-link to="profile">
<text>Profile</text>
</router-link>
</div>
</template>
但是在weex当中这种形式是不可以使用的,要使用编程式导航的形式进行跳转。
<template>
<div>
<text @click="jump">Profile</text>
</div>
</template>
<script>
import router from './path/to/router'
export default {
methods: {
jump () {
router.push('profile')
}
}
}
</script>