如何封装AVM组件?(以声网组件为例)

STML最终被编译为JS组件/页面,渲染到不同终端。向子组件传值向子组件传值采用props的方式,这里以一个示例来进行说明。在其它页面使用子组件时传递静态值:fire方法有两个参数,第一个参数为事件名称,第二个参数为要传递的自定义数据,在父

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组件/页面,渲染到不同终端。

定义组件:

// 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) {          //success          console.log('设置主播模式成功')        }      });       agoraRtc.enableAudio((ret) => {        if (ret.code == 0) {          //success          console.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弹性布局原理进行布局。而实现声网语音通话的核心逻辑很简单:两个用户加入同一个频道即可。

本文到此结束,希望对大家有所帮助。

本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至81118366@qq.com举报,一经查实,本站将立刻删除。发布者:简知小编,转载请注明出处:https://www.jianzixun.com/92580.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫

相关推荐

软文友链广告合作联系站长qq81118366