AVM.js(-View-Model)是一个移动优先的高性能跨端框架,支持一次编写多端渲染 。它提供更趋近于原生的编程体验,通过简洁的模型来分离应用的用户界面、业务逻辑和数据模型,适合高度定制的应用开发 。
AVM前端组件化开发模式基于标准Web 组件化思想vue组件之间传值 , 提供包含虚拟DOM和的编程框架AVM.js以及多端统一编译工具,完全兼容Web 标准 , 同时兼容Vue和React语法糖编写代码,编译工具将Vue和React相关语法糖编译转换为AVM.js代码 。
有Vue和React开发经验的开发者很容易上手 。
1. 组件的定义和引用
(1) 使用STML定义一个组件/页面
STML组件兼容Vue单文件组件(SFC)规范,使用语义化的HTML模板及对象化JS风格定义组件或页面 。STML最终被编译为JS组件/页面,渲染到不同终端 。
定义组件:
【以声网组件为例 如何封装AVM组件?】// api-test.stml:{this.data.title}export default {name: 'api-test',data(){return {title: 'Hello APP'}}}.header{height: 45px;}
(2) 组件引用
// app-index.stml:import './components/api-test.stml'export default {name: 'app-index',data: function () {return {title: 'Hello APP'}}}.app {text-align: center;margin-top: 60px;}
2. 向子组件传值
向子组件传值采用props的方式,这里以一个示例来进行说明 。
定义子组件,在props里面注册一个title属性:
// api-test.stml:{title}export default {name:'api-test',props:{title: String}}
这里定义的title属性类型为vue组件之间传值 , 属性类型包括、、、Array、、等 。
(1) 在其它页面使用子组件时传递静态值:
// app-index.stml:import './components/api-test.stml'export default {name: 'app-index'}
(2) 通过数据绑定传递动态值:
// app-index.stml:import './components/api-test.stml'export default {name: 'app-index',data() {return {msg: 'Hello App!'}}}
传递静态值时只能传递字符串类型数据 , 通过数据绑定的方式则可以传递任意类型的数据 。
3. 监听子组件事件
监听子组件事件和监听普通事件类似,如:
// api-index.stml:import './components/api-test.stml'export default {name: 'app-index',methods: {onGetResult(e){console.log(e.detail.msg);}}}
以上示例中监听了子组件的事件,子组件里面通过fire方法来触发监听的事件:
// app-test.stml:Hello App!export default {name:'api-test',methods:{onclick(){let detail = {msg:'Hi'};this.fire('result', detail);}}}
fire方法有两个参数,第一个参数为事件名称,第二个参数为要传递的自定义数据,在父组件监听方法里面通过e.获取传递的数据 。
// api-index.stml: methods: {onGetResult(e){console.log(e.detail.msg);}}
4. 声网组件实例
了解了以上组件的规则和用法,就可以封装自己的组件了。下面看一个基于声网模块,实现1对1语音通话的组件实例:
{{item.username }}export default {name: 'agorartc-call-voice',props: {channel: String,userList: Array,rtcAppId: String},installed() {this.fnishasper_mic();},data() {return {connected: false};},methods: {fnishasper_mic(_userid) {var resultList = api.hasPermission({list: ["microphone"]});if (resultList[0].granted) {} else {api.toast({msg: "需要启用麦克风权限"});api.requestPermission({list: ["microphone"]}, res => {if (res.list[0].granted) {}});}},fnstart_voice_call(_userid) {this.fnrtc_init();this.fnerr_listener();this.fnjoin_channel(_userid);},fnrtc_init() {console.log('初始化');var agoraRtc = api.require('agoraRtc');agoraRtc.init({appId: this.props.rtcAppId});},fnjoin_channel(_userid) {console.log('121:---' + _userid);this.data.connected = true;var agoraRtc = api.require('agoraRtc');agoraRtc.joinChannelSuccessListener(function (ret) {console.log(ret.uid + 'uid------');});agoraRtc.remoteUserJoinedListener((ret) => {console.log(ret.uid + 'remoteUserJoinedListener------');if (ret.uid) {this.data.connected = true;}});// 多人语音通话 ,需设置角色为主播agoraRtc.setClientRole({role: 1}, function (ret) {if (ret.code == 0) {//successconsole.log('设置主播模式成功')}});agoraRtc.enableAudio((ret) => {if (ret.code == 0) {//successconsole.log('开启音频成功---' + this.props.channel);agoraRtc.joinChannel({channel: this.props.channel,uid: _userid}, function (ret) {if (ret.code == 0) {console.log('加入频道成功');}});}});agoraRtc.remoteUserOfflineListener((ret) => {api.toast({msg: '对方已挂断'})this.fnhangup();});},fnerr_listener() {var agoraRtc = api.require('agoraRtc');agoraRtc.errorListener(function (ret) {if (ret.errorCode == 0) {var agoraRtc = api.require('agoraRtc');agoraRtc.leaveChannel(function (ret) {if (ret.code == 0) { //success}});api.toast({msg: '通话出错!'});}});},fnhangup() {var agoraRtc = api.require('agoraRtc');agoraRtc.leaveChannel(function (ret) {if (ret.code == 0) {//success}});this.data.connected = false;}}};.agorartc-call-voice_page {height: 100%;width: 100%;background-color: #fff;} .agorartc-call-voice_list {height: 64px;width: 100%;display: flex;flex-direction: row;flex-wrap: nowrap;justify-content: flex-start;margin-bottom: 10px;} .agorartc-call-voice_userinfo {display: flex;flex-direction: row;flex-wrap: nowrap;justify-content: flex-start;align-items: center;padding-left: 20px;} .agorartc-call-voice_callimg {display: flex;flex-direction: row;flex-wrap: nowrap;justify-content: flex-end;align-items: center;flex-grow: 2;padding-right: 20px;} .agorartc-call-voice_connected {position: absolute;top: 0;left: 0;background-color: #fff;width: 100%;height: 100%;display: flex;flex-direction: column;justify-content: space-around;align-items: center;} .agorartc-call-voice_hangup {margin-top: 30px;}
AVM.js默认使用flex弹性盒子布局,实现UI时,应充分利用flex弹性布局原理进行布局 。而实现声网语音通话的核心逻辑很简单:两个用户加入同一个频道即可 。
本文到此结束,希望对大家有所帮助 。
- 遇到以下四种情况的豆瓣酱再便宜也不要购买
- 超标车定义,以及管理方法
- 怎样鉴别白酒的真伪
- ?白毫银针可以用保温杯泡吗
- 现在小学生可以跳级吗?要满足哪些条件?
- 从女生的哪些行为可以判断出她就是一个坏女人?
- 女人喜欢一个人,常会有的三种表现,两条以上多半是真爱
- MyFreeMP3
- 是不是可以在太空生育呢?
- 在Java项目中集成chatgpt的方法以及步骤