<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                **閱讀目錄** [TOC] 前后端分手大師——MVVM 模式 === # 簡而言之 Model–View–ViewModel(MVVM) 是一個軟件架構設計模式,由微軟 WPF 和 Silverlight 的架構師 Ken Cooper 和 Ted Peters 開發,是一種簡化用戶界面的事件驅動編程方式。由 John Gossman(同樣也是 WPF 和 Silverlight 的架構師)于2005年在他的博客上發表。 MVVM 源自于經典的 Model–View–Controller(MVC)模式(期間還演化出了 Model-View-Presenter(MVP)模式,可忽略不計)。MVVM 的出現促進了 GUI 前端開發與后端業務邏輯的分離,極大地提高了前端開發效率。MVVM 的核心是 ViewModel 層,它就像是一個中轉站(value converter),負責轉換 Model 中的數據對象來讓數據變得更容易管理和使用,該層向上與視圖層進行雙向數據綁定,向下與 Model 層通過接口請求進行數據交互,起呈上啟下作用。如下圖所示: ![](https://box.kancloud.cn/487e1c8a52539dd1ecf77ed757f7a797_966x311.png) MVVM模式 MVVM 已經相當成熟了,主要運用但不僅僅在網絡應用程序開發中。KnockoutJS 是最早實現 MVVM 模式的前端框架之一,當下流行的 MVVM 框架有 Vue,Angular 等。 # 組成部分 簡單畫了一張圖來說明 MVVM 的各個組成部分: ![](https://box.kancloud.cn/c9203b4f58c225ee5947dabfc61492f8_894x775.png) MVVM分層示意圖 分層設計一直是軟件架構的主流設計思想之一,MVVM 也不例外。 ## View 層 View 是視圖層,也就是用戶界面。前端主要由 HTML 和 CSS 來構建,為了更方便地展現 ViewModel 或者 Model 層的數據,已經產生了各種各樣的前后端模板語言,比如 FreeMarker、Marko、Pug、Jinja2等等,各大 MVVM 框架如 KnockoutJS,Vue,Angular 等也都有自己用來構建用戶界面的內置模板語言。 ## Model 層 Model 是指數據模型,泛指后端進行的各種業務邏輯處理和數據操控,主要圍繞數據庫系統展開。后端的處理通常會非常復雜: ![](https://box.kancloud.cn/e1ba813539501144eb4a53b7ec651fb3_488x387.png) 前后端對比 后端:我們這里的業務邏輯和數據處理會非常復雜! 前端:關我屁事! 后端業務處理再復雜跟我們前端也沒有半毛錢關系,只要后端保證對外接口足夠簡單就行了,我請求api,你把數據返出來,咱倆就這點關系,其他都扯淡。 ## ViewModel 層 ViewModel 是由前端開發人員組織生成和維護的視圖數據層。在這一層,前端開發者對從后端獲取的 Model 數據進行轉換處理,做二次封裝,以生成符合 View 層使用預期的視圖數據模型。需要注意的是 ViewModel 所封裝出來的數據模型包括視圖的狀態和行為兩部分,而 Model 層的數據模型是只包含狀態的,比如頁面的這一塊展示什么,那一塊展示什么這些都屬于視圖狀態(展示),而頁面加載進來時發生什么,點擊這一塊發生什么,這一塊滾動時發生什么這些都屬于視圖行為(交互),視圖狀態和行為都封裝在了 ViewModel 里。這樣的封裝使得 ViewModel 可以完整地去描述 View 層。由于實現了雙向綁定,ViewModel 的內容會實時展現在 View 層,這是激動人心的,因為前端開發者再也不必低效又麻煩地通過操縱 DOM 去更新視圖,MVVM 框架已經把最臟最累的一塊做好了,我們開發者只需要處理和維護 ViewModel,更新數據視圖就會自動得到相應更新,真正實現數據驅動開發。看到了吧,View 層展現的不是 Model 層的數據,而是 ViewModel 的數據,由 ViewModel 負責與 Model 層交互,這就完全解耦了 View 層和 Model 層,這個解耦是至關重要的,它是前后端分離方案實施的重要一環。 # 沒有什么是一個栗子不能解決的 扯了這么多,并沒有什么卵用。千言萬語不如一個栗子來的干脆,下面用一個 Vue 實例來說明 MVVM 的具體表現。 Vue 的 View 模板: ~~~ <div id="app"> <p>{{message}}</p> <button v-on:click="showMessage()">Click me</button> </div> ~~~ Vue 的 ViewModel 層(下面是偽代碼): ~~~ var app = new Vue({ el: '#app', data: { // 用于描述視圖狀態(有基于 Model 層數據定義的,也有純前端定義) message: 'Hello Vue!', // 純前端定義 server: {}, // 存放基于 Model 層數據的二次封裝數據 }, methods: { // 用于描述視圖行為(完全前端定義) showMessage(){ let vm = this; alert(vm.message); } }, created(){ let vm = this; // Ajax 獲取 Model 層的數據 ajax({ url: '/your/server/data/api', success(res){ // TODO 對獲取到的 Model 數據進行轉換處理,做二次封裝 vm.server = res; } }); } }) ~~~ 服務端的 Model 層(省略業務邏輯處理,只描述對外接口): ~~~ { "url": "/your/server/data/api", "res": { "success": true, "name": "IoveC", "domain": "www.cnblogs.com" } } ~~~ 這就是完整的 MVVM 編程模式。 代碼執行之后雙向綁定的效果如下: ![](https://box.kancloud.cn/6d33749048f5f3c07174f61a87062fc3_866x489.gif) Vue實現的響應的數據綁定
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看