云開發(fā)練手項(xiàng)目:音樂播放器(下)

本文目錄:

  • 1.冷啟動(dòng)與熱啟動(dòng)
  • 2.小程序里不要頻繁的進(jìn)行setData
  • 3.小程序的更新機(jī)制
  • 4.小程序性能與體驗(yàn)優(yōu)化
  • 5.場(chǎng)景值scene的作用與應(yīng)用場(chǎng)景
  • 6.頁面收錄sitemap.json的作用與使用方法
  • 7.云開發(fā)小程序上限審核流程
  • 8.輪播圖圖片
  • 9.歌單信息管理
  • 10.發(fā)現(xiàn)信息管理
網(wǎng)頁開發(fā)和小程序開發(fā)的主要區(qū)別.png

小程序運(yùn)行環(huán)境.png

在不同的運(yùn)行環(huán)境下蛤签,邏輯層和渲染層的運(yùn)行位置都不同对碌,所以在小程序開發(fā)中,要多用真機(jī)去進(jìn)行調(diào)試先誉。
小程序的開發(fā)其實(shí)就是典型的客戶端原生與web技術(shù)結(jié)合的混合技術(shù)(Hybrid)

1.冷啟動(dòng)與熱啟動(dòng)

第一次打開小程序,雖然以前打開過聋溜,但是數(shù)據(jù)被小程序主動(dòng)銷毀了谆膳,再次啟動(dòng)也算是冷啟動(dòng),熱啟動(dòng):已經(jīng)打開了撮躁,在一定時(shí)間內(nèi)再次打開(大約5分鐘)漱病,這時(shí)候的打開只是從后臺(tái)切換到前臺(tái)把曼。


冷啟動(dòng)與熱啟動(dòng).png

2.小程序里不要頻繁的進(jìn)行setData

不表現(xiàn)在頁面上的數(shù)據(jù),不需要定義在data中嗤军。直接定義全局變量就行了。因?yàn)槊看蝧etData都會(huì)觸發(fā)渲染層和系統(tǒng)層叙赚、邏輯層的通信老客。


小程序的渲染邏輯.png

3.小程序的更新機(jī)制

我們可以在app.js的onLaunch生命周期中震叮,添加代碼,進(jìn)行版本的檢查和更新苇瓣,把下面這個(gè)函數(shù)放在onLaunch()里面尉间,讓小程序啟動(dòng)的時(shí)候就檢查更新击罪。

checkUpdate() {
  const updateManager = wx.getUpdateManager()
  // 檢測(cè)版本更新
  updateManager.onCheckForUpdate((res) => {
    // 如果有版本更新的話
    if (res.hasUpdate) {
      updateManager.onUpdateReady(() => {
        wx.showModal({
          title: '更新提示',
          content: '新版本已經(jīng)準(zhǔn)備好,是否重啟應(yīng)用',
          // 如果用戶選擇的是確定
          success(res) {
            updateManager.applyUpdate()
          }
        })
      })
    }
  })
}

4.小程序性能與體驗(yàn)優(yōu)化

  • 合理設(shè)置可點(diǎn)擊元素的響應(yīng)區(qū)域大小
  • 避免渲染頁面耗時(shí)過長(zhǎng)
  • 避免執(zhí)行腳本時(shí)間過長(zhǎng)
  • 對(duì)網(wǎng)絡(luò)請(qǐng)求做必要的緩存以避免多余的請(qǐng)求
  • 不要引入未被使用的wxss樣式
  • 所有資源請(qǐng)求建議使HTTPS眠副,更加安全
  • 不要使用廢棄接口
  • 避免過大的WXML節(jié)點(diǎn)數(shù)目
    • 一個(gè)頁面少于1000個(gè)WXML節(jié)點(diǎn)
    • 節(jié)點(diǎn)數(shù)深度少于30層
    • 子節(jié)點(diǎn)數(shù)量不大于60個(gè)
  • 避免將不可能被訪問到的頁面打包在小程序包里
  • 及時(shí)回收定時(shí)器(小程序中的定時(shí)器都是全局的竣稽,不會(huì)隨便頁面切換而消失)
  • 避免使用:active偽類來實(shí)現(xiàn)點(diǎn)擊態(tài)(使用navigator組件)
  • 滾動(dòng)區(qū)域可開啟慣性滾動(dòng)以增強(qiáng)體驗(yàn)
    IOS上:-webkit-overflow-scrolling:touch
  • 避免出現(xiàn)任何的Javascript異常
  • 所有請(qǐng)求的耗時(shí)不應(yīng)該太久,請(qǐng)求最好都要加上showloading,不要讓頁面處于假死狀態(tài)
  • 避免短時(shí)間內(nèi)發(fā)起太多的圖片請(qǐng)求
  • 避免短時(shí)間內(nèi)發(fā)起太多請(qǐng)求

setData的優(yōu)化

  • 避免setData的數(shù)據(jù)過大(小程序的限制是每次1M以內(nèi))
  • 避免setData的調(diào)用過于頻繁
  • 避免將未綁定到WXML的變量傳入setData

setData是一個(gè)異步操作拧烦,this.data是同步操作钝计,setData的回調(diào)是所有同步任務(wù)完成后才去執(zhí)行齐佳,但是this.data的值我們可以直接拿到進(jìn)行使用
案例1:下面代碼的執(zhí)行順序是什么债沮?
test的初始值是0

console.log('test開始:'+this.test)
this.setData({
  test:1
},()=>{
  console.log('回調(diào)執(zhí)行')
})
console.log('test設(shè)置后:’+this.test)
for (let i =0;i<10000;i++){
  for(let j=0;j<10000;j++){}
}
console.log('長(zhǎng)耗時(shí):'+this.test)

//test開始:0
//test設(shè)置后:1
//test長(zhǎng)耗時(shí):1
//回調(diào)執(zhí)行

案例2:setData改變對(duì)象的屬性值
testObj的默認(rèn)屬性為name:zhangsan,age:27

changeAge(){
  this.setData({
    testObj:{
      age:28
    }
  })
}

如果直接像上面這樣設(shè)置的話疫衩,age屬性值確實(shí)是變了,但是name屬性就消失了童芹,正確的做法應(yīng)該是

changeAge(){
  this.setData({
     ['testObj.age']:{
      age:28
    }
  })
}

setData改變的值可以不事先在data中進(jìn)行定義鲤拿,但是建議所有需要setData并且在頁面上顯示的值都在data中進(jìn)行定義近顷。

小程序開發(fā)的性能檢查:測(cè)試器中有個(gè)界面是Audits,我們開始檢查后將頁面的所有功能都手動(dòng)操作一遍窒升,然后點(diǎn)擊Stop就會(huì)出現(xiàn)響應(yīng)的評(píng)分异剥,A是最好的

5.場(chǎng)景值scene的作用與應(yīng)用場(chǎng)景

有幾十種途徑可以進(jìn)行到小程序,每個(gè)途徑對(duì)應(yīng)著一個(gè)ID值冤寿,如掃描二維碼對(duì)應(yīng)的是1011督怜,長(zhǎng)按圖片識(shí)別二維碼對(duì)應(yīng)的1012
我們可以通過對(duì)應(yīng)的代碼設(shè)置,來實(shí)現(xiàn)根據(jù)不同的入口場(chǎng)景号杠,來實(shí)現(xiàn)頁面的分流,同時(shí)也可以很方便的進(jìn)行后期的數(shù)據(jù)統(tǒng)計(jì)屉凯。
在app.js中對(duì)應(yīng)的生命周期onShow()中添加代碼(onShow監(jiān)聽小程序的啟動(dòng)和切前臺(tái))
開發(fā)者工具的導(dǎo)航欄有個(gè)功能鍵“切后臺(tái)”眼溶,點(diǎn)擊后可以模擬小程序切入后臺(tái),然后可以選擇不同的場(chǎng)景來進(jìn)行小程序

onShow(options){
}

onLauch:監(jiān)聽小程序的初始化
onShow:監(jiān)聽小程序的啟動(dòng)和切換前臺(tái)
這兩個(gè)的options的結(jié)構(gòu)是一樣的灌旧,里面都有scene字段
options可以打印出來scene值,根據(jù)這個(gè)值的不同我們可以進(jìn)行不同的設(shè)置描融,同時(shí)onLaunch生命周期中有可以進(jìn)行打印衡蚂,有幾個(gè)特定的場(chǎng)景代表著來源是外部的應(yīng)用(其他小程序或者公眾號(hào)),如果是的話让歼,options的referrerInfo字段會(huì)出現(xiàn)appid值丽啡,對(duì)我們也很有用补箍。

6.頁面收錄sitemap.json的作用與使用方法

在sitemap沒出現(xiàn)之前,小程序的搜索只能通過分類的名稱坑雅,sitemap讓小程序的搜索也可以根據(jù)頁面內(nèi)容實(shí)現(xiàn)裹粤。(本質(zhì)就是小程序的搜索功能優(yōu)化)
小程序的官網(wǎng)設(shè)置頁面,有一個(gè)頁面收錄功能開關(guān)按鈕拇泣,默認(rèn)是開啟的
項(xiàng)目文件里默認(rèn)創(chuàng)建有sitemap.json矮锈,我們可以里面添加和改變配置苞笨,在page里面配置頁面,*代表所有頁面瀑凝。頁面參數(shù)params以及匹配規(guī)則matching都是可以自由配置的粤咪。

"action":"allow"http://允許被索引
"action":"disallow"http://不允許被索引

7.云開發(fā)小程序上限審核流程

微信公眾平臺(tái)=》版本管理
首先需要把項(xiàng)目提交成”體驗(yàn)版”,項(xiàng)目預(yù)覽只有項(xiàng)目成員才可以掃描二維碼進(jìn)行預(yù)覽藏杖,小程序成為“體驗(yàn)版”
微信開發(fā)者工具右上角有個(gè)按鈕”上傳”脉顿,上傳之后就生成了體驗(yàn)版,微信公眾平臺(tái)的版本管理中就有了對(duì)應(yīng)的“開發(fā)版本”来吩。

項(xiàng)目架構(gòu)圖_20191226105049.png

GitHub上搜索vue-element-admin弟疆,star最多的那個(gè)盗冷,我們選擇使用基礎(chǔ)模板vue-admin-template

克隆項(xiàng)目
git clone https://github.com/PanJiaChen/vue-admin-template.git
進(jìn)入項(xiàng)目目錄
cd vue-admin-template
安裝依賴
npm install
建議不要直接使用 cnpm 安裝以來,會(huì)有各種詭異的 bug柑司」埃可以通過如下操作解決 npm 下載速度慢的問題
npm install --registry=https://registry.npm.taobao.org
啟動(dòng)服務(wù)
npm run dev

問題:下載了之后npm run dev報(bào)錯(cuò)故爵,去掉vue.config.js中的open:true之后可以直接啟動(dòng),但是登陸報(bào)405錯(cuò)誤劲室。

后端框架我們選用koa
1.建立空文件夾
2.npm init -y
3.npm install koa
4.新建app.js作為入口文件
在nodejs中出現(xiàn)最多的就是異步操作
實(shí)現(xiàn)hello world

const Koa = require('koa')
const app = new Koa()
app.use(async (ctx)=>{
    ctx.body = 'hello world'
})
app.listen(3000)

選用request來實(shí)現(xiàn)后端的發(fā)送請(qǐng)求
npm install request
npm install request-promise
獲取access_token的請(qǐng)求接口
GET https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET

請(qǐng)求參數(shù)與返回值_20191227171811.png

我們把請(qǐng)求獲得token的代碼封裝在utils文件夾中的getAccessToken.js文件中

const rp = require('request-promise')
const APPID = 'xxxx'
const APPSECRET = 'xxx'
const URL = `https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=${APPID}&secret=${APPSECRET}`
const updateAccessToken = async () => {
    const resStr = await rp(URL)
    const res = JSON.parse(resStr)
    console.log(res)
}
updateAccessToken()

這時(shí)候通過運(yùn)行g(shù)etAccessToken.js文件我們可以在控制臺(tái)上看到痹籍,我們已經(jīng)獲取到了token晦鞋,并且有效時(shí)間為7200s悠垛,我們選擇把獲取到的token,通過node寫入到j(luò)son文件中去斤讥。
寫入信息,需要引入fs和path兩個(gè)核心模塊派草,并且封裝一個(gè)可以讀取token的方法铛楣。同時(shí)讀取代碼的時(shí)候如果文件不存在,會(huì)報(bào)錯(cuò)鉴竭,我們需要進(jìn)行一個(gè)異常的捕獲岸浑。完整代碼如下

const rp = require('request-promise')
const APPID = 'xxx'
const APPSECRET = 'xxx'
const URL = `https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=${APPID}&secret=${APPSECRET}`

// 引入兩個(gè)核心文件矢洲,一個(gè)用來讀取文件,一個(gè)用來獲得文件的絕對(duì)路徑
const fs = require('fs')
const path = require('path')
// 定義我們要寫入數(shù)據(jù)的文件路徑
const fileName = path.resolve(__dirname, './access_token.json')

const updateAccessToken = async () => {
    const resStr = await rp(URL)
    const res = JSON.parse(resStr)
    console.log(res)
    // 寫文件,writeFileSync第一個(gè)參數(shù)是要寫入的文件路徑蛆橡,文件沒有的話會(huì)自動(dòng)創(chuàng)建掘譬,
    //第二個(gè)參數(shù)是我們想要寫入的值
    //第二個(gè)參數(shù)我們寫代碼的時(shí)候定義的是對(duì)象,但是最終錄入的是字符串睦焕,所以需要進(jìn)行轉(zhuǎn)換
    if (res.access_token) {
        fs.writeFileSync(fileName, JSON.stringify({
            access_token: res.access_token,
            createTime: new Date()
        }))
    }else{
        // 如果因?yàn)榫W(wǎng)絡(luò)原因靴拱,一次獲取token失敗也必須再次獲取袜炕,因?yàn)楹竺娴乃胁僮鞫家蕾囘@個(gè)token
        updateAccessToken()
    }
}
// 封裝讀取token的方法
const getAccessToken = async ()=>{
    try {
        // 讀取文件
        // 第二個(gè)參數(shù)utf8如果不傳,則默認(rèn)讀取的是二進(jìn)制數(shù)
        const readRes = fs.readFileSync(fileName, 'utf8')
        const readObj = JSON.parse(readRes)
        console.log(readObj)
    } catch (error) {
        // 如果讀取失敗乌助,就重新請(qǐng)求接口
        await updateAccessToken()
        // 然后再去獲取token信息
        await getAccessToken()
    }
}

// updateAccessToken()
getAccessToken()

module.exports = getAccessToken

設(shè)置一個(gè)定時(shí)器陌知,去獲取token

setInterval(()=>{
    await updateAccessToken()
},7200*1000)

路由規(guī)劃

下載安裝koa-router
npm install koa-router
新建controller文件夾仆葡,表示項(xiàng)目中C層(MVC模式),把前端發(fā)送過來的請(qǐng)求把篓,我們進(jìn)行云函數(shù)調(diào)用處理后再返還給前端=>這個(gè)文件夾的作用
在controller文件夾中新建一個(gè)playlist.js,關(guān)于歌單的處理寫在這個(gè)文件中
此時(shí)的app.js代碼

const Koa = require('koa')
const app = new Koa()

const Router = require('koa-router')
const router = new Router()

const playlist = require('./controller/playlist.js')
// 通過router聲明路由名稱, 對(duì)應(yīng)的就是playlist里面的路由
router.use('/playlist', playlist.routes())

// 聲明router
app.use(router.routes())
// 允許方法的調(diào)用
app.use(router.allowedMethods())

app.use(async (ctx) => {
    ctx.body = 'hello world'
})
app.listen(3000, () => {
    console.log('listening on 3000')
})

playlist.js代碼

const Router = require('koa-router')
const router = new Router()

router.get('/list',async(ctx,next)=>{
    // 查詢歌單列表
    ctx.body='歌單列表'
})

module.exports = router

啟動(dòng)項(xiàng)目皇耗,訪問localhost:3000/playlist/list,我們就能看到“歌單列表”
接下來万伤,在playlist.js中調(diào)用HTTP API觸發(fā)云函數(shù)
這一步敌买,我們實(shí)現(xiàn)訪問localhost:3000/playlist/list可以把請(qǐng)求到的歌單信息展現(xiàn)到瀏覽器上,此時(shí)的playlist.js完整代碼如下

const Router = require('koa-router')
const router = new Router()
const getAccessToken = require('../utils/getAccessToken.js')
const ENV = 'test-t1x7t'
const rp = require('request-promise')

router.get('/list', async (ctx, next) => {
    const access_token = await getAccessToken()
    // 查詢歌單列表
    const url = `https://api.weixin.qq.com/tcb/invokecloudfunction?access_token=${access_token}&env=${ENV}&name=music`
    // 用request-promise發(fā)送post請(qǐng)求的方式:定義一個(gè)options對(duì)象,然后將options作為發(fā)送請(qǐng)求的參數(shù)
    const options = {
        method: 'POST',
        url: url,
        body: {
            // 首先我們需要告訴云函數(shù)中的tcb-router聋庵,我們要請(qǐng)求的具體路由
            $url: 'playlist',
            start: 0,
            count: 50
        },
        json: true
    }
    ctx.body = await rp(options)
        .then((res) => {
            // console.log(res)
            return JSON.parse(res.resp_data).data
        })
        .catch((err) => {
            console.log("出錯(cuò)了")
        })
})

module.exports = router

接下來我們要實(shí)現(xiàn)從前端項(xiàng)目發(fā)送請(qǐng)求到后端拿取這個(gè)json歌單列表數(shù)據(jù)
前端代碼部分1.30左右
解決跨域的方案之一:cors
在后端項(xiàng)目中配置上允許發(fā)請(qǐng)求的域名
首先需要在后端項(xiàng)目安裝corsnpm install koa2-cors
然后在app.js文件中進(jìn)行導(dǎo)入const cors = require('koa2-cors')
進(jìn)行配置

app.use(cors({
    origin:['http://localhost:9528'],
    credentials:true
}))

這樣的話祭玉,我們就可以從http://localhost:9528發(fā)送請(qǐng)求了春畔,origin的值是個(gè)數(shù)組,可以配置多個(gè)振峻。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末扣孟,一起剝皮案震驚了整個(gè)濱河市荣赶,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌料仗,老刑警劉巖伏蚊,帶你破解...
    沈念sama閱讀 211,265評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異氛改,居然都是意外死亡胜卤,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,078評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門澈段,熙熙樓的掌柜王于貴愁眉苦臉地迎上來舰攒,“玉大人摩窃,你說我怎么就攤上這事』福” “怎么了蒂秘?”我有些...
    開封第一講書人閱讀 156,852評(píng)論 0 347
  • 文/不壞的土叔 我叫張陵材彪,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我段化,道長(zhǎng)显熏,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,408評(píng)論 1 283
  • 正文 為了忘掉前任缓升,我火速辦了婚禮蕴轨,結(jié)果婚禮上橙弱,老公的妹妹穿的比我還像新娘燥狰。我一直安慰自己斜筐,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,445評(píng)論 5 384
  • 文/花漫 我一把揭開白布目代。 她就那樣靜靜地躺著榛了,像睡著了一般煞抬。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,772評(píng)論 1 290
  • 那天蝗碎,我揣著相機(jī)與錄音旗扑,去河邊找鬼。 笑死眠菇,一個(gè)胖子當(dāng)著我的面吹牛袱衷,可吹牛的內(nèi)容都是我干的致燥。 我是一名探鬼主播,決...
    沈念sama閱讀 38,921評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼辐益,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼脱吱!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起续捂,我...
    開封第一講書人閱讀 37,688評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤疾忍,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后杨幼,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體聂渊,經(jīng)...
    沈念sama閱讀 44,130評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡汉嗽,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,467評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了稳析。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片弓叛。...
    茶點(diǎn)故事閱讀 38,617評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡撰筷,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出抬闯,到底是詐尸還是另有隱情关筒,我是刑警寧澤,帶...
    沈念sama閱讀 34,276評(píng)論 4 329
  • 正文 年R本政府宣布奈虾,位于F島的核電站廉赔,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏碉纳。R本人自食惡果不足惜馏艾,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,882評(píng)論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望铁孵。 院中可真熱鬧,春花似錦檀头、人聲如沸岖沛。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,740評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽嗤朴。三九已至虫溜,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背乓序。 一陣腳步聲響...
    開封第一講書人閱讀 31,967評(píng)論 1 265
  • 我被黑心中介騙來泰國打工替劈, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人盒犹。 一個(gè)月前我還...
    沈念sama閱讀 46,315評(píng)論 2 360
  • 正文 我出身青樓眨业,卻偏偏與公主長(zhǎng)得像龄捡,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子晨雳,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,486評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容

  • 今年的成長(zhǎng)項(xiàng)(暫時(shí))沒有獨(dú)立的個(gè)人項(xiàng)目餐禁,都是團(tuán)隊(duì)的整體成長(zhǎng)提升。 成長(zhǎng)項(xiàng)的推進(jìn)按照順序進(jìn)行不會(huì)并行推進(jìn)氧吐! 1 前端...
    angular_moon閱讀 164評(píng)論 0 0
  • 存儲(chǔ)類別:C中提供了許多不同的模型或者存儲(chǔ)類別在內(nèi)存中存儲(chǔ)數(shù)據(jù)喜鼓。從硬件方面看:被存儲(chǔ)的值都占用了一定的物理內(nèi)存庄岖,C...
    轉(zhuǎn)身一世鉛華盡閱讀 288評(píng)論 0 0
  • 關(guān)鍵詞:自帶設(shè)備 服務(wù)費(fèi) 某初中調(diào)研,學(xué)校3個(gè)班學(xué)生自購平板電腦心剥,用于答題背桐。 該初中的校長(zhǎng)和學(xué)生還是很支持的链峭。 然...
    由里世界閱讀 132評(píng)論 0 0
  • Had I not seen the Sun by Emily Dickinson Had I not seen ...
    Y艾閱讀 202評(píng)論 0 0
  • Standard C 語言標(biāo)準(zhǔn)函數(shù)庫速查弊仪,這個(gè)網(wǎng)址很全 Standard C++ Library Overview...
    一盞省油的小燈閱讀 108評(píng)論 0 0