整合營銷服務商

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

          免費咨詢熱線:

          「開源推薦」electron:使用web技術開發桌面

          「開源推薦」electron:使用web技術開發桌面應用

          日github繼續更新:

          21,tensorflow / models

          tensorflow已經訓練好的一些模型。學習tensorflow從這里開始。

          22,electron / electron

          如果你可以建一個網站,你就可以建一個桌面應用程序。 Electron 是一個使用 JavaScript, HTML 和 CSS 等 Web 技術創建原生程序的框架,它負責比較難搞的部分,你只需把精力放在你的應用的核心上即可。這個好棒??!我要重點研究下

          23,golang / go

          go語言。最近幾年熱度持續上漲的一門語言。關于Go語言能夠取代Java,成為下一個王者

          這個話題也時常被人聊起,由此可以go的熱度。

          24,torvalds/linux

          大名鼎鼎的linux,雖然我們看不懂源碼,但不妨礙點上star,略表崇拜

          25,webpack / webpack

          webpack 是一個現代 JavaScript 應用程序的靜態模塊打包器,在現在的前端工程中使用非常非常廣泛。

          26,laravel / laravel

          Laravel是一套簡潔、優雅的PHP Web開發框架(PHP Web Framework)。終于看到PHP的框架上榜了。

          27,jwasham / coding-interview-university

          一套完整的學習手冊幫助自己準備 Google 的面試。這是作者為了從 web 開發者(自學、非計算機科學學位)蛻變至 Google 軟件工程師所制定的計劃,其內容歷時數月。(有中文翻譯版)

          28,apple / swift

          Swift,蘋果于2014年WWDC(蘋果開發者大會)發布的新開發語言,用于開發IOS應用程序。

          29,GoogleChrome / puppeteer

          Puppeteer是谷歌官方出品的一個通過DevTools協議控制headless Chrome的Node庫。可以通過Puppeteer的提供的api直接控制Chrome模擬大部分用戶操作來進行UI Test或者作為爬蟲訪問頁面來收集數據。

          30,atom / atom

          號稱是21世紀編輯器,用最酷的編輯器寫最酷的代碼。非官方統計,排在前三的編輯器分別是sublime、Atom、webstorm。

          么是Vue.js

            Vue.js是一個構建數據驅動的web界面的庫。技術上,它重點集中在MVVM模式的ViewModel層,因此它非常容易學習,非常容易與其它庫或已有項目整合。

            Vue.js的目標是通過盡可能簡單的API實現響應的數據綁定和組合的視圖組件。

            Vue.js 的核心是一個響應的數據綁定系統,它讓數據與DOM保持同步非常簡單。在使用jQuery手工操作DOM時,我們的代碼常常是命令式的、重復的與易錯的。Vue.js擁抱數據驅動的視圖概念。通俗地講,它意味著我們在普通HTML模板中使用特殊的語法將DOM “綁定”到底層數據。

          安裝

          獨立版本

            直接下載并用 < script > 標簽引入,Vue會被注冊為一個全局變量。如下代碼,這樣就可以在腳本中使用Vue.js了。

          <script src="lib/vue.js"></script>

          CDN

            也可以在 jsdelivr或 cdnjs獲取 (版本更新可能會略滯后)。

          NPM

            在用 Vue.js 構建大型應用時推薦使用 NPM 安裝,NPM 能很好地和諸如 Webpack 或 Browserify 的 CommonJS 模塊打包器配合使用。Vue.js 也提供配套工具來開發單文件組件。

          $ npm install vue
          `# 獲取CSP兼容版本:
          `$ npm install vue@csp
          `# 獲取最新開發版本(來自于GitHub):
          $ npm install yyx990803/vue#dev

          Hello World

            現在就讓我們來寫第一個vue.js的實例。如下代碼:

          html代碼:

          <div id="demo">
            {{ message }}
          </div>

          JavaScript代碼:

          new Vue({
            el: '#demo',
            data: {
              message: 'Hello World!'
            }
          })

            上面代碼中div中的部分 {{ message }}為數據綁定,我們將會在后面的學習中講到。而vue.js代碼是實例化一個Vue對象。在使用vue之前必須要實例化。

          構造器

            每個Vue.js應用的起步都是通過構造函數Vue創建一個Vue的根實例:

          var vm=new Vue({
            // 選項
          })

            一個Vue實例其實正是一個MVVM模式中所描述的 ViewModel - 因此在文檔中經常會使用vm這個變量名。

          屬性與方法

            每個Vue實例都會代理其data對象里所有的屬性,如下代碼:

          var data={ a: 1 }
          var vm=new Vue({
            data: data
          })
          //vm.a===data.a  -> true
          // 設置屬性也會影響到原始數據
          vm.a=2
          // data.a  -> 2
          // ... 反之亦然
          data.a=3
          //vm.a -> 3

            注意只有這些被代理的屬性是響應的。如果在實例創建之后添加新的屬性到實例上,它不會觸發視圖更新。

            除了前面這些數據屬性,Vue 實例還有一些有用的實例屬性與方法。這些屬性與方法都有前綴 $,以便與代理的數據屬性區分。例如:

          var data={ a: 1 }
          var vm=new Vue({
            el: '#example',
            data: data
          })
          
          vm.$data===data // -> true
          vm.$el===document.getElementById('example') // -> true
          
          // $watch 是一個實例方法
          vm.$watch('a', function (newVal, oldVal) {
            // 這個回調將在 `vm.a`  改變后調用
          })

          插值

           數據綁定最基礎的形式是文本插值,使用 {{}} 語法(雙大括號):

          <span>Message: {{ msg }}</span>

            {{ msg }} 標簽會被相應數據對象的 msg 屬性的值替換。每當這個屬性變化時它也會更新。

            也可以只處理單次插值,今后的數據變化就不會再引起插值更新了:

          <span>This will never change: {{* msg }}</span>

          如下JavaScript代碼:

          var data={msg:'Hello Vue.js!'};
          new Vue({
            el: '#demo',
            data: data
           })
          data.msg="Hello World!";

          原始的HTML

            雙大括號標簽將數據解析為純文本而不是HTML。為了輸出真的HTML字符串,需要用三大括號標簽:

          <div>{{{ msg }}}</div>

            如下javascript代碼:

          
          var data={msg:'<p>Hello Vue.js!</p>'};
          new Vue({
              el: '#demo',
              data: data
             })

          HTML特性

            雙大括號標簽也可以用在 HTML 特性 (Attributes) 內:

          <div id="{{ id }}"></div>

          javascript代碼如下:

          var data={id:'demo'};
          new Vue({
            el: 'div',
            data: data
           })

          我們去查看HTML源碼,是不是id已經變成我們設置的id了。

          JavaScript表達式

            Vue.js 在數據綁定內支持全功能的JavaScript表達式:

          {{ number + 1 }}
          {{ ok ? 'YES' : 'NO' }}
          {{ message.split('').reverse().join('') }}

          過濾器

            Vue.js 允許在表達式后添加可選的“過濾器 (Filter) ”,以“管道符(|)”指示。過濾器本質上是一個函數,這個函數會接收一個值,將其處理并返回。

          {{ message | uppercase }}

            這里我們將表達式 message 的值“管輸(pipe)”到內置的 uppercase 過濾器,這個過濾器其實只是一個 JavaScript 函數,返回大寫化的值。Vue.js 提供數個內置過濾器,在后面我們會談到如何開發自己的過濾器。

            可以串聯多個過濾器:

          {{ message | filterA | filterB }}

          html代碼:  

          
          <div id='demo'>
          <span>{{msg | lowercase | capitalize}}</span>
          </div>

          javaScript代碼:

          
           var data={msg:'heLLO!'};
           new Vue({
            el: '#demo',
            data: data
           })

          運行結果為:Hello

          指令

            Vue.js指令 (Directives) 是特殊的帶有前綴 v- 的特性。本質是模板中出現的特殊標記,讓處理模板的庫知道需要對這里的DOM元素進行一些對應的處理。指令的職責就是當其表達式的值改變時把某些特殊的行為應用到 DOM 上。

          <p v-if="msg">Hello!</p>

            這里 v-if 指令將根據表達式 msg 值的真假刪除/插入 < p > 元素。

            在Vue.js中為我們提供了一些指令:v-text,v-html,v-model,v-on,v-else等等,同學們可以去查看Vue.js的指令api(cn.vuejs.org/api/#指令)。

          javascript代碼:

           var data={msg:0};
           new Vue({
            el: '#demo',
            data: data
           })

          計算屬性

            在模板中表達式非常便利,但是它們實際上只用于簡單的操作。模板是為了描述視圖的結構。在模板中放入太多的邏輯會讓模板過重且難以維護。這就是為什么 Vue.js 將綁定表達式限制為一個表達式。如果需要多于一個表達式的邏輯,應當使用計算屬性。

            在 Vue.js 中,你可以通過 computed 選項定義計算屬性:

          <div id="example">
            a={{ a }}, b={{ b }}
          </div>
          var vm=new Vue({
            el: '#example',
            data: {
              a: 1
            },
            computed: {
              // 一個計算屬性的 getter
              b: function () {
                // `this` 指向 vm 實例
                return this.a + 1
              }
            }
          })

          運行結果為:a=1,b=2。

          更多內容如 Class 與 Style 綁定、 渲染指令、 表單控件綁定、 自定義指令和過濾器、 方法與事件處理器、組件等請參考: http://www.hubwiz.com/course/566e67417e7d40946afc5ddc/

          紹 官網 github Vue.js 是一套構建用戶界面(UI)的漸進式 JavaScript 框架 庫和框架的區別 庫: ?> 庫,本質上是一些函數的集合。每次調用函數,實現一個特定的功能,接著把控制權交給使用者 jQuery:DOM 操作,即:封裝 DOM 操作,簡化 DOM 操作 框架: ?> 框架,是一套完整的解決方案,使用框架的時候,需要把你的代碼放到框架合適的地方,框架會在合適的時機調用你的代碼 框架規定了自己的編程方式,是一套完整的解決方案 使用框架的時候,由框架控制一切,我們只需要按照規則寫代碼 主要區別: !> 核心點:誰起到主導作用(控制反轉)框架的侵入性很高(從頭到尾) MVVM 和 MVC 的介紹: MVVM,一種更好的 UI 模式解決方案 MVVM===> M / V / VM M:model 數據模型 V:view 視圖 VM:ViewModel 視圖模型 MVC 模型-視圖-控制器 M: Model 數據模型(專門用來操作數據,數據的 CRUD) V:View 視圖(對于前端來說,就是頁面) C:Controller 控制器(是視圖和數據模型溝通的橋梁,用于處理業務邏輯) MVVM 和 MVC 的優勢對比 MVC 模式,將應用程序劃分為三大部分,實現了職責分離 在前端中經常要通過 JS 代碼 來進行一些邏輯操作,最終還要把這些邏輯操作的結果現在頁面中。也就是需要頻繁的操作 DOM MVVM 通過數據雙向綁定讓數據自動地雙向同步 V(修改數據) -> M M(修改數據) -> V 數據是核心 Vue 這種 MVVM 模式的框架,不推薦開發人員手動操作 DOM Vue 中的 MVVM 雖然沒有完全遵循 MVVM 模型,Vue 的設計無疑受到了它的啟發。因此在文檔中經常會使用 vm (ViewModel 的簡稱) 這個變量名表示 Vue 實例 !> 學習 Vue 要轉化思想 不要在想著怎么操作 DOM,而是想著如何操作數據!!! 起步 - Hello Vue 安裝:cnpm i -S vue {{ msg }}

          1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 Vue 實例 !> 注意 1:先在 data 中聲明數據,再使用數據 !> 注意 2:可以通過 vm.$data 或者 vm.msg 訪問到data中的所有屬性, var vm=new Vue({ data: { msg: "大家好,..." } }); vm.$data.msg===vm.msg; // true 1 2 3 4 5 6 7 1 2 3 4 5 6 7 數據綁定 最常用的方式:Mustache(插值語法),也就是 {{}} 語法 解釋:{{}}從數據對象data中獲取數據 說明:數據對象的屬性值發生了改變,插值處的內容都會更新 說明:{{}}中只能出現 JavaScript 表達式 而不能解析 js 語句 注意:Mustache 語法不能作用在 HTML 元素的屬性上

          Hello, {{ msg }}.

          {{ 1 + 2 }}

          {{ isOk ? 'yes': 'no' }}

          1 2 3 4 5 6 1 2 3 4 5 6 數據雙向綁定 雙向數據綁定:將 DOM 與 Vue 實例的 data 數據綁定到一起,彼此之間相互影響 數據的改變會引起 DOM 的改變 DOM 的改變也會引起數據的變化 原理:Object.defineProperty中的get和set方法 getter和setter:訪問器 作用:指定讀取或設置對象屬性值的時候,執行的操作 深入響應式原理 /* defineProperty語法 介紹 */ var obj={}; Object.defineProperty(obj, "msg", { // 設置 obj.msg="1" 時set方法會被系統調用 參數分別是設置后和設置前的值 set: function(newVal, oldVal) {}, // 讀取 obj.msg 時get方法會被系統調用 get: function(newVal, oldVal) {} }); 1 2 3 4 5 6 7 8 1 2 3 4 5 6 7 8 Vue 雙向綁定的極簡實現 剖析 Vue 原理&實現雙向綁定 MVVM 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 動態添加數據的注意點 注意:只有 data 中的數據才是響應式的,動態添加進來的數據默認為非響應式 可以通過以下方式實現動態添加數據的響應式 1 Vue.set(object, key, value) - 適用于添加單個屬性 2 Object.assign() - 適用于添加多個屬性 var vm=new Vue({ data: { stu: { name: "jack", age: 19 } } }); /* Vue.set */ Vue.set(vm.stu, "gender", "male"); /* Object.assign 將參數中的所有對象屬性和值 合并到第一個參數 并返回合并后的對象*/ vm.stu=Object.assign({}, vm.stu, { gender: "female", height: 180 }); 1 2 3 4 5 6 7 8 9 10 11 12 1 2 3 4 5 6 7 8 9 10 11 12 異步 DOM 更新 說明:Vue 異步執行 DOM 更新,監視所有數據改變,一次性更新 DOM 優勢:可以去除重復數據,對于避免不必要的計算和 避免重復 DOM 操作上,非常重要 如果需要那到更新后 dom 中的數據 則需要通過 Vue.nextTick(callback):在 DOM 更新后,執行某個操作(屬于 DOM 操作) 實例調用 vm.$nextTick(function () {}) methods: { fn() { this.msg='change' this.$nextTick(function () { console.log('$nextTick中打?。?, this.$el.children[0].innerText); }) console.log('直接打?。?, this.$el.children[0].innerText); } } 1 2 3 4 5 6 7 8 9 1 2 3 4 5 6 7 8 9 指令 解釋:指令 (Directives) 是帶有 v- 前綴的特殊屬性 作用:當表達式的值改變時,將其產生的連帶影響,響應式地作用于 DOM v-text 解釋:更新 DOM 對象的 textContent 1 2 1 2 v-html 解釋:更新 DOM 對象的 innerHTML 1 1 v-bind 作用:當表達式的值改變時,將其產生的連帶影響,響應式地作用于 DOM 語法:v-bind:title="msg" 簡寫::title="msg" 1 2 3 4 1 2 3 4 v-on 作用:綁定事件 語法:v-on:click=“say” or v-on:click=“say(‘參數’, $event)” 簡寫:@click=“say” 說明:綁定的事件定義在 methods 1 2 3 4 1 2 3 4 事件修飾符 .stop 阻止冒泡,調用 event.stopPropagation() .prevent 阻止默認行為,調用 event.preventDefault() .capture 添加事件偵聽器時使用事件捕獲模式 .self 只當事件在該元素本身(比如不是子元素)觸發時,才會觸發事件 .once 事件只觸發一次 v-model 作用:在表單元素上創建雙向數據綁定 說明:監聽用戶的輸入事件以更新數據 你輸入了: {{ message }}

          1 2 1 2 v-for 作用:基于源數據多次渲染元素或模板塊 {{ item.text }}

          {{item}} -- {{index}}

          {{item}} -- {{key}}

          {{item}}

          1 2 3 4 5 6 7 8 9 10 1 2 3 4 5 6 7 8 9 10 key 屬性 推薦:使用 v-for 的時候提供 key 屬性,以獲得性能提升。 說明:使用 key,VUE 會基于 key 的變化重新排列元素順序,并且會移除 key 不存在的元素。

          1 2 3 1 2 3 樣式處理 class 和 style 使用方式:v-bind:class=“expression” or :class=“expression” 表達式的類型:字符串、數組、對象(重點)===> 解析后===>解析后===>解析后 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 v-if 和 v-show v-if:根據表達式的值的真假條件,銷毀或重建元素 v-show:根據表達式之真假值,切換元素的 display CSS 屬性

          這個元素展示出來了嗎???

          這個元素,在HTML結構中嗎???

          1 2 1 2 提升性能:v-pre vue 會跳過這個元素和它的子元素的編譯過程??梢杂脕盹@示原始 Mustache 標簽。跳過大量沒有指令的節點會加快編譯。 {{ 這將不會被編譯 }} 1 1 提升性能:v-once 說明:vue 只渲染元素和組件一次。隨后的重新渲染,元素/組件及其所有的子節點將被視為靜態內容并跳過。這可以用于優化更新性能。 這不會被改變: {{msg}} 1 1 過濾器 filter 作用:文本數據格式化 過濾器可以用在兩個地方:{{}}和 v-bind 表達式 兩種過濾器:1.全局過濾器 2. 局部過濾器 全局過濾器 說明:通過全局方式創建的過濾器,在任何一個 vue 實例中都可以使用 注意:使用全局過濾器的時候,需要先創建全局過濾器,再創建 Vue 實例 顯示的內容由過濾器的返回值決定

          {{ dateStr | date }}

          {{ dateStr | date('YYYY-MM-DD hh:mm:ss') }}

          1 2 3 4 5 6 7 8 9 10 1 2 3 4 5 6 7 8 9 10 局部過濾器 說明:局部過濾器是在某一個 vue 實例的內容創建的,只在當前實例中起作用 { data: {}, // 通過 filters 屬性創建局部過濾器 // 注意:此處為 filters filters: { filterName: function(value, format) {} } } 1 2 3 4 5 6 7 8 1 2 3 4 5 6 7 8 按鍵值修飾符 說明:在監聽鍵盤事件時,Vue 允許為 v-on 在監聽鍵盤事件時添加關鍵修飾符 其他:修飾鍵(.ctrl 等)、鼠標按鍵修飾符(.left 等) 鍵盤事件 - 鍵值修飾符 // 只有在 keyCode 是 13 時調用 vm.submit() @keyup.13="submit" // 使用全局按鍵別名 @keyup.enter="add" --- // 通過全局 config.keyCodes 對象自定義鍵值修飾符別名 Vue.config.keyCodes.f2=113 // 使用自定義鍵值修飾符 @keyup.enter.f2="add" 1 2 3 4 5 6 7 8 9 10 11 1 2 3 4 5 6 7 8 9 10 11 監視數據變化 - watch 概述:watch 是一個對象,鍵是需要觀察的表達式,值是對應回調函數 作用:當表達式的值發生變化后,會調用對應的回調函數完成響應的監視操作 vue$watch new Vue({ data: { a: 1, b: { age: 10 } }, watch: { a: function(val, oldVal) { // val 表示當前值 // oldVal 表示舊值 console.log("當前值為:" + val, "舊值為:" + oldVal); }, // 監聽對象屬性的變化 b: { handler: function(val, oldVal) { /* ... */ }, // deep : true表示是否監聽對象內部屬性值的變化 deep: true }, // 只監視user對象中age屬性的變化 "user.age": function(val, oldVal) {} } }); 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 計算屬性 說明:計算屬性是基于它們的依賴進行緩存的,只有在它的依賴發生改變時才會重新求值 注意:Mustache 語法({{}})中不要放入太多的邏輯,否則會讓模板過重、難以理解和維護 注意:computed 中的屬性不能與 data 中的屬性同名,否則會報錯 Vue computed 屬性原理 var vm=new Vue({ el: "#app", data: { firstname: "jack", lastname: "rose" }, computed: { fullname() { return this.firstname + "." + this.lastname; } } }); 1 2 3 4 5 6 7 8 9 10 11 12 1 2 3 4 5 6 7 8 9 10 11 12 實例生命周期 所有的 Vue 組件都是 Vue 實例,并且接受相同的選項對象即可 (一些根實例特有的選項除外)。 實例生命周期也叫做:組件生命周期 生命周期介紹 ?> 生命周期鉤子函數的定義:從組件被創建,到組件掛載到頁面上運行,再到頁面關閉組件被卸載,這三個階段總是伴隨著組件各種各樣的事件,這些事件,統稱為組件的生命周期函數! vue 生命周期鉤子函數 簡單說:一個組件從開始到最后消亡所經歷的各種狀態,就是一個組件的生命周期 注意:Vue 在執行過程中會自動調用生命周期鉤子函數,我們只需要提供這些鉤子函數即可 注意:鉤子函數的名稱都是 Vue 中規定好的! 鉤子函數 - beforeCreate() 說明:在實例初始化之后,數據觀測 (data observer) 和 event/watcher 事件配置之前被調用 注意:此時,無法獲取 data 中的數據、methods 中的方法 鉤子函數 - created() 注意:這是一個常用的生命周期,可以調用 methods 中的方法、改變 data 中的數據 vue 實例生命周期 參考 1 vue 實例生命周期 參考 2 使用場景:發送請求獲取數據 鉤子函數 - beforeMounted() 說明:在掛載開始之前被調用 鉤子函數 - mounted() 說明:此時,vue 實例已經掛載到頁面中,可以獲取到 el 中的 DOM 元素,進行 DOM 操作 鉤子函數 - beforeUpdated() 說明:數據更新時調用,發生在虛擬 DOM 重新渲染和打補丁之前。你可以在這個鉤子中進一步地更改狀態,這不會觸發附加的重渲染過程。 注意:此處獲取的數據是更新后的數據,但是獲取頁面中的 DOM 元素是更新之前的 鉤子函數 - updated() 說明:組件 DOM 已經更新,所以你現在可以執行依賴于 DOM 的操作。 鉤子函數 - beforeDestroy() 說明:實例銷毀之前調用。在這一步,實例仍然完全可用。 使用場景:實例銷毀之前,執行清理任務,比如:清除定時器等 鉤子函數 - destroyed() 說明:Vue 實例銷毀后調用。調用后,Vue 實例指示的所有東西都會解綁定,所有的事件監聽器會被移除,所有的子實例也會被銷毀。 vue 單文件組件 vue-loader single-file components(單文件組件) 后綴名:.vue,該文件需要被預編譯后才能在瀏覽器中使用 注意:單文件組件依賴于兩個包 vue-loader / vue-template-compiler 安裝:cnpm i -D vue-loader vue-template-compiler 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 // webpack.config.js 配置: module: { rules: [ { test: /\.vue$/, loader: "vue-loader" } ]; } 1 2 3 4 5 6 7 8 9 1 2 3 4 5 6 7 8 9 使用單文件組件 /* main.js */ import Vue from "vue"; // 導入 App 組件 import App from "./App.vue"; const vm=new Vue({ el: "#app", // 通過 render 方法,渲染App組件 render: c=> c(App) }); 1 2 3 4 5 6 7 8 9 10 11 1 2 3 4 5 6 7 8 9 10 11 單文件組件使用步驟 1 安裝:cnpm i -D vue-loader vue-template-compiler 2 在 webpack.config.js 中配置 .vue 文件的 loader { test: /\.vue$/, use: 'vue-loader' } 3 創建 App.vue 單文件組件,注意:App 可以是任意名稱 4 在 main.js 入口文件中,導入 vue 和 App.vue 組件,通過 render 將組件與實例掛到一起 單文件組件+路由 vue - Vue.use Vue.use 和 路由 import Vue from "vue"; import App from "./App.vue"; // ------------- vue路由配置 開始 -------------- import Home from "./components/home/Home.vue"; import Login from "./components/login/Login.vue"; // 1 導入 路由模塊 import VueRouter from "vue-router"; // 2 ** 調用use方法使用插件 ** Vue.use(VueRouter); // 3 創建路由對象 const router=new VueRouter({ routes: [ { path: "/home", component: Home }, { path: "/login", component: Login } ] }); // ------------- vue路由配置 結束 -------------- const vm=new Vue({ el: "#app", render: c=> c(App), // 4 掛載到 vue 實例中 router }); 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 Mint-UI 基于 Vue.js 的移動端組件庫 Mint-UI 安裝:cnpm i -S mint-ui // 1 導入 mint-ui模塊 import MintUI from "mint-ui"; // 2 導入 樣式 import "mint-ui/lib/style.css"; // 3 注冊插件 Vue.use(MintUI); 1 2 3 4 5 6 1 2 3 4 5 6 MUI MUI MUI 也是移動端的 UI 庫 使用:從 github 下載包,找到 dist 文件夾,只需要導入樣式即可 // 只需要導入 MUI的樣式 即可,根據MUI的例子,直接使用HTML結果即可 // 導入樣式 import "./lib/mui/css/mui.min.css"; 1 2 3 1 2 3 ElementUI 這是 PC 端的 UI 組件庫 安裝:cnpm i -S element-ui 餓了么 - ElementUI { "presets": [ ["es2015", { "modules": false }], "stage-0" ], "plugins": [ ["component", [ { "libraryName": "mint-ui", "style": true }, { "libraryName": "element-ui", "styleLibraryName": "theme-default" } ]] ] } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 axios 以 Promise 為基礎的 HTTP 客戶端,適用于:瀏覽器和 node.js 封裝 ajax,用來發送請求,異步獲取數據 安裝:cnpm i -S axios github axios 文檔 // 在瀏覽器中使用,直接引入js文件使用下面的GET/POST請求方式即可 // 1 引入 axios.js // 2 直接調用axios提供的API發送請求 created: function () { axios.get(url) .then(function(resp) {}) } // 配合 webpack 使用方式如下: import Vue from 'vue' import axios from 'axios' // 將 axios 添加到 Vue.prototype 中 Vue.prototype.$axios=axios // 在組件中使用: methods: { getData() { this.$axios.get('url') .then(res=> {}) .catch(err=> {}) } } // API使用方式: axios.get(url[, config]) axios.post(url[, data[, config]]) axios(url[, config]) axios(config) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 axios - Get 請求 const url="http://vue.studyit.io/api/getnewslist"; // url中帶有query參數 axios .get("/user?id=89") .then(function(response) { console.log(response); }) .catch(function(error) { console.log(error); }); // url和參數分離,使用對象 axios.get("/user", { params: { id: 12345 } }); 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 axios - Post 請求 不同環境中處理 POST 請求 ?> 默認情況下,axios 會將 JS 對象序列化為 JSON 對象。為了使用 application/x-www-form-urlencoded 格式發送請求,我們可以這樣: // 使用 qs 包,處理將對象序列化為字符串 // npm i -S qs // var qs=require('qs') import qs from 'qs' qs.stringify({ 'bar': 123 })===> "bar=123" axios.post('/foo', qs.stringify({ 'bar': 123 })) // 或者: axios.post('/foo', 'bar=123&age=19') 1 2 3 4 5 6 7 8 9 1 2 3 4 5 6 7 8 9 const url="http://vue.studyit.io/api/postcomment/17"; axios.post(url, "content=點個贊不過份"); axios .post( "/user", qs.stringify({ firstName: "Fred", lastName: "Flintstone" }) ) .then(function(response) { console.log(response); }) .catch(function(error) { console.log(error); }); 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 axios 全局配置 // 設置請求公共路徑: axios.defaults.baseURL="http://vue.studyit.io"; 1 2 1 2 axios 攔截器 攔截器會攔截發送的每一個請求,請求發送之前執行 request 中的函數,請求發送完成之后執行 response 中的函數 // 請求攔截器 axios.interceptors.request.use( function(config) { // 所有請求之前都要執行的操作 return config; }, function(error) { // 錯誤處理 return Promise.reject(error); } ); // 響應攔截器 axios.interceptors.response.use( function(response) { // 所有請求完成后都要執行的操作 return response; }, function(error) { // 錯誤處理 return Promise.reject(error); } ); 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 vue 自定義指令 作用:進行 DOM 操作 使用場景:對純 DOM 元素進行底層操作,比如:文本框獲得焦點 vue 自定義指令用法實例 兩種指令:1. 全局指令 2. 局部指令 全局自定義指令 // 第一個參數:指令名稱 // 第二個參數:配置對象,指定指令的鉤子函數 Vue.directive('directiveName', { // bind中只能對元素自身進行DOM操作,而無法對父級元素操作 // 只調用一次 指令第一次綁定到元素時調用。在這里可以進行一次性的初始化設置。 bind( el,binding, vnode ) { // 參數詳解 // el:指令所綁定的元素,可以用來直接操作 DOM 。 // binding:一個對象,包含以下屬性: // name:指令名,不包括 v- 前綴。 // value:指令的綁定值,等號后面的值 。 // oldValue:指令綁定的前一個值,僅在 update 和 componentUpdated 鉤子中可用。無論值是否改變都可用。 // expression:字符串形式的指令表達式 等號后面的字符串 形式 // arg:傳給指令的參數,可選。例如 v-my-directive:foo 中,參數為 "foo"。 // modifiers:指令修飾符。例如:v-directive.foo.bar中,修飾符對象為 { foo: true, bar: true }。 // vnode:Vue 編譯生成的虛擬節點。。 // oldVnode:上一個虛擬節點,僅在 update 和 componentUpdated 鉤子中可用。 }, // inserted這個鉤子函數調用的時候,當前元素已經插入頁面中了,也就是說可以獲取到父級節點了 inserted ( el,binding, vnode ) {}, // DOM重新渲染前 update(el,binding, vnode,oldVnode) {}, // DOM重新渲染后 componentUpdated ( el,binding, vnode,oldVnode ) {}, // 只調用一次,指令與元素解綁時調用 unbind ( el ) { // 指令所在的元素在頁面中消失,觸發 } }) // 簡寫 如果你想在 bind 和 update 時觸發相同行為,而不關心其它的鉤子: Vue.directive('自定義指令名', function( el, binding ) {}) // 例: Vue.directive('color', function(el, binding) { el.style.color=binging.value }) // 使用 注意直接些會被i成data中的數據“red” 需要字符串則嵌套引號"'red'" 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 局部自定義指令 vue 剖析 Vue 原理&實現雙向綁定 MVVM var vm=new Vue({ el: "#app", directives: { directiveName: {} } }); 1 2 3 4 5 6 1 2 3 4 5 6 組件 組件系統是 Vue 的另一個重要概念,因為它是一種抽象,允許我們使用小型、獨立和通常可復用的組件構建大型應用。仔細想想,幾乎任意類型的應用界面都可以抽象為一個組件樹 #### 全局組件 說明:全局組件在所有的 vue 實例中都可以使用 注意:先注冊組件,再初始化根實例 // 1 注冊全局組件 Vue.component('my-component', { // template 只能有一個根元素 template: '

          A custom component!

          ', // 組件中的 `data` 必須是函數 并且函數的返回值必須是對象 data() { return { msg: '注意:組件的data必須是一個函數?。。? } } }) // 2 使用:以自定義元素的方式

          //=====> 渲染結果

          A custom component!

          // 3 template屬性的值可以是: - 1 模板字符串 - 2 模板id template: '#tpl' 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 extend:使用基礎 Vue 構造器,創建一個“子類”。參數是一個包含組件選項的對象。 // 注冊組件,傳入一個擴展過的構造器 Vue.component( "my-component", Vue.extend({ /* ... */ }) ); // 注冊組件,傳入一個選項對象 (自動調用 Vue.extend) Vue.component("my-component", { /* ... */ }); var Home=Vue.extend({ template: "", data() {} }); Vue.component("home", Home); 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 局部組件 說明:局部組件,是在某一個具體的 vue 實例中定義的,只能在這個 vue 實例中使用 var Child={ template: "

          A custom component!

          • " }; new Vue({ // 注意:此處為 components components: { // 將只在當前vue實例中使用 // my-component 為組件名 值為配置對象 "my-component": { template: ``, data() { return {}; }, props: [] } } }); 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 is 特性 在某些特定的標簽中只能存在指定表恰 如 ul > li 如果要瀏覽器正常解析則需要使用 is 正常識別

          1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 組件通訊 父組件到子組件(父子組件傳值) 方式:通過子組件props屬性來傳遞數據 props是一個數組 注意:屬性的值必須在組件中通過props屬性顯示指定,否則,不會生效 說明:傳遞過來的props屬性的用法與data屬性的用法相同

          1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 子組件到父組件 方式:父組件給子組件傳遞一個函數,由子組件調用這個函數 說明:借助 vue 中的自定義事件(v-on:cunstomFn=“fn”) 步驟: 1、在父組件中定義方法 parentFn 2、在子組件 組件引入標簽 中綁定自定義事件 v-on:自定義事件名=“父組件中的方法”==> @pfn=“parentFn” 3、子組件中通過emit()觸發自定義事件事件this. emit()觸發自定義事件事件 this.emit()觸發自定義事件事件this.emit(pfn,參數列表。。。) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 非父子組件通訊 ?> 在簡單的場景下,可以使用一個空的 Vue 實例作為事件總線 $on():綁定自定義事件 var bus=new Vue(); // 在組件 B 綁定自定義事件 bus.$on("id-selected", function(id) { // ... }); // 觸發組件 A 中的事件 bus.$emit("id-selected", 1); 1 2 3 4 5 6 7 1 2 3 4 5 6 7 示例:組件 A —> 組件 B 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 內容分發 通過 標簽指定內容展示區域 我是額外的內容

          1 2 3 4 5 6 7 1 2 3 4 5 6 7 // js代碼 new vue({ el: "#app", components: { hello: { template: `

          我是子組件中的內容

          ` } } }); 1 2 3 4 5 6 7 8 9 10 11 12 13 14 1 2 3 4 5 6 7 8 9 10 11 12 13 14 獲取組件(或元素) - refs 說明:vm.$refs 一個對象,持有已注冊過 ref 的所有子組件(或 HTML 元素) 使用:在 HTML 元素 中,添加 ref 屬性,然后在 JS 中通過 vm.$refs.屬性來獲取 注意:如果獲取的是一個子組件,那么通過 ref 就能獲取到子組件中的 data 和 methods

          1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 SPA -單頁應用程序 SPA: Single Page Application ?> 單頁 Web 應用(single page application,SPA),就是只有一個 Web 頁面的應用, 是加載單個 HTML 頁面,并在用戶與應用程序交互時動態更新該頁面的 Web 應用程序。 單頁面應用程序: 只有第一次會加載頁面, 以后的每次請求, 僅僅是獲取必要的數據.然后, 由頁面中 js 解析獲取的數據, 展示在頁面中 傳統多頁面應用程序: 對于傳統的多頁面應用程序來說, 每次請求服務器返回的都是一個完整的頁面 優勢 1 減少了請求體積,加快頁面響應速度,降低了對服務器的壓力 2 更好的用戶體驗,讓用戶在 web app 感受 native app 的流暢 實現思路和技術點 1 ajax 2 錨點的使用(window.location.hash #) 3 hashchange 事件 window.addEventListener(“hashchange”,function () {}) 4 監聽錨點值變化的事件,根據不同的錨點值,請求相應的數據 5 原本用作頁面內部進行跳轉,定位并展示相應的內容 路由 路由即:瀏覽器中的哈希值(# hash)與展示視圖內容(template)之間的對應規則 vue 中的路由是:hash 和 component 的對應關系 在 Web app 中,通過一個頁面來展示和管理整個應用的功能。 SPA 往往是功能復雜的應用,為了有效管理所有視圖內容,前端路由 應運而生! 簡單來說,路由就是一套映射規則(一對一的對應規則),由開發人員制定規則。 當 URL 中的哈希值(# hash)發生改變后,路由會根據制定好的規則,展示對應的視圖內容 基本使用 安裝:cnpm i -S vue-router

          首頁 登錄

          1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 重定向 // 將path 重定向到 redirect { path: '/', redirect: '/home' } 1 2 1 2 路由其他配置 路由導航高亮 說明:當前匹配的導航鏈接,會自動添加 router-link-exact-active router-link-active 類 配置:linkActiveClass 匹配路由模式 配置:mode new Router({ routers: [], mode: "hash", //默認hash | history 可以達到隱藏地址欄hash值 | abstract,如果發現沒有瀏覽器的 API 則強制進入 linkActiveClass: "now" //當前匹配的導航鏈接將被自動添加now類 }); 1 2 3 4 5 1 2 3 4 5 路由參數 說明:我們經常需要把某種模式匹配到的所有路由,全都映射到同一個組件,此時,可以通過路由參數來處理 語法:/user/:id 使用:當匹配到一個路由時,參數值會被設置到 this.$route.params 其他:可以通過 $route.query 獲取到 URL 中的查詢參數 等 如果你需要在模版中使用路由參數 可以這樣 {{$router.params.id}} 用戶 Rose 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 嵌套路由 - 子路由 路由是可以嵌套的,即:路由中又包含子路由 規則:父組件中包含 router-view,在路由規則中使用 children 配置 // 父組件: const User=Vue.component("user", { template: `

          User Center

          個人資料 崗位

          ` }); // 子組件[簡寫] const UserProfile={ template: "

          個人資料:張三

          " }; const UserPosts={ template: "

          崗位:FE

          " }; // 路由 var router=new Router({ routers: [ { path: "/user", component: User, // 子路由配置: children: [ { // 當 /user/profile 匹配成功, // UserProfile 會被渲染在 User 的 中 path: "profile", component: UserProfile }, { // 當 /user/posts 匹配成功 // UserPosts 會被渲染在 User 的 中 path: "posts", component: UserPosts } ] } ] }); 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 前端模塊化 ?> 為什么需要模塊化 最開始的 js 就是為了實現客戶端驗證以及一些簡單的效果 后來,js 得到重視,應用越來越廣泛,前端開發的復雜度越來越高 舊版本的 js 中沒有提供與模塊(module)相關的內容 模塊的概念 在 js 中,一個模塊就是實現特定功能的文件(js 文件) 遵循模塊的機制,想要什么功能就加載什么模塊 模塊化開發需要遵循規范 模塊化解決的問題 命名沖突 文件依賴(加載文件) 模塊的復用 統一規范和開發方式 JS 實現模塊化的規范 AMD 瀏覽器端 requirejs CommonJS nodejs 加載模塊:require() 導出模塊:module.exports={} / exports={} ES6 中的 import / export CMD 瀏覽器端 玉伯(阿里前端大神) -> seajs UMD 通用模塊化規范,可以兼容 AMD、CommonJS、瀏覽器中沒有模塊化規范 等這些語法 AMD 的使用 Asynchronous Module Definition:異步模塊定義,瀏覽器端模塊開發的規范 代表:require.js 特點:模塊被異步加載,模塊加載不影響后面語句的運行 1、定義模塊 // 語法:define(name, dependencies?, factory); // name表示:當前模塊的名稱,是一個字符串 可有可無 // dependencies表示:當前模塊的依賴項,是一個數組無論依賴一項還是多項 無則不寫 // factory表示:當前模塊要完成的一些功能,是一個函數 // 定義對象模塊 define({}); // 定義方法模塊 define(function() { return {}; }); // 定義帶有依賴項的模塊 define(["js/a"], function() {}); 1 2 3 4 5 6 7 8 9 10 11 12 13 1 2 3 4 5 6 7 8 9 10 11 12 13 2、加載模塊 // - 注意:require 的第一個參數必須是數組 // 參數必須是數組 表示模塊路徑 以當前文件為基準,通過回調函數中的參數獲取加載模塊中的變量 參數與模塊按照順序一一對應 require(["a", "js/b"], function(a, b) { // 使用模塊a 和 模塊b 中的代碼 }); 1 2 3 4 5 1 2 3 4 5 3、路徑查找配置 requirejs 默認使用 baseUrl+paths 的路徑解析方式 可以使用以下方式避開此設置: 以.js結尾 以 / 開始 包含協議:https:// 或 http:// // 配置示例 // 注意配置應當在使用之前 require.config({ baseUrl: "./js" // 配置基礎路徑為:當前目錄下的js目錄 }); require(["a"]); // 查找 基礎路徑下的 ./js/a.js // 簡化加載模塊路徑 require.config({ baseUrl: "./js", // 配置一次即可,直接通過路徑名稱(template || jquery)加載模塊 paths: { template: "assets/artTemplate/template-native", jquery: "assets/jquery/jquery.min" } }); // 加載jquery template模塊 require(["jquery", "template"]); 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 4、非模塊化和依賴項支持 添加模塊的依賴模塊,保證加載順序(deps) 將非模塊化模塊,轉化為模塊化(exports) // 示例 require.config({ baseUrl: "./js", paths: { // 配置路徑 noModule: "assets/demo/noModule" }, // 配置不符合規范的模塊項 shim: { // 模塊名稱 noModule: { deps: [], // 依賴項 exports: "sayHi" // 導出模塊中存在的函數或變量 } } }); // 注意點 如果定義模塊的時候,指定了模塊名稱,需要使用該名稱來引用模塊 // 定義 這個模塊名稱與paths中的名稱相同 define("moduleA", function() {}); // 導入 require.config({ paths: { // 此處的模塊名:moduleA moduleA: "assets/demo/moduleA" } }); 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 5、路徑加載規則 路徑配置的優先級: 通過 config 配置規則查找 通過 data-main 指定的路徑查找 以引入 requirejs 的頁面所在路徑為準查找 1 2 3 4 5 6 1 2 3 4 5 6 Webpack webpack 文檔 bundle [?b?ndl] 捆綁,收集,歸攏,把…塞入 webpack 將帶有依賴項的各個模塊打包處理后,變成了獨立的瀏覽器能夠識別的文件 webpack 合并以及解析帶有依賴項的模塊 概述 webpack 是一個現代 JavaScript 應用程序的模塊打包器(特點 module、 bundler) webpack 是一個模塊化方案(預編譯) webpack 獲取具有依賴關系的模塊,并生成表示這些模塊的靜態資源 四個核心概念:入口(entry)、輸出(output)、加載器loader、插件(plugins) 對比 模塊化方案: webpack 和 requirejs(通過編寫代碼的方式將前端的功能,劃分成獨立的模塊) browserify 是與 webpack 相似的模塊化打包工具 webpack 預編譯 (在開發階段通過 webpack 進行模塊化處理, 最終項目上線, 就不在依賴于 webpack) requirejs 線上的編譯( 代碼運行是需要依賴于 requirejs 的 ) webpack 起源 webpack 解決了現存模塊打包器的兩個痛點: 1 Code Spliting - 代碼分離 按需加載 2 靜態資源的模塊化處理方案 webpack 與模塊 前端模塊系統的演進 在 webpack 看來:所有的靜態資源都是模塊 webpack 模塊能夠識別以下等形式的模塊之間的依賴: JS 的模塊化規范: ES2015 import export CommonJS require() module.exports AMD define 和 require 非 JS 等靜態資源: css/sass/less 文件中的 @import 圖片連接,比如:樣式 url(...) 或 HTML

          字體 等 入門 Webpack,看這篇就夠了 安裝 webpack 全局安裝:cnpm i -g webpack 目的:在任何目錄中通過 CLI 使用 webpack 這個命令 項目安裝:cnpm i -D webpack 目的:執行當前項目的構建 webpack 的基本使用 安裝:npm i -D webpack webpack 的兩種使用方式:1 命令行 2 配置文件(webpack.config.js) 命令行方式演示 - 案例:隔行變色 1 使用npm init -y 初始package.json,使用 npm 來管理項目中的包 2 新建 index.html 和 index.js,實現隔行變色功能 3 運行webpack src/js/index.js dist/bundle.js進行打包構建,語法是:webpack 入口文件 輸出文件 4 注意:需要在頁面中引入 輸出文件 的路徑(此步驟可通過配置 webpack 去掉) /* src/js/index.js */ // 1 導入 jQuery import $ from "jquery"; // 2 獲取頁面中的li元素 const $lis=$("#ulList").find("li"); // 3 隔行變色 // jQuery中的 filter() 方法用來過濾jquery對象 $lis.filter(":odd").css("background-color", "#def"); $lis.filter(":even").css("background-color", "skyblue"); //命令行運行 `webpack src/js/index.js dist/bundle.js 目錄生成在命令行運行目錄 /* 運行流程: 1、webpack 根據入口找到入口文件 2、分析js中的模塊化語法 3、將所有關聯文件 打包合并輸出到出口 */ 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 webpack-dev-server 配置 一、package.json 配置方式 安裝:cnpm i -D webpack-dev-server 作用:配合 webpack,創建開發環境(啟動服務器、監視文件變化、自動編譯、刷新瀏覽器等),提高開發效率 注意:無法直接在終端中執行 webpack-dev-server,需要通過 package.json 的 scripts 實現 使用方式:cnpm run dev // 參數解釋 注意參數是無序的 有值的參數空格隔開 // --open 自動打開瀏覽器 // --contentBase ./ 指定瀏覽器 默認打開的頁面路徑中的 index.html 文件 // --open 自動打開瀏覽器 // --port 8080 端口號 // --hot 熱更新,只加載修改的文件(按需加載修改的內容),而非全部加載 "scripts": { "dev": "webpack-dev-server --open --contentBase ./ --port 8080 --hot" } 1 2 3 4 5 6 7 8 9 1 2 3 4 5 6 7 8 9 二、webpack.config.js 配置方式(推薦) var path=require('path') module.exports={ // 入口文件 entry: path.join(__dirname, 'src/js/index.js'), // 輸出文件 output: { path: path.join(__dirname, 'dist'), // 輸出文件的路徑 filename: 'bundle.js' // 輸出文件的名稱 } } const webpack=require('webpack') devServer: { // 服務器的根目錄 Tell the server where to serve content from // https://webpack.js.org/configuration/dev-server/#devserver-contentbase contentBase: path.join(__dirname, './'), // 自動打開瀏覽器 open: true, // 端口號 port: 8888, // --------------- 1 熱更新 ----------------- hot: true }, plugins: [ // ---------------- 2 啟用熱更新插件 ---------------- new webpack.HotModuleReplacementPlugin() ] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 html-webpack-plugin 插件 安裝:cnpm i -D html-webpack-plugin 作用:根據模板,自動生成 html 頁面 優勢:頁面存儲在內存中,自動引入bundle.js、css等文件 /* webpack.config.js */ const htmlWebpackPlugin=require("html-webpack-plugin"); plugins: [ new htmlWebpackPlugin({ // 模板頁面路徑 template: path.join(__dirname, "./index.html"), // 在內存中生成頁面路徑,默認值為:index.html filename: "index.html" }) ]; 1 2 3 4 5 6 7 8 9 10 1 2 3 4 5 6 7 8 9 10 Loaders(加載器) webpack - Loaders webpack - 管理資源示例 webpack 只能處理 JavaScript 資源 webpack 通過 loaders 處理非 JavaScript 靜態資源 1、 CSS 打包 安裝:cnpm i -D style-loader css-loader 注意:use 中模塊的順序不能顛倒,加載順序:從右向左加載 /* 在index.js 導入 css 文件*/ import "./css/app.css"; /* webpack.config.js 配置各種資源文件的loader加載器*/ module: { // 配置匹配規則 rules: [ // test 用來配置匹配文件規則(正則) // use 是一個數組,按照從后往前的順序執行加載 { test: /\.css$/, use: ["style-loader", "css-loader"] } ]; } 1 2 3 4 5 6 7 8 9 10 11 12 1 2 3 4 5 6 7 8 9 10 11 12 2、 使用 webpack 打包 sass 文件 安裝:cnpm i -D sass-loader node-sass 注意:sass-loader 依賴于 node-sass 模塊 /* webpack.config.js */ // 參考:https://webpack.js.org/loaders/sass-loader/#examples // "style-loader" :creates style nodes from JS strings 創建style標簽 // "css-loader" :translates CSS into CommonJS 將css轉化為CommonJS代碼 // "sass-loader" :compiles Sass to CSS 將Sass編譯為css module: { rules: [ { test: /\.(scss|sass)$/, use: ["style-loader", "css-loader", "sass-loader"] } ]; } 1 2 3 4 5 6 7 8 9 10 11 12 13 1 2 3 4 5 6 7 8 9 10 11 12 13 3、 圖片和字體打包 安裝:cnpm i -D url-loader file-loader file-loader:加載并重命名文件(圖片、字體 等) url-loader:將圖片或字體轉化為 base64 編碼格式的字符串,嵌入到樣式文件中 /* webpack.config.js */ module: { rules: [ // 打包 圖片文件 { test: /\.(jpg|png|gif|jpeg)$/, use: "url-loader" }, // 打包 字體文件 { test: /\.(woff|woff2|eot|ttf|otf)$/, use: "file-loader" } ]; } 1 2 3 4 5 6 7 8 9 10 1 2 3 4 5 6 7 8 9 10 圖片打包細節 limit 參數的作用:(單位為:字節(byte)) 當圖片文件大小(字節)小于指定的 limit 時,圖片被轉化為base64編碼格式 當圖片文件大小(字節)大于等于指定的 limit 時,圖片被重命名以 url 路徑形式加載(此時,需要 file-loader 來加載圖片) 圖片文件重命名,保證相同文件不會被加載多次。例如:一張圖片(a.jpg)拷貝一個副本(b.jpg),同時引入這兩張圖片,重命名后只會加載一次,因為這兩張圖片就是同一張 文件重命名以后,會通過 MD5 加密的方式,來計算這個文件的名稱 /* webpack.config.js */ module: { rules: [ // {test: /\.(jpg|png|gif|jpeg)$/, use: 'url-loader?limit=100'}, { test: /\.(jpg|png|gif|jpeg)$/, use: [ { loader: "url-loader", options: { limit: 8192 } } ] } ]; } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 字體文件打包說明 處理方式與圖片相同,可以使用:file-loader或url-loader babel babel babel 全家桶 安裝:cnpm i -D babel-core babel-loader 安裝:cnpm i -D babel-preset-env 基本使用(兩步) 第一步: /* webpack.config.js */ module: { rules: [ // exclude 排除,不需要編譯的目錄,提高編譯速度 { test: /\.js$/, use: "babel-loader", exclude: /node_modules/ } ]; } 1 2 3 4 5 6 7 1 2 3 4 5 6 7 第二步:在項目根目錄中新建.babelrc配置文件 /* 創建 .babelrc 文件*/ // 將來babel-loader運行的時候,會檢查這個配置文件,并讀取相關的語法和插件配置 { "presets": ["env"] } 1 2 3 4 5 1 2 3 4 5 babel 的說明 babel 的作用: 1 語法轉換:將新的 ES 語法轉化為瀏覽器能識別的語法(babel-preset-*) 2 polyfill 瀏覽器兼容:讓低版本瀏覽器兼容最新版 ES 的 API babel-preset-* Babel 通過語法轉換器,能夠支持最新版本的 JavaScript 語法 babel-preset-* 用來指定我們書寫的是什么版本的 JS 代碼 作用:將新的 ES 語法轉化為瀏覽器能識別的 ES5 代碼 ES6 語法提案的批準流程 ES2015 也就是 ES6, 下一個版本是 ES7, 從 ES6 到 ES7 之間經歷了 5 個階段 babel-preset-es2015 轉換 es6 的語法 babel-preset-stage-0 轉換比 es6 更新的語法 Stage 0 - Strawman(展示階段) Stage 1 - Proposal(征求意見階段) Stage 2 - Draft(草案階段) Stage 3 - Candidate(候選人階段) Stage 4 - Finished(定案階段) 1 2 3 4 5 總結 babel-core babel 核心包 babel-loader 用來解析 js 文件 babel-preset-* 新 ES 語法的解析和轉換 transform-runtime / babel-polyfill 兼容舊瀏覽器,到達支持新 API 目的 // 判斷瀏覽器是否兼容 padStart 這個 API if (!String.prototype.padStart) { // 如果不兼容, 就自己模擬 padStart的功能實現一份 String.prototype.padStart=function padStart(targetLength, padString) {}; } 1 2 3 4 5 1 2 3 4 5 Webpack 發布項目 webpack 打包的各種坑 webpack 命令能夠生成dist目錄到磁盤中,最終,把打包后的代碼,部署服務器中去 webpack-dev-server 僅是在內存中生成的文件,并沒有寫到磁盤中,所以,只能在開發期間使用 創建項目發布配置文件 開發期間配置文件:webpack.config.js 項目發布配置文件:webpack.prod.js (文件名稱非固定 production 生產環境) 命令:webpack --config webpack.prod.js 指定配置文件名稱運行 webpack 參數:–display-error-details 用于顯示 webpack 打包的錯誤信息 /* package.json */ "scripts": { "build": "webpack --config webpack.prod.js" } 1 2 3 4 5 1 2 3 4 5 在項目根目錄中創建 webpack.prod.js 文件 在 package.json 中, 配置一個 scripts 在 終端中 通過 npm run build 對項目進行打包 打包處理過程 刪除掉 devServer 相關的配置項 將圖片和字體文件輸出到指定的文件夾中 自動刪除 dist 目錄 分離第三方包(將使用的 vue 等第三方包抽離到 vender.js 中) 壓縮混淆 JS 以及 指定生成環境 抽取和壓縮 CSS 文件 壓縮 HTML 頁面 配合 vue 的異步組件,實現按需加載功能 處理圖片路徑 注意:如果 limit 小于比圖片大,那么圖片將被轉化為 base64 編碼格式 name 參數介紹 /* webpack.prod.js */ // 處理URL路徑的loader { test: /\.(jpg|png|gif|bmp|jpeg)$/, use: { loader: 'url-loader', options: { limit: 8192, name: 'images/[hash:7].[ext]' // 作用:將圖片輸出到images文件夾中,文件名采用7位的哈希值(MD5),并且保持原來的圖片文件擴展名 // name:指定文件輸出路徑和輸出文件命令規則 // [hash:7]:表示使用7位哈希值代表文件名稱 // [ext]:表示保持文件原有后綴名 // name: 'imgs/img-[hash:7].[ext]' } } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 自動刪除 dist 目錄 安裝:cnpm i -D clean-webpack-plugin 作用: 每次打包之前, 刪除上一次打包的 dist 目錄 /* webpack.prod.js */ const cleanWebpackPlugin=require("clean-webpack-plugin"); plugins: [ // 創建一個刪除文件夾的插件,刪除dist目錄 new cleanWebpackPlugin(["./dist"]) ]; 1 2 3 4 5 6 7 1 2 3 4 5 6 7 分離第三方包 目的:將公共的第三方包,抽離為一個單獨的包文件,這樣防止重復打包! 例如:main.js、router、vuex中都引入了 vue,不分離的話,vue 會被打包 3 次 抽離后, vue 文件只會被打包一次, 用到的地方僅僅是引用 /* webpack.prod.js */ // 1 入口 -- 打包文件的入口 entry: { // 項目代碼入口 app: path.join(__dirname, './src/js/main.js'), // 第三方包入口 vendor: ['vue', 'vue-router', 'axios'] }, output: { // 2 修改輸出文件路徑和命名規則 filename: 'js/[name].[chunkhash].js', }, plugins: [ // 3 抽離第三方包 new webpack.optimize.CommonsChunkPlugin({ // 將 entry 中指定的 ['vue', 'vue-router', 'axios'] 打包到名為 vendor 的js文件中 // 第三方包入口名稱,對應 entry 中的 vendor 屬性 name: 'vendor', }), ] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 壓縮混淆 JS 注意:uglifyjs 無法壓縮 ES6 的代碼 plugins: [ // 優化代碼 // https://github.com/webpack-contrib/uglifyjs-webpack-plugin/tree/v0.4.6 new webpack.optimize.UglifyJsPlugin({ // 壓縮 compress: { // 移除警告 warnings: false } }), // 指定環境為生產環境:vue會根據這一項啟用壓縮后的vue文件 new webpack.DefinePlugin({ "process.env": { NODE_ENV: JSON.stringify("production") } }) ]; 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 抽取和壓縮 CSS 文件 安裝:抽離 cnpm i -D extract-text-webpack-plugin 安裝:壓縮 cnpm i -D optimize-css-assets-webpack-plugin webpack 抽離 CSS 文檔 壓縮抽離后的 CSS 壓縮和抽離 CSS 報錯的說明: Error processing file: css/style.css postcss-svgo: Error in parsing SVG: Unquoted attribute value 1 2 1 2 原因:壓縮和抽離 CSS 的插件中只允許 SVG 使用雙引號 /* webpack.prod.js */ // 分離 css 到獨立的文件中 const ExtractTextPlugin=require("extract-text-webpack-plugin"); // 壓縮 css 資源文件 const OptimizeCssAssetsPlugin=require('optimize-css-assets-webpack-plugin') // bug描述: 生成后面的css文件中圖片路徑錯誤,打開頁面找不到圖片 // 解決:google搜索 webpack css loader 樣式圖片路徑 output: { // https://doc.webpack-china.org/configuration/output/#output-publicpath // 設置公共路徑 publicPath: '/', }, module: { rules: [ { test: /\.css$/, use: ExtractTextPlugin.extract({ fallback: "style-loader", use: "css-loader" }) }, { test: /\.scss$/, use: ExtractTextPlugin.extract({ fallback: "style-loader", use: ['css-loader', 'sass-loader'] }) }, ] }, plugins: [ // 通過插件抽離 css (參數) new ExtractTextPlugin("css/style.css"), // 抽離css 的輔助壓縮插件 new OptimizeCssAssetsPlugin() ] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 壓縮 HTML 頁面 詳細的配置可以參考html-minifier new htmlWebpackPlugin({ // 模板頁面 template: path.join(__dirname, './index.html'), // 壓縮HTML minify: { // 移除空白 collapseWhitespace: true, // 移除注釋 removeComments: true, // 移除屬性中的雙引號 removeAttributeQuotes: true } }), 1 2 3 4 5 6 7 8 9 10 11 12 13 14 1 2 3 4 5 6 7 8 9 10 11 12 13 14 vue 配合 webpack 實現路由按需加載 Vue 路由懶加載 Vue 異步組件 Vue 組件懶加載淺析 步驟 1 修改組件的引用方式 // 方式一: require.ensure() const NewsList=r=> require.ensure( [], ()=> r(require("../components/news/newslist.vue")), "news" ); // 方式二: import() -- 推薦 // 注意:/* webpackChunkName: "newsinfo" */ 是一個特殊的語法,表示生成js文件的名稱 const NewsInfo=()=> import(/* webpackChunkName: "newsinfo" */ "../components/news/newsinfo.vue"); 1 2 3 4 5 6 7 8 9 10 11 1 2 3 4 5 6 7 8 9 10 11 2 修改 webpack 配置文件的 output output: { // ------添加 chunkFilename, 指定輸出js文件的名稱------ chunkFilename: 'js/[name].[chunkhash].js', }


          主站蜘蛛池模板: 国内精品一区二区三区最新| 国产主播福利精品一区二区| 精品人妻无码一区二区色欲产成人 | 国产一区二区福利久久| 久久精品岛国av一区二区无码| 国产成人精品亚洲一区| 一区二区三区四区无限乱码| 国产日韩一区二区三区在线播放| 国产AV一区二区三区无码野战| 国产三级一区二区三区| 久久久国产精品亚洲一区 | 亚洲av午夜精品一区二区三区| 理论亚洲区美一区二区三区| 亚洲国产视频一区| 国产成人午夜精品一区二区三区| 久久99国产精品一区二区| 国产精品视频一区二区噜噜| 香蕉视频一区二区三区| 精品亚洲一区二区三区在线播放| 欧美日韩国产免费一区二区三区| 无码人妻一区二区三区在线水卜樱 | 国精产品999一区二区三区有限 | 国产人妖视频一区在线观看| 69久久精品无码一区二区| 一区国产传媒国产精品| 精品在线视频一区| 亚洲一区影音先锋色资源| 久夜色精品国产一区二区三区| 精品一区二区久久| 亚洲一本一道一区二区三区 | 国产a久久精品一区二区三区| 男人免费视频一区二区在线观看| 亚洲美女高清一区二区三区| 精品无码av一区二区三区 | 国产精品一区电影| 久久一区二区明星换脸| 日韩精品一区二区三区在线观看| 精品一区二区三区在线视频| 精品无码成人片一区二区| 亚洲AV无码一区二区三区人| 久久国产精品免费一区|