国产亚洲精品福利在线无卡一,国产精久久一区二区三区,亚洲精品无码国模,精品久久久久久无码专区不卡

當(dāng)前位置: 首頁 > news >正文

自己開發(fā)一款游戲怎么做搜索引擎seo優(yōu)化

自己開發(fā)一款游戲怎么做,搜索引擎seo優(yōu)化,學(xué)校建設(shè)網(wǎng)站的目的,集團門戶網(wǎng)站建設(shè)不足最近,接到小程序需求,并且是在以前公司老項目上改造,打開項目,發(fā)現(xiàn)卻不是我想象中的那樣,不是上來就是 Page({}),而是create(store,{}),納尼???這什么玩意&am…

最近,接到小程序需求,并且是在以前公司老項目上改造,打開項目,發(fā)現(xiàn)卻不是我想象中的那樣,不是上來就是 Page({}),而是create(store,{}),納尼???這什么玩意,怎么沒見過

1、初見Westore

接上,于是乎打開了create函數(shù)(后面得知本項目引用的1.0版本)如下

export default function create(store, option) {let updatePath = nullif (arguments.length === 2) {   ...Page(option)} else {...Component(store)}
}

咋眼一看,難不成是自己寫了一套狀態(tài)管理?直覺告訴我,這應(yīng)該不是前輩寫的,應(yīng)該是某個三方庫,于是乎去搜索了一番,果然是騰訊官網(wǎng)針對小程序優(yōu)化而出的,鏈接在這里,感興趣的小伙伴可以去看看哦

2、按文檔理解

大概是說,以store去驅(qū)動視圖,性能有所提高,能解決小程序跨頁面通訊,傳值等問題,反正巴拉巴拉一大堆(小程序不是有g(shù)lobalData嗎,說實話,我還沒理解它這個的好處),結(jié)合自己理解再簡單總結(jié)下吧

  1. 經(jīng)過改造后,相比小程序更新視圖的setData,Westore的update性能更好,為啥呢?update底層實質(zhì)還是調(diào)用的setData,只是再調(diào)用直接走了一次diff,只更新變動的,舉個栗子:
data: {info: {a: 'xxx',b: 'xxx'...}
}我們一般在更新一些數(shù)據(jù)時,可能會直接 setData({ info: newInfo }),而實際 newInfo 只是某個屬性改變了
當(dāng)使用 update() 時,會直接找出不同,差量的去更新
update()-------> setData({ 'info.a': '改變了哦' })
  1. 通過 store ,可以設(shè)置一些函數(shù)屬性,這個就類似vue計算屬性
  2. 剩下的就是關(guān)于 store 全局?jǐn)?shù)據(jù)的一個概念,就不累贅了
    當(dāng)然,這里只是簡單說下體會最明顯的幾點

3、簡單分析下流程

  1. 映入眼簾的是 create ,那么需要知道它干了啥
  2. 函數(shù)屬性是怎么實現(xiàn)的
  3. 憑什么 update 就比 setData好

3.1 淺析create

export default function create(store, option) {let updatePath = null// 在這一步,區(qū)分是組件還是頁面if (arguments.length === 2) {   if (option.data && Object.keys(option.data).length > 0) {// 記錄data中的keyupdatePath = getUpdatePath(option.data)// 頁面data的值初始值替換為 store中的值syncValues(store.data, option.data)}// 保留store源數(shù)據(jù),同時給當(dāng)前store新增幾個方法,尤其是updateif (!originData) {originData = JSON.parse(JSON.stringify(store.data))globalStore = storestore.instances = {}store.update = update...// 給全局的 globalStore 添加一個 methodextendStoreMethod(store)}getApp().globalData && (getApp().globalData.store = store)//option.data = store.dataconst onLoad = option.onLoad// walk 為了解決當(dāng)定義在store里面屬性是一個方法時// 會通過 Object.defineProperty 攔截一下該屬性的get過程(也就是緩存下函數(shù),改變this環(huán)境執(zhí)行一下)walk(store.data)// 解決函數(shù)屬性初始化不能顯示的問題,要求必須在data中聲明使用// 這段代碼是同步store.data到option.data,只有經(jīng)過walk方法后store.data中的函數(shù)才能變成屬性,才能被小程序page方法渲染if (option.data && Object.keys(option.data).length > 0) {updatePath = getUpdatePath(option.data)console.log('updatePath',updatePath)syncValues(store.data, option.data)}option.onLoad = function (e) {// 給當(dāng)前實例添加 store 、更新路徑、update方法、執(zhí)行onLoad、同步data、// 走小程序 setDatathis.store = storethis._updatePath = updatePath...this.setData(this.data)}// 解決執(zhí)行navigateBack或reLaunch時清除store.instances對應(yīng)頁面的實例const onUnload = option.onUnloadoption.onUnload = function () {onUnload && onUnload.call(this)store.instances[this.route] = []}Page(option)} else {組件邏輯,先不看}
}

create,接收兩個參數(shù)
store ---- 可以理解為頁面的數(shù)據(jù)(或者共享時公有的)
option — 則是小程序原有選項
代碼開頭則通過實參個數(shù),區(qū)分了當(dāng)前是組件,還是頁面(這里以頁面為例),同時記錄下頁面data路徑,也就是 getUpdatePath 函數(shù)

function getUpdatePath(data) {const result = {}dataToPath(data, result)return result
}function dataToPath(data, result) {Object.keys(data).forEach(key => {result[key] = trueconst type = Object.prototype.toString.call(data[key])if (type === OBJECTTYPE) {_objToPath(data[key], key, result)} else if (type === ARRAYTYPE) {_arrayToPath(data[key], key, result)}})
}

如上,getUpdatePath 目的就是把各個屬性記錄下來,如

data: {a: '123',b: { c: '456' }
}
getUpdatePath(data){a: true,'b.c': true
}

有了這個后,是為了方便后續(xù)判斷要更新的key在不在data中

還有一步 syncValues,這個函數(shù)就是把store中的值,同步到 data 中,這就是為什么頁面需要列出store中的屬性的原因(這里是v1,貌似proxy那個版本不需要了)

接著就是給store添加一些方法(如update),以及源數(shù)據(jù)保留等

來到 walk 函數(shù)

function walk(data) {Object.keys(data).forEach(key => {const obj = data[key]const tp = type(obj)if (tp == FUNCTIONTYPE) {setProp(key, obj)} else if (tp == OBJECTTYPE) {Object.keys(obj).forEach(subKey => {// 值,key vipInfo.age_walk(obj[subKey], key + '.' + subKey)})} else if (tp == ARRAYTYPE) {obj.forEach((item, index) => {_walk(item, key + '[' + index + ']')})}})
}function _walk(obj, path) {const tp = type(obj)if (tp == FUNCTIONTYPE) {setProp(path, obj)} else if (tp == OBJECTTYPE) {Object.keys(obj).forEach(subKey => {_walk(obj[subKey], path + '.' + subKey)})} else if (tp == ARRAYTYPE) {obj.forEach((item, index) => {_walk(item, path + '[' + index + ']')})}
}function setProp(path, fn) {const ok = getObjByPath(path)fnMapping[path] = fnObject.defineProperty(ok.obj, ok.key, {enumerable: true,get: () => {return fnMapping[path].call(globalStore.data)},set: () => {console.warn('Please using store.method to set method prop of data!')}})
}

看到這種名字的函數(shù),第一反應(yīng)就是逐個遍歷的過程,這個函數(shù)雖然拆成了幾個函數(shù),但目的其實很簡單,只有當(dāng) tp == FUNCTIONTYPE 時,才會跳出這個過程,走 setProp 函數(shù),看到這里可能還是有點迷糊,那就加一個函數(shù)屬性,豁然開朗

data: {vipInfo: {age: '25',getAge(){return this.vipInfo.age}}
}
經(jīng)過 walk 后
vipInfo: {age: '25',getAge: undefined
}
// getAge 變成了一個屬性,并且通過攔截的方式,當(dāng)get的時候再執(zhí)行開始定義的函數(shù)
// 這也就能解釋如何實現(xiàn) 函數(shù)屬性的了

剩下幾部就是對onLoad函數(shù)的改寫,以及一些頁面卸載,實例銷戶的過程,最終還是走的小程序Page函數(shù)

以上步驟,可以知道主要是
1、同步 store 中的值到 小程序 data 中
2、記錄每個屬性的路徑
3、當(dāng) store 中有函數(shù)屬性時,通過響應(yīng)攔截方式,將其轉(zhuǎn)變?yōu)?屬性(同時再次同步一次值)
4、給store添加一些api
5、對 onLoad 方法進行改寫,包括 onUnload
6、走小程序 Page 過程

3.2 那就看看 update

function update(patch) {return new Promise(resolve => {//defineFnProp(globalStore.data)// 可以傳路徑,也可以不傳if (patch) {for (let key in patch) {updateByPath(globalStore.data, key, patch[key])}}// diff 后直接找出差異的數(shù)據(jù)let diffResult = diff(globalStore.data, originData)if (Object.keys(diffResult)[0] == '') {diffResult = diffResult['']}// 是否是全局?jǐn)?shù)據(jù)const updateAll = matchGlobalData(diffResult)let array = []if (Object.keys(diffResult).length > 0) {for (let key in globalStore.instances) {globalStore.instances[key].forEach(ins => {if(updateAll || globalStore.updateAll || ins._updatePath){// 獲取需要更新的字段const needUpdatePathList = getNeedUpdatePathList(diffResult, ins._updatePath)console.log('needUpdatePathList',needUpdatePathList)if (needUpdatePathList.length) {...// 值差量更新,并且包裝成 數(shù)組 Promise 形式array.push( new Promise(cb => {ins.setData.call(ins, _diffResult, cb)}) )}}})}// 數(shù)據(jù)更新的回調(diào)globalStore.onChange && globalStore.onChange(diffResult)...Promise.all(array).then(e=>{resolve(diffResult)})})
}

可以看到,update 就比較殘暴了,通過 diff ,找出變動的數(shù)據(jù),接著是對應(yīng)實例更新問題,最后把需要更新的數(shù)據(jù)包裝成 Promise 的形式,最終通過 setData 實現(xiàn)

4、總結(jié)

以上就是筆者對整個過程的分析,從簡單來看,可以理解為重點對 setData 進行了 diff 的優(yōu)化,用法是上顯得直觀,官方也給出了 多頁面時幾種情況 store 的拆分,不過筆者還沒想好應(yīng)該怎么寫,跟優(yōu)雅

http://m.aloenet.com.cn/news/42526.html

相關(guān)文章:

  • 企業(yè)網(wǎng)站手機版模板免費下載上海關(guān)鍵詞優(yōu)化外包
  • php婚慶網(wǎng)站競價賬戶托管哪家好
  • 大理市住房和城鄉(xiāng)建設(shè)局網(wǎng)站磁力棒
  • wordpress 漏洞 掃描seo網(wǎng)站推廣專員
  • web網(wǎng)站開發(fā)用什么語言網(wǎng)絡(luò)廣告電話
  • 服飾網(wǎng)站模板設(shè)計百度搜索引擎怎么弄
  • 廣西網(wǎng)站建設(shè)運營費用專業(yè)代寫文案的公司
  • html網(wǎng)站開發(fā)工具有哪些互聯(lián)網(wǎng)登錄的網(wǎng)站名
  • 做sns網(wǎng)站需要什么百度熱線電話
  • 網(wǎng)站建設(shè)技術(shù)哪個好seo管理系統(tǒng)
  • qt科技感ui界面sem優(yōu)化軟件哪家好
  • 石家莊做網(wǎng)站價格網(wǎng)站優(yōu)化的關(guān)鍵詞
  • 網(wǎng)站做流量怎么賺錢的培訓(xùn)后的收獲和感想
  • 濟南網(wǎng)站建設(shè)工作室網(wǎng)球排名即時最新排名
  • 有沒有做網(wǎng)站的聯(lián)系方式經(jīng)典營銷案例分析
  • 消費返利系統(tǒng)網(wǎng)站建設(shè)廈門站長優(yōu)化工具
  • 做電商網(wǎng)站注意什么問題seo推廣代運營
  • 建設(shè)信用卡銀行積分商城網(wǎng)站福清網(wǎng)絡(luò)營銷
  • 網(wǎng)站制作難點seo是做什么工作內(nèi)容
  • 網(wǎng)站設(shè)計流程電話站長工具網(wǎng)
  • 網(wǎng)站開發(fā)管理電工培訓(xùn)技術(shù)學(xué)校
  • 怎么建設(shè)自己網(wǎng)站企業(yè)宣傳推廣
  • 國內(nèi)房地產(chǎn)設(shè)計網(wǎng)站建設(shè)網(wǎng)站優(yōu)化公司開始上班了
  • 制作釣魚網(wǎng)站的費用永久免費跨境瀏覽app
  • 怎么接做網(wǎng)站的任務(wù)seo在線優(yōu)化技術(shù)
  • 廣州展廳設(shè)計公司排名廣州seo優(yōu)化推廣
  • 網(wǎng)站搜索框如何做國內(nèi)最好用的免費建站平臺
  • 高端建筑鋁型材seo資料站
  • 做網(wǎng)站需要公司資質(zhì)嗎免費創(chuàng)建自己的網(wǎng)站
  • 摩洛哥網(wǎng)站后綴網(wǎng)上電商平臺開發(fā)