当前位置 : 主页 > 网络编程 > JavaScript >

跨端开发框架avm组件封装经验分享

来源:互联网 收集:自由互联 发布时间:2023-02-08
目录 引言 1.组件的定义和引用: 1.1 使用stml定义一个组件 / 页面 1.2 组件引用: 2.向子组件传值 2.1 在其它页面使用子组件时传递静态值: 2.2 通过数据绑定传递动态值: 3.监听子组件事
目录
  • 引言
  • 1. 组件的定义和引用:
    • 1.1 使用stml定义一个组件 / 页面
    • 1.2 组件引用:
  • 2. 向子组件传值
    • 2.1 在其它页面使用子组件时传递静态值:
    • 2.2 通过数据绑定传递动态值:
  • 3. 监听子组件事件**
    • 4.  声网组件实例

      引言

      avm.js 是一个跨端开发框架,AVM(Application-View-Model)前端组件化开发模式基于标准Web Components组件化思想,提供包含虚拟DOM和Runtime的编程框架avm.js以及多端统一编译工具,完全兼容Web Components标准,同时兼容Vue和React语法糖编写代码,编译工具将Vue和React相关语法糖编译转换为avm.js代码。

      有Vue和React 开发经验的很容易上手。

      1. 组件的定义和引用:

      1.1 使用stml定义一个组件 / 页面

      stml组件兼容Vue单文件组件(SFC)规范,使用语义化的Html模板及对象化js风格定义组件或页面。stml最终被编译为JS组件 / 页面,渲染到不同终端。

      定义组件:

      // api-test.stml:
      <template>  
          <view class='header'>
              <text>{this.data.title}</text>
          </view>  
      </template>  
      <script>
          export default {  
              name: 'api-test',
              data(){
                  return {
                      title: 'Hello APP'
                  }
              }
          }
      </script>
      <style scoped>
          .header{
              height: 45px;
          }
      </style>

      1.2 组件引用:

      // app-index.stml:
      <template>  
          <view class="app">  
              <img src="./assets/logo.png" />  
              <api-test></api-test> 
          </view>  
      </template>
      <script>
          import './components/api-test.stml'  
          export default {  
              name: 'app-index',  
              data: function () {  
                  return {
                      title: 'Hello APP'
                  }
              }  
          }  
      </script>  
      <style>  
          .app {   
              text-align: center;  
              margin-top: 60px;  
          }  
      </style>

      2. 向子组件传值

      向子组件传值采用 props 的方式,这里以一个示例来进行说明。

      定义子组件,在 props 里面注册一个 title 属性:

      // api-test.stml:
      <template>
          <text>{title}</text>
      </template>
      <script>
          export default {
              name:'api-test',
              props:{
                  title: String
              }
          }
      </script>

      这里定义的title属性类型为String,属性类型包括 String、Number、Boolean、Array、Object、Function等。

      2.1 在其它页面使用子组件时传递静态值:

      // app-index.stml:
      <template>  
          <view>  
              <api-test title="Hello App!"></api-test> 
          </view>  
      </template>
      <script>
          import './components/api-test.stml'  
          export default {  
              name: 'app-index'
          }  
      </script>

      2.2 通过数据绑定传递动态值:

      // app-index.stml:
      <template>
          <view>
              <api-test v-bind:title="msg"></api-test>
          </view>
      </template>
      <script>
          import './components/api-test.stml'  
          export default {
              name: 'app-index',
              data() {
                  return {
                    msg: 'Hello App!'
                }
              }
          }
      </script>

      传递静态值时只能传递字符串类型数据,通过数据绑定的方式则可以传递任意类型的数据。

      3. 监听子组件事件**

      监听子组件事件和监听普通事件类似,如:

      // api-index.stml:
      <template>
          <view>
              <api-test onresult="onGetResult"></api-test>
          </view>
      </template>
      <script>
          import './components/api-test.stml'  
          export default {
              name: 'app-index',
              methods: {
                  onGetResult(e){
                      console.log(e.detail.msg);
                  }
              }
          }
      </script>

      以上示例中监听了子组件的result事件,子组件里面通过fire方法来触发监听的事件:

      // app-test.stml:
      <template>
          <text onclick="onclick">Hello App!</text>
      </template>
      <script>
          export default {
              name:'api-test',
              methods:{
                  onclick(){
                      let detail = {msg:'Hi'};
                      this.fire('result', detail);
                  }
              }
          }
      </script>

      fire方法有两个参数,第一个参数为事件名称,第二个参数为要传递的自定义数据,在父组件监听方法里面通过e.detail获取传递的数据。

      // api-index.stml:
      methods: {
        onGetResult(e){
            console.log(e.detail.msg);
        }
      }

      4.  声网组件实例

      了解了以上组件的规则和用法,就可以封装自己的组件了 。下面看一个基于agoraRtc声网模块,实现1对1语音通话的组件实例:

      <template>
          <view class="agorartc-call-voice_page">
              <safe-area></safe-area>
              <view class="agorartc-call-voice_list" v-for="(item,index) in userList">
                  <view class="agorartc-call-voice_userinfo">
                      <image class="agorartc-call-voice_userinfo-image" thumbnail='false'
                          style="width: 64px; height: 64px; margin-right:10px" src={{item.userimg }}></image>
                      <text class="agorartc-call-voice_userinfo-text">{{item.username }}</text>
                  </view>
                  <view class="agorartc-call-voice_callimg">
                      <image @click="fnstart_voice_call(item.userid)" thumbnail='false' style="width: 50px; height: 50px"
                          src="../../image/voice-call.png"></image>
                  </view>
              </view>
              <view class="agorartc-call-voice_connected" v-if="connected">
                  <image class="agorartc-call-voice_voice" thumbnail='false' style="width: 200px;"
                      src="../../image/video-voice.gif"></image>
                  <image class="agorartc-call-voice_hangup" @click="fnhangup()" thumbnail='false'
                      style="width: 64px; height: 64px;" src="../../image/video-hangup.png"></image>
              </view>
          </view>
      </template>
      <script>
      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;
              }
          }
      };
      </script>
      <style>
      .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;
      }
      </style>

      avm.js 默认使用 flex 弹性盒子布局,实现UI时,应充分利用 flex 弹性布局原理进行布局。而实现声网语音通话的核心逻辑很简单:两个用户加入同一个频道即可 。

      以上就是跨端开发框架avm组件封装经验分享的详细内容,更多关于跨端开发框架avm组件封装的资料请关注易盾网络其它相关文章!

      网友评论