<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
avm.js 是一個跨端開發框架,AVM(Application-View-Model)前端元件化開發模式基於標準Web Components元件化思想,提供包含虛擬DOM和Runtime的程式設計框架avm.js以及多端統一編譯工具,完全相容Web Components標準,同時相容Vue和React語法糖編寫程式碼,編譯工具將Vue和React相關語法糖編譯轉換為avm.js程式碼。
有Vue和React 開發經驗的很容易上手。
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>
// 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>
向子元件傳值採用 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等。
// 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>
// 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>
傳遞靜態值時只能傳遞字串型別資料,通過資料繫結的方式則可以傳遞任意型別的資料。
監聽子元件事件和監聽普通事件類似,如:
// 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); } }
瞭解了以上元件的規則和用法,就可以封裝自己的元件了 。下面看一個基於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元件封裝的資料請關注it145.com其它相關文章!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45