整合營銷服務商

          電腦端+手機端+微信端=數據同步管理

          免費咨詢熱線:

          前端工程-從原理到輪子之JS模塊化

          前端工程-從原理到輪子之JS模塊化

          前,一個典型的前端項目技術框架的選型主要包括以下三個方面:

          1. JS模塊化框架。(Require/Sea/ES6 Module/NEJ)

          2. 前端模板框架。(React/Vue/Regular)

          3. 狀態管理框架。(Flux/Redux)

            系列文章將從上面三個方面來介紹相關原理,并且嘗試自己造一個簡單的輪子。

          本篇介紹的是 JS模塊化

          JS模塊化是隨著前端技術的發展,前端代碼爆炸式增長后,工程化所采取的必然措施。目前模塊化的思想分為CommonJS、AMD和CMD。有關三者的區別,大家基本都多少有所了解,而且資料很多,這里就不再贅述。

          模塊化的核心思想:

          1. 拆分 。將js代碼按功能邏輯拆分成多個可復用的js代碼文件(模塊)。

          2. 加載 。如何將模塊進行加載執行和輸出。

          3. 注入 。能夠將一個js模塊的輸出注入到另一個js模塊中。

          4. 依賴管理 。前端工程模塊數量眾多,需要來管理模塊之間的依賴關系。

          根據上面的核心思想,可以看出要設計一個模塊化工具框架的關鍵問題有兩個:一個是如何將一個模塊執行并可以將結果輸出注入到另一個模塊中;另一個是,在大型項目中模塊之間的依賴關系很復雜,如何使模塊按正確的依賴順序進行注入,這就是依賴管理。

          下面以具體的例子來實現一個簡單的 基于瀏覽器端AMD 模塊化框架(類似NEJ),對外暴露一個define函數,在回調函數中注入依賴,并返回模塊輸出。要實現的如下面代碼所示。

          define([ '/lib/util.js', //絕對路徑
          './modal/modal.js', //相對路徑
          './modal/modal.html',//文本文件], function(Util, Modal, tpl) { /*
           * 模塊邏輯
           */
          return Module;
          })

          1. 模塊如何加載和執行

          先不考慮一個模塊的依賴如何處理。假設一個模塊的依賴已經注入,那么如何加載和執行該模塊,并輸出呢?

          在瀏覽器端,我們可以借助瀏覽器的 script 標簽來實現 JS模塊文件 的引入和執行,對于 文本模塊文件 則可以直接利用 ajax 請求實現。

          具體步驟如下:

          • 第一步,獲取 模塊文件的絕對路徑

            要在瀏覽器內加載文件,首先要獲得對應模塊文件的完整網絡絕對地址。由于 a標簽 的href屬性總是會返回絕對路徑,也就是說它具有把相對路徑轉成絕對路徑的能力,所以這里可以利用該特性來獲取模塊的絕對網絡路徑。需要指出的是,對于使用相對路徑的依賴模塊文件,還需要遞歸先獲取當前模塊的網絡絕對地址,然后和相對路徑拼接成完整的絕對地址。代碼如下:

          var a=document.createElement('a');
          a.id='_defineAbsoluteUrl_';
          a.style.display='none';document.body.appendChild(a);function getModuleAbsoluteUrl(path) {
          a.href=path; return a.href;
          }function parseAbsoluteUrl(url, parentDir) { var relativePrefix='.',
          parentPrefix='..',
          result; if (parentDir && url.indexOf(relativePrefix)===0) { // 以'./'開頭的相對路徑
          return getModuleAbsoluteUrl(parentDir.replace(/[^\/]*$/, '') + url);
          } if (parentDir && url.indexOf(parentPrefix)===0) { // 以'../'開頭的相對路徑
          return getModuleAbsoluteUrl(parentDir.replace(/[\/]*$/, '').replace(/[\/]$/, '').replace(/[^\/]*$/, '') + url);
          } return getModuleAbsoluteUrl(url);
          }
          • 第二步, 加載和執行模塊文件

          對于JS文件,利用 script 標簽實現。代碼如下:

          var head=document.getElementsByTagName('head')[0] || document.body;
          
          function loadJsModule(url) { 
           var script=document.createElement('script');
          script.charset='utf-8';
          script.type='text/javascript';
          script.onload=script.onreadystatechange=function() { if (!this.readyState || this.readyState==='loaded' || this.readyState==='complete') { /*
           * 加載邏輯, callback為define的回調函數, args為所有依賴模塊的數組
           * callback.apply(window, args);
           */
          script.onload=script.onreadystatechange=null;
          } 
          };
          }

          對于文本文件,直接用 ajax 實現。代碼如下:

          var xhr=window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject('Microsoft.XMLHTTP'),
          textContent='';
          xhr.onreadystatechange=function(){ var DONE=4, OK=200; if(xhr.readyState===DONE){ if(xhr.status===OK){
          textContent=xhr.responseText; // 返回的文本文件
          } else{ console.log("Error: "+ xhr.status); // 加載失敗
          }
          }
          }
          xhr.open('GET', url, true);// url為文本文件的絕對路徑xhr.send(null);

          2. 模塊依賴管理

          一個模塊的加載過程如下圖所示。

          • 狀態管理

            從上面可以看出,一個模塊的加載可能存在以下幾種可能的狀態。

          1. 加載(load)狀態,包括未加載(preload)狀態、加載(loading)狀態和加載完畢(loaded)狀態。

          2. 正在加載依賴(pending)狀態。

          3. 模塊回調完成(finished)狀態。

            因此,需要為每個加載的模塊加上狀態標志(status),來識別目前模塊的狀態。

          • 依賴分析

            在模塊加載后,我們需要解析出每個模塊的絕對路徑(path)、依賴模塊(deps)和回調函數(callback),然后也放在模塊信息中。模塊對象管理邏輯的數據模型如下所示。

            {
            path: 'http://asdas/asda/a.js',
            deps: [{}, {}, {}],
            callback: function(){ },
            status: 'pending'
            }
          • 依賴循環

            模塊很可能出現循環依賴的情況。也就是a模塊和b模塊相互依賴。依賴分為 強依賴弱依賴強依賴 是指,在模塊回調執行時就會使用到的依賴;反之,就是 弱依賴 。對于 強依賴,會造成死鎖,這種情況是無法解決的。但 弱依賴 可以通過現將一個空的模塊引用注入讓一個模塊先執行,等依賴模塊執行完后,再替換掉就可以了。 強依賴弱依賴 的例子如下:

          //強依賴的例子
          //A模塊
          define(['b.js'], function(B) { 
           // 回調執行時需要直接用到依賴模塊
          B.demo=1; // 其他邏輯});//B模塊define(['a.js'], function(A) { // 回調執行時需要直接用到依賴模塊
          A.demo=1; // 其他邏輯});
          // 弱依賴的例子
          // A模塊
          define(['b.js'], function(B) { 
           // 回調執行時不會直接執行依賴模塊
          function test() {
          B.demo=1;
          } return {testFunc: test}
          });//B模塊define(['a.js'], function(A) { // 回調執行時不會直接執行依賴模塊
          function test() {
          A.demo=1;
          } return {testFunc: test}
          });

          3. 對外暴露define方法

          對于define函數,需要遍歷所有的未處理js腳本(包括 內聯外聯 ),然后執行模塊的加載。這里對于 內聯外聯 腳本中的define,要做分別處理。主要原因有兩點:

          1. 內斂腳本不需要加載操作。

          2. 內斂腳本中define的模塊的回調輸出是不能作為其他模塊的依賴的。

          var handledScriptList=[];
          window.define=function(deps, callback) { var scripts=document.getElementsByTagName('script'),
          defineReg=/s*define\s*\(\[.*\]\s*\,\s*function\s*\(.*\)\s*\{/,
          script; for (var i=scripts.length - 1; i >=0; i--) {
          script=list[i]; if (handledScriptList.indexOf(script.src) < 0) {
          handledScriptList.push(script.src); if (script.innerHTML.search(defineReg) >=0) { // 內斂腳本直接進行模塊依賴檢查。
          } else { // 外聯腳本的首先要監聽腳本加載
          }
          }
          }
          };

          上面就是對實現一個模塊化工具所涉及核心問題的描述。

          者:肖鵬

          轉發鏈接:https://mp.weixin.qq.com/s/8gMg8pL1d89ofvc8FMiMBA

          大家好,我是小雨!

          今天我們要介紹的知識點是 Django 中的 Templates,它也是 MVT 結構中的 T,Templates 可以叫它模板。Templates 究竟用來做什么,通過這一節的介紹,希望大家有一個基本的了解。

          一、Templates 模板

          在上一節當中,我們在瀏覽器中看到的是 HTTPResponse 返回的字符串,而這一節我們講的 templates 最直接的功能是把前端的 html 頁面顯示出來,這樣用戶就能看到清晰美觀的界面。那么 Django 是如何加載 html 網頁的呢?下面介紹兩種方式:

          1.使用 render_to_string 加載 html

          我們提前準備好一個 html 頁面index.html,然后為了方便 views 中能成功訪問到這個index.html,需要在settings.py中將templates文件夾的路徑聲明清楚。在 TEMPLATES 列表字典的DIRS屬性下添加一下內容:

          os.path.join(BASE_DIR, 'templates')  # 如果缺少os模塊記得導入

          render_to_string 的使用方法: 先使用from django.templates.loader import render_to_string導入模塊,然后給 render_to_string 傳入 html 文件后,最后將其以 HttpResponse 的方式返回出去即可。

          from django.http import HttpResponse
          from django.templates.loader import render_to_string
          
          def index(request):
              html = render_to_string("index.html")
              return HttpResponse(html)

          2. 使用 render 加載 html

          這里我們需要從django.shortcut導入 render 模塊,一般情況下 Django 會默認導入這個模塊,views 中如果沒有的話就手動導入一下:

          from django.shortcut import render

          接著 render 中傳入 html 文件,記得添加 request 參數,然后使用 return 返回 render 即可:

          def index(request):
              return render(request,'index.html')

          最后記得在 urls.py 中將路徑對應的 views.index 添加進來就可以了。

          二、模板語言的基本使用

          我們要知道 templates 作為 MVT 架構中的 T,不僅僅是加載前端中的頁面,它還包含一種模板語言,能夠在 htmlL 語言中實現邏輯控制(條件選擇、循環),相對于 JavaScript 會更加的靈活。

          常用的python模板語言引擎

          接下來,我們就以一個簡單的例子來介紹 Django 模板語言的使用。

          1.功能需求分析

          我們有一個存儲學生信息的Students.csv文件,包含了學號、姓名、性別、手機號碼、出生日期、電子郵箱等信息。

          319001,趙一,男,1998/12/27,18706012232,532211428@qq.com,北京市海淀區頤和園路5號,342622199801144314,2019/9/1,計算機,趙一,13655512212
          319002,錢二,女,1995/10/25,13459732456,572501101@qq.com,北京市海淀區雙清路30號,342622199709066819,2019/9/1,物聯網,王二,13856909992

          這里數據其實有很多條,為了減少篇幅我們就羅列出兩條。

          現在需要將這些數據加載到前端的 html 頁面中,通過 tabel 標簽顯示出來。

          2. 實現過程

          (1)準備

          首先用 pycharm 新建一個 Django 項目,為了方便使用直接把 application 和 templates 文件夾都建好。

          pycharm新建Django項目

          在 templates 中新建一個 index.html 文件,寫好用于顯示學生信息的標題以及表格框架。

          <div id="title">學生信息列表</div>
          <div id="table_main">
              <table border="1">
                  <thead>
                      <tr>
                          <th>學號</th>
                          <th>姓名</th>
                          <th>性別</th>
                          <th>出生日期</th>
                          <th>手機號碼</th>
                          <th>電子郵箱</th>
                          <th>家庭地址</th>
                      </tr>
                  </thead>
                  <tbody>
                  </tbody>
              </table>
          </div>

          (2)views 設置

          為了讀取 csv 文件,寫一個read_form_file方法,將文件中的信息存儲在 Students 列表中。

          def read_from_file(path:str):
              students = []
              try:
                  with open(path, mode="r", encoding="UTF-8") as fd:
                      # 讀取當前行
                      current_line = fd.readline()
                      # 判斷當前行是否為空
                      while current_line:
                          temp_line = current_line.split(",")
                          students.append(temp_line)
                          current_line = fd.readline()
                  return students
              except Exception as e:
                  raise e

          接下來,我們定義一個 student 方法,用來顯示 html 內容給前端,這里面我們還是使用 render 將獲取的數據傳遞給前端頁面index.html

          注意使用 context 參數,它的值我們設置為一個字典,鍵設置為 DTL 模板語言中要引用的變量,值設置為本地獲取的數據

          def student(request):
              students = read_from_file(r"D:\Python\Project\Demo\Student.csv")
              return render(request, "index.html", context={"all_student":students})

          (3)DTL 模板語言

          index.html中,表格內容的填充,我們通過 DTL 模板語言來完成。在 HTML 代碼中要插入 DTL 模板語言,需要使用{%語句%},for 語句還要使用{% endfor %}來結尾,在語句內部調用變量列表中的元素也是直接使用變量名.數字并且需要包裹兩層大括號。這里我們以循環輸出 student 列表中的各個元素為例,其 DTL 模板語言的寫法如下:

           {% for student in all_student %}
              <tr>
              <td>{{ student.0 }}</td>
              <td>{{ student.1 }}</td>
              <td>{{ student.2 }}</td>
              <td>{{ student.3 }}</td>
              <td>{{ student.4 }}</td>
              <td>{{ student.5 }}</td>
              <td>{{ student.6 }}</td>
              </tr>
           {% endfor %}

          (4)urls 配置

          接下來配置路由,添加 student 路徑

          path('student/',app01_views.student),

          (5)運行效果

          一切準備就緒后,執行python manage.py runserver,在瀏覽器中打開127.0.0.1:8000/student效果如下:

          數據被成功加載

          三、加載靜態文件

          1. 什么是靜態文件

          不能與服務器做動態交互的文件叫靜態文件; 對于 HTML 中的圖片、視頻、css、js 這些都屬于靜態文件。Django 對于這些文件有一套明確的管理機制。 如果我們只遵循 HTML 的規范去加載靜態文件,在 Django 中是顯示不出來的。

          Django無法加載靜態文件

          2. 如何加載靜態文件

          為了解決這個問題,我們首先要確保配置文件 settings.py 中 INSTALLED_APP 下靜態文件模塊有被加載到:

          'django.contrib.staticfiles',  # 必須確保安裝靜態模塊

          然后使用STATICFILES_DIRS這個全局變量來存儲靜態文件的路徑。

          STATICFILES_DIRS = [
              os.path.join(BASE.DIR, 'static'),
          ]

          然后在 html 中開始加上模板語言,如果讓 html 引用靜態文件,那就需要先導入靜態模塊。在 html 語句第一行寫上

          {% load static %}

          對于要引用靜態圖片的標簽路徑使用{% static "路徑文件名 "%},如:

          <img src="{% static "logo.png"%}">

          這樣 Django 就能顯示靜態文件圖片了。

          3. 顯示效果

          靜態圖片被正確顯示了


          4. 注意事項

          一般情況下,static 文件夾我們會放在app目錄下。這時候訪問靜態文件,則需要在STATICFILES_DIRS的 os.path.join 參數中再多添加一個子文件夾名,可以寫成:

          STATICFILES_DIRS = [
              os.path.join(BASE.DIR, 'app01','static'),
          ]

          5. 直接訪問靜態文件

          在 Django 配置的文件 settings.py 中有一個全局變量STATIC_URL,它定義了一個給外界用戶直接訪問靜態文件的路徑。 上面我們添加在標題中的 logo.png,我們可以在瀏覽器中直接通過127.0.0.1:8000/student/static/logo.png來訪問。

          直接訪問靜態文件

          四、加載靜態文件綜合案例

          為了更好地鞏固 Django 加載靜態文件的知識,我們做一個小案例。學生信息管理系統的登錄頁面。有顯示圖片 logo,有用戶名和密碼的輸入框,并且有提交按鈕。當點擊按鈕時,會彈出提示表示登錄成功。

          這里簡單說明一下:

          界面采用了 Bootstrap 框架,登錄按鈕的功能函數用了 jQuery 腳本。關于前端的知識我們這里就不做過多介紹了。

          {% load static %}
          <!DOCTYPE html>
          <html lang="en">
          <head>
              <meta charset="UTF-8">
              <title>login</title>
              <!--加載外部的CSS文件-->
              <link type="text/css" rel="stylesheet" href="{% static "css/bootstrap.min.css" %}">
              <link type="text/css" rel="stylesheet" href="{% static "css/basic.css" %}">
              <!--加載外部的js文件-->
              <script src="{% static "js/jquery.min.js" %}"></script>
              <script src="{% static "js/login.js" %}"></script>
          </head>
          <body>
              <div class="container">
                  <div id = "login">
                      <form class="form">
                          <h2><img src="{% static "imags/mainlogo.png" %}"></h2>
                          <h2>學生信息管理系統登錄</h2>
                          <hr>
                          <hr>
                          <div class="form-group">
                              <label for="user">用戶名:</label>
                              <input type="text" class="form-control" placeholder="請輸入用戶名" id="user">
                          </div>
                          <div class="form-group">
                              <label for="password">密碼</label>
                              <input type="password" class="form-control" placeholder="請輸入密碼" id="password">
                          </div>
                          <div class="form-group">
                              <div class="checkbox">
                                  <label>
                                      <input type="checkbox">請記住我
                                  </label>
                              </div>
                          </div>
                          <button id="submit01" class="form-control">提交</button>
                      </form>
                  </div>
              </div>
          </body>
          </html>

          將以上 html 文件保存在 templates 中,在 views 中配置好方法,urls 中配置好路由,最后在 settings 中配置好靜態文件路徑,最后啟動 Django 服務器,頁面顯示效果如下:

          效果演示:

          登錄頁面案例演示


          最后

          本節,我們介紹了 Django 中 templates 的知識,Django 加載 HTML 方法、模板的語言的使用,以及加載靜態文件的方法。希望大家多多練習,才能鞏固所學的知識。下一節我們將繼續介紹 Django 中 URL 跳轉的知識!

          感謝大家的閱讀!


          主站蜘蛛池模板: 亚洲综合一区二区| 国产99精品一区二区三区免费 | 狠狠色综合一区二区| 蜜桃视频一区二区| 亚洲av成人一区二区三区观看在线| 国产一区二区三区精品视频| 国产精品一区二区综合| 丰满爆乳无码一区二区三区| 亚洲日本乱码一区二区在线二产线 | 国产成人欧美一区二区三区 | 一区二区乱子伦在线播放| 国产福利一区视频| 久久精品日韩一区国产二区| 亚洲国产精品一区二区三区在线观看 | 国产一区二区三区日韩精品| 尤物精品视频一区二区三区 | 久久久久人妻精品一区三寸蜜桃 | 亚洲一区二区三区国产精品| 波多野结衣一区二区免费视频| 国产在线步兵一区二区三区| 国产精品成人一区二区三区| 国精产品一区一区三区有限在线| 国产精品第一区揄拍| 另类国产精品一区二区| 成人精品视频一区二区三区尤物| 精品国产精品久久一区免费式| 国产一区在线观看免费| 国产在线一区二区视频| 亚洲第一区精品日韩在线播放| 国产激情一区二区三区成人91| 国产精品福利区一区二区三区四区| 久久久久人妻精品一区三寸蜜桃| 久久se精品一区二区| 精品国产一区二区三区四区| 无码人妻精品一区二区三区久久久| 国产精品一区二区综合| 国产日韩一区二区三免费高清| 无码少妇一区二区三区| 亚无码乱人伦一区二区| 无码人妻AⅤ一区二区三区水密桃| 亚洲一区二区三区国产精品|