2019獨角獸企業重金招聘Python工程師標準>>>
開源地址:https://github.com/leebingbin/Python3.WebAPP.Blog
?
????單從編碼來說,WebApp開發真正困難的地方在于編寫前端頁面。前端頁面需要混合HTML、CSS和JavaScript,如果對這三者沒有深入地掌握,編寫的前端頁面將很快難以維護。更大的問題在于,前端頁面通常是動態頁面,也就是說,前端頁面往往是由后端代碼生成的。
????生成前端頁面最早的方式是拼接字符串:
s = '<html><head><title>'+ title+ '</title></head><body>'+ body+ '</body></html>'
????顯然這種方式完全不具備可維護性。所以有第二種模板方式:
<html>
<head><title>{{ title }}</title>
</head>
<body>{{ body }}
</body>
</html>
????JSP、PHP等都是用這種模板方式生成前端頁面。如果在頁面上大量使用JavaScript(實際上大部分頁面都會),模板方式仍然會導致JavaScript代碼與后端代碼綁得非常緊密,以至于難以維護。其根本原因在于負責顯示的HTML DOM模型與負責數據和交互的JavaScript代碼沒有分割清楚。
????要編寫可維護的前端代碼絕非易事。和后端結合的MVC模式已經無法滿足復雜頁面邏輯的需要了,所以,新的MVVM:Model View ViewModel模式應運而生。
????MVVM最早由微軟提出來,它借鑒了桌面應用程序的MVC思想,在前端頁面中,把Model用純JavaScript對象表示:
<script>var blog = {name: 'hello python3',summary: 'this is summary',content: 'this is content'};
</script>
View是純HTML:
<form action="/api/blogs" method="post"><input name="name"><input name="summary"><textarea name="content"></textarea><button type="submit">Submit</button>
</form>
????由于Model表示數據,View負責顯示,兩者做到了最大限度的分離。
????把Model和View關聯起來的就是ViewModel。ViewModel負責把Model的數據同步到View顯示出來,還負責把View的修改同步回Model。
????ViewModel如何編寫?需要用JavaScript編寫一個通用的ViewModel,這樣,就可以復用整個MVVM模型了。市面上已有許多成熟的MVVM框架,例如AngularJS,KnockoutJS等。我們選擇Vue (https://vuejs.org/)這個簡單易用的MVVM框架來實現創建Blog的頁面templates/manage_blog_edit.html:
{% extends '__base__.html' %}{% block title %}編輯日志{% endblock %}{% block beforehead %}<script>varID = '{{ id }}',action = '{{ action }}';function initVM(blog) {var vm = new Vue({el: '#vm',data: blog,methods: {submit: function (event) {event.preventDefault();var $form = $('#vm').find('form');$form.postJSON(action, this.$data, function (err, r) {if (err) {$form.showFormError(err);}else {return location.assign('/api/blogs/' + r.id);}});}}});$('#vm').show();
}$(function () {if (ID) {getJSON('/api/blogs/' + ID, function (err, blog) {if (err) {return fatal(err);}$('#loading').hide();initVM(blog);});}else {$('#loading').hide();initVM({name: '',summary: '',content: ''});}
});</script>{% endblock %}{% block content %}<div class="uk-width-1-1 uk-margin-bottom"><div class="uk-panel uk-panel-box"><ul class="uk-breadcrumb"><li><a href="/manage/comments">評論</a></li><li><a href="/manage/blogs">日志</a></li><li><a href="/manage/users">用戶</a></li></ul></div></div><div id="error" class="uk-width-1-1"></div><div id="loading" class="uk-width-1-1 uk-text-center"><span><i class="uk-icon-spinner uk-icon-medium uk-icon-spin"></i> 正在加載...</span></div><div id="vm" class="uk-width-2-3"><form v-on="submit: submit" class="uk-form uk-form-stacked"><div class="uk-alert uk-alert-danger uk-hidden"></div><div class="uk-form-row"><label class="uk-form-label">標題:</label><div class="uk-form-controls"><input v-model="name" name="name" type="text" placeholder="標題" class="uk-width-1-1"></div></div><div class="uk-form-row"><label class="uk-form-label">摘要:</label><div class="uk-form-controls"><textarea v-model="summary" rows="4" name="summary" placeholder="摘要" class="uk-width-1-1" style="resize:none;"></textarea></div></div><div class="uk-form-row"><label class="uk-form-label">內容:</label><div class="uk-form-controls"><textarea v-model="content" rows="16" name="content" placeholder="內容" class="uk-width-1-1" style="resize:none;"></textarea></div></div><div class="uk-form-row"><button type="submit" class="uk-button uk-button-primary"><i class="uk-icon-save"></i> 保存</button><a href="/manage/blogs" class="uk-button"><i class="uk-icon-times"></i> 取消</a></div></form></div>{% endblock %}
????初始化Vue時,我們指定3個參數:
????????el:根據選擇器查找綁定的View,這里是#vm,就是id為vm的DOM,對應的是一個<div>標簽;
????????data:JavaScript對象表示的Model,我們初始化為{ name: '', summary: '', content: ''};
????????methods:View可以觸發的JavaScript函數,submit就是提交表單時觸發的函數。
????接下來,我們在<form>標簽中,用幾個簡單的v-model,就可以讓Vue把Model和View關聯起來:
<!-- input的value和Model的name關聯起來了 -->
<input v-model="name" class="uk-width-1-1">
????Form表單通過<form v-on="submit: submit">把提交表單的事件關聯到submit方法。
????需要特別注意的是,在MVVM中,Model和View是雙向綁定的。如果我們在Form中修改了文本框的值,可以在Model中立刻拿到新的值。試試在表單中輸入文本,然后在Chrome瀏覽器中打開JavaScript控制臺,可以通過vm.name訪問單個屬性,或者通過vm.$data訪問整個Model:
????如果我們在JavaScript邏輯中修改了Model,這個修改會立刻反映到View上。試試在JavaScript控制臺輸入vm.name = 'MVVM簡介',可以看到文本框的內容自動被同步了。
????雙向綁定是MVVM框架最大的作用。借助于MVVM,我們把復雜的顯示邏輯交給框架完成。由于后端編寫了獨立的REST API,所以,前端用AJAX提交表單非常容易,前后端分離得非常徹底。
?
?
本文為博主原創文章,轉載請注明出處!
https://my.oschina.net/u/3375733/blog/