由於本人喜歡封裝元件做到高內聚,這樣的好處是,拿來就用,如果封裝乙個元件,需要外部耦合,那麼將沒法做到很好的復用,因為耦合的部分需要每次重新開發。
最近遇到了乙個業務場景是這樣,如圖:
1. 頁面展示主頁,主頁可以瀏覽,也可以點選去其他頁面,主頁有登入按鈕,登入按鈕點選顯示登入view(注意:登入不是跳去登入頁,而是在當前頁做view切換)。
2. 登入view中可以填寫使用者名稱、密碼,可以登入、可以返回(返回到主頁view)。
1. 首先將主頁是小程式的乙個頁面,由於我希望登入模組是通用的,既然不是新的頁面,就做成乙個元件。
2. 登入元件命名為login-view,愉快的開發完畢。
3. 接下來頁面引用元件,並在wxml中使用
<4. 就這樣,定義data:showlogin, 用其控制是否切換到登入view。view
class
="home-container"
wx:if
="}"
>
view
>
<
login-view
wx:else
>
login-view
>
5. 當主頁中點選登入時,將showlogin = true。
6. 很棒,展示了登入介面。填寫使用者名稱、密碼、點選登入,成功!。
7. 很開心,第一次測試成功了,接著第二次測試。
8. 這是第二次測試,點選登入,到登入介面,輸入使用者名稱,這時候點選了返回。
9. 再次點選登入來到了登入介面,發現剛剛輸入的使用者名稱不見了
10. 留下了沒有技術的淚水,emmm...
接下來展示思考,終於想到了為什麼:
wx:if是dom的移除與新增,並不是顯示與隱藏,因此,在切換showlogin = false時,login-view元件被移除了,當再次點選登入,showlogin = true時,login-view元件又重新掛在。
好,失蹤的使用者名稱找到了,是wx:if將它奪走了。那麼該怎麼解決?
我解決此問題用了兩個過程,分別是:完成與完善。
分析:資訊丟失是因為元件的登出與重新掛載,這是不可避免的,元件登出後,內容永遠也儲存不了。要解決的就是把元件內容儲存起來
解決辦法: 資訊儲存在page中,因為page是一直生存的,元件是會登出的。因此page中的data是不會隨著元件登出而消失的。那麼如何將資訊存放在page中?
如下:1. 將username和password直接放在page的data中,並且接收input事件去改變值
<2. 在page中宣告oninput,當元件中觸發此函式,則改變username和password的值login-view
username
="}"
password
="}"
bindinput
="oninput"
>
login-view
>
page(,3. 在login-view元件中,接收username和password值,並渲染到login-view.wxml中去,這裡就不再貼**了。//元件中觸發事件,修改輸入框的值
oninput(e) =e.detail;
this
.setdata();
},});
思考:這樣修改有什麼問題?我認為這樣的元件不能稱之為乙個優秀的元件,為什麼?
答:我希望我的元件是拿來就用的,那麼這樣修改,我怎麼做到拿來就用?這樣的元件已與page高耦合,沒有page中的邏輯,此元件無法執行,因此我不能這樣該。
該怎樣:那麼我該怎樣該達到我快取資料的目的呢?
首先看完善後的業務上該怎麼用
<wxml裡直接這樣使用,那麼page的js裡呢?答案:不需要任何**。這麼神奇麼?就是這麼神奇。login-view
>
login-view
>
思路: 儲存原來**不變,login-view做了任何login-view該做的事情,資料儲存、資料更新都在元件內完成。我要做的是做到元件重新掛在,資料快取。該怎樣做?
同樣,利用page data快取資料,但是不需要主動去定義,在login-view元件裡做手腳:
const base = require('./wx-component.js');以上**,引用了wx-component.js,暴露乙個方法,將原本傳遞給component的options物件傳遞給他,base(options),然後再將其返回值傳遞給component,component(base(options))。做了一層包裝。就這樣,就完成了資料快取,再次切換login-view時,資料依舊儲存著。component(base(,
methods: );
},},
}));
那麼看到這裡讀者要問:wx-component是什麼鬼?$$data又是什麼?
wx-component.js是自己封裝的乙個元件增強的擴充套件函式,他可以輕鬆賦予你三個特殊能力。
什麼意思?我們都知道,page中的data可以傳遞給元件使用,並且page中data更新,元件中的view頁同步更新,但是元件中的data更新不會反射到page中。
那麼這第乙個buff就是:元件data更新引發page中data的更新,換句話說,page的data中會時時儲存元件data的乙個副本。因此我叫他逆向資料繫結。
**如下:
const base = require('./wx-component.js');name是必須宣告的,使用增強元件功能,需要宣告唯一name值,比如『login』,$$data屬性是逆向資料繫結的所有資料,其他不需要逆向資料繫結的資料依舊放在data中。component(base(,
}));
這樣就完成了component.$$data -> page.data的功能,在元件setdata改變username和password的值會同步到page.data中去。
那你怎麼可以在page中獲取到他呢?在page中用this.data.$[name]格式,此例子中為:this.data.$login就獲取到了逆向資料的物件。
有了逆向資料繫結,你可能猜到了,就用這種方法可以把資料儲存到page中了,那麼在元件登出後重新掛載,我們可以拿到此份資料來進行渲染到元件。
這部分**在wx-component.js中做體現,業務中並不需要做額外的事情。
很多時候,元件內部的一些方法,page中其實也需要用到的, 比如:tab元件,點選某個tab,則變為啟用狀態,在page中可能也是需要主動去改變某個tab的啟用狀態,因此需要用到元件內部方法。
當然元件內部方法是有辦法獲取的,官方文件有介紹如何獲取元件例項,獲取到元件例項,當然就可以使用其方法,但這樣很麻煩的,我可以提供更好的方法。
const base = require('./wx-component.js');如上用$parentmethods物件來暴露給page方法,在page中可以直接呼叫component(base(,
//定義向page暴露的方法
$parentmethods: );
},},
}));
page(這就是wx-component的功能,功能並不是通用的,只適合部分業務場景。如果你的業務放好需要這樣做,你就可以用到它。})
github點這裡
如果對你有幫助,點乙個star吧~~~
如果有錯誤的地方,請提issue吧~~~
微信小程式網悅新聞開發 自定義元件開發(六)
1 首先在根目錄下建立乙個components目錄,用來存放所有元件。2 然後右擊components資料夾選擇新建乙個components。3 這裡我們輸入mytabbar就會給我們自動建立乙個元件,裡面包含了 json wxml wxss js 4個檔案。4 要編寫乙個自定義元件,首先需要在js...
開發自定義控制項
學習自定義控制項的開發不僅可以使你開發出更靈活的系統更重要的是它可以使你加深對已有伺服器控制項的理解,得以更靈活的應用。先說一下伺服器控制項的概念吧 所謂伺服器控制項,就是在伺服器上執行,並可以對映到所有瀏覽器支援的標準 html 標記的控制項,在你的web窗體中,凡是包含 runat server...
開發自定義View
view元件就類似於乙個矩形空白區域,剛開始它裡面什麼都沒有,對於android應用的其他ui元件來說,他們都繼承了view元件,然後在view元件的空白區域上繪製外觀.基於這個原理,開發者可以開發出專案定製的元件,當android系統提供的ui不能滿足開發需求時,可以自定義類去繼承view類或者v...