1. 程式人生 > 其它 >Vue筆記(狂神說)

Vue筆記(狂神說)

學習自狂神說

一、前端核心分析

1.1、概述

Soc原則:關注點分離原則

Vue 的核心庫只關注檢視層,方便與第三方庫或既有專案整合。

HTML + CSS + JS : 檢視 : 給使用者看,重新整理後臺給的資料

網路通訊 : axios

頁面跳轉 : vue-router

狀態管理:vuex

Vue-UI : ICE , Element UI

1.2、前端三要素

  • HTML(結構):超文字標記語言(Hyper Text Markup Language),決定網頁的結構和內容
  • CSS(表現):層疊樣式表(Cascading Style Sheets),設定網頁的表現樣式。
  • JavaScript(行為):是一種弱型別指令碼語言,其原始碼不需經過編譯,而是由瀏覽器解釋執行,用於控制網頁的行為

1.3、結構層(HTML)

太簡單,略

1.4、表現層(CSS)

CSS層疊樣式表是一門標記語言,並不是程式語言,因此不可以自定義變數,不可以引用等,換句話說就是不具備任何語法支援,它主要缺陷如下:

  • 語法不夠強大,比如無法巢狀書寫,導致模組化開發中需要書寫很多重複的選擇器;
  • 沒有變數和合理的樣式複用機制,使得邏輯上相關的屬性值必須以字面量的形式重複輸出,導致難以維護;這就導致了我們在工作中無端增加了許多工作量。為了解決這個問題,前端開發人員會使用一種稱之為【CSS前處理器】的工具,提供CSS缺失的樣式層複用機制、減少冗餘程式碼,提高樣式程式碼的可維護性。大大的提高了前端在樣式上的開發效率。

什麼是CSS前處理器:

CSS前處理器定義了一種新的語言,其基本思想是,用一種專門的程式語言,為CSS增加了一些程式設計的特性,將CSS作為目標生成檔案,然後開發者就只需要使用這種語言進行CSS的編碼工作。轉化成通俗易懂的話來說就是“用一種專門的程式語言,進行Web頁面樣式設計,再通過編譯器轉化為正常的CSS檔案,以供專案使用”。

常用的CSS前處理器有哪些

  • SASS:基於Ruby ,通過服務端處理,功能強大。解析效率高。需要學習Ruby語言,上手難度高於LESS。
  • LESS:基於NodeJS,通過客戶端處理,使用簡單。功能比SASS簡單,解析效率也低於SASS,但在實際開發中足夠了,所以如果我們後臺人員如果需要的話,建議使用LESS。

1.5、行為層(JavaScript)

JavaScript一門弱型別指令碼語言,其原始碼在發往客戶端執行之前不需要經過編譯,而是將文字格式的字元程式碼傳送給瀏覽器,由瀏覽器解釋執行。

Native 原生JS開發

原生JS開發,也就是讓我們按照【ECMAScript】標準的開發方式,簡稱ES,特點是所有瀏覽器都支援。截至到當前,ES標準以釋出如下版本:

  • ES3
  • ES4(內部,未正式釋出)
  • ES5(全瀏覽器支援)
  • ES6(常用,當前主流版本:webpack打包成為ES5支援)
  • ES7
  • ES8
  • ES9(草案階段)

區別就是逐步增加新特性。
TypeScript 微軟的標準
TypeScript是一種由微軟開發的自由和開源的程式語言。它是JavaScript的一個超集, 而且本質上向這個語言添加了可選的靜態型別和基於類的面向物件程式設計。由安德斯·海爾斯伯格(C#、Delphi、TypeScript之父; .NET創立者) 主導。該語言的特點就是除了具備ES的特性之外還納入了許多不在標準範圍內的新特性,所以會導致很多瀏覽器不能直接支援TypeScript語法, 需要編譯後(編譯成JS) 才能被瀏覽器正確執行。

JavaScript框架

  • JQuery:大家熟知的JavaScript庫,優點就是簡化了DOM操作,缺點就是DOM操作太頻繁,影響前端效能;在前端眼裡使用它僅僅是為了相容IE6,7,8;
  • Angular:Google收購的前端框架,由一群Java程式設計師開發,其特點是將後臺的MVC模式搬到了前端並增加了模組化開發的理念,與微軟合作,採用了TypeScript語法開發;對後臺程式設計師友好,對前端程式設計師不太友好;最大的缺點是版本迭代不合理(如1代–>2 代,除了名字,基本就是兩個東西;截止發表部落格時已推出了Angular6)
  • React:Facebook 出品,一款高效能的JS前端框架;特點是提出了新概念 【虛擬DOM】用於減少真實 DOM 操作,在記憶體中模擬 DOM操作,有效的提升了前端渲染效率;缺點是使用複雜,因為需要額外學習一門【JSX】語言;
  • Vue:一款漸進式 JavaScript 框架,所謂漸進式就是逐步實現新特性的意思,如實現模組化開發、路由、狀態管理等新特性。其特點是綜合了 Angular(模組化)和React(虛擬 DOM) 的優點;
  • Axios前端通訊框架;因為 Vue 的邊界很明確,就是為了處理 DOM,所以並不具備通訊能力,此時就需要額外使用一個通訊框架與伺服器互動;當然也可以直接選擇使用jQuery 提供的AJAX 通訊功能;

二、前端發展史

2.1、UI框架

  • Ant-Design:阿里巴巴出品,基於React的UI框架
  • ElementUI、iview、ice:餓了麼出品,基於Vue的UI框架
  • BootStrap:Teitter推出的一個用於前端開發的開源工具包
  • AmazeUI:又叫“妹子UI”,一款HTML5跨屏前端框架

2.2、JavaScript構建工具

  • Babel:JS編譯工具,主要用於瀏覽器不支援的ES新特性,比如用於編譯TypeScript
  • WebPack:模組打包器,主要作用就是打包、壓縮、合併及按序載入
  • 注:以上知識點已將WebApp開發所需技能全部梳理完畢

2.3、三端同一

混合開發(Hybrid App)

主要目的是實現一套程式碼三端統一(PC、Android:.apk、iOS:.ipa)並能夠呼叫到裝置底層硬體(如:感測器、GPS、攝像頭等),打包方式主要有以下兩種:

  • 雲打包:HBuild -> HBuildX,DCloud 出品;API Cloud
  • 本地打包: Cordova(前身是 PhoneGap)

微信小程式

詳見微信官網,這裡就是介紹一個方便微信小程式UI開發的框架:WeUI

2.4、後端技術

前端人員為了方便開發也需要掌握一定的後端技術但我們Java後臺人員知道後臺知識體系極其龐大複雜,所以為了方便前端人員開發後臺應用,就出現了Node JS這樣的技術。Node JS的作者已經聲稱放棄Node JS(說是架構做的不好再加上笨重的node modules,可能讓作者不爽了吧)開始開發全新架構的De no
既然是後臺技術,那肯定也需要框架和專案管理工具, Node JS框架及專案管理工具如下:

  • Express:Node JS框架
  • Koa:Express簡化版
  • NPM:專案綜合管理工具,類似於Maven
  • YARN:NPM的替代方案,類似於Maven和Gradle的關係

2.5、主流前端框架
Vue.js

iView

iview是一個強大的基於Vue的UI庫, 有很多實用的基礎元件比element ui的元件更豐富, 主要服務於PC介面的中後臺產品。使用單檔案的Vue元件化開發模式基於npm+webpack+babel開發, 支援ES 2015高質量、功能豐富友好的API, 自由靈活地使用空間。

  • 官網地址
  • Github
  • iview-admin

備註:屬於前端主流框架,選型時可考慮使用,主要特點是移動端支援較多

Element UI

Element是餓了麼前端開源維護的Vue UI元件庫, 元件齊全, 基本涵蓋後臺所需的所有元件,文件講解詳細, 例子也很豐富。主要用於開發PC端的頁面, 是一個質量比較高的Vue UI元件庫。
·官網地址
·Git hub
·vue-element-admin
備註:屬於前端主流框架,選型時可考慮使用,主要特點是桌面端支援較多

ICE

飛冰是阿里巴巴團隊基於React/Angular/Vue的中後臺應用解決方案, 在阿里巴巴內部, 已經有270多個來自幾乎所有BU的專案在使用。飛冰包含了一條從設計端到開發端的完整鏈路,幫助使用者快速搭建屬於自己的中後臺應用。

  • 官網地址。
  • Git hub

備註:主要元件還是以React為主, 截止2019年02月17日更新部落格前對Vue的支援還不太完善,目前尚處於觀望階段

VantUI

Vant UI是有贊前端團隊基於有贊統一的規範實現的Vue元件庫, 提供了-整套UI基礎元件和業務元件。通過Vant, 可以快速搭建出風格統一的頁面,提升開發效率。

官網地址
Github
AtUI

at-ui是一款基於Vue 2.x的前端UI元件庫, 主要用於快速開發PC網站產品。它提供了一套n pm+web pack+babel前端開發工作流程, CSS樣式獨立, 即使採用不同的框架實現都能保持統一的UI風格。
·官網地址
·Git hub

Cube Ul

cube-ui是滴滴團隊開發的基於Vue js實現的精緻移動端元件庫。支援按需引入和後編譯, 輕量靈活;擴充套件性強,可以方便地基於現有元件實現二次開發。

  • 官網地址
  • Github

混合開發

Flutter

Flutter是谷歌的移動端UI框架, 可在極短的時間內構建Android和iOS上高質量的原生級應用。Flutter可與現有程式碼一起工作, 它被世界各地的開發者和組織使用, 並且Flutter是免費和開源的。

  • 官網地址

Github
備註:Google出品, 主要特點是快速構建原生APP應用程式, 如做混合應用該框架為必選框架

lonic

lonic既是一個CSS框架也是一個Javascript UI庫, lonic是目前最有潛力的一款HTML 5手機應用開發框架。通過SASS構建應用程式, 它提供了很多UI元件來幫助開發者開發強大的應用。它使用JavaScript MV VM框架和Angular JS/Vue來增強應用。提供資料的雙向繫結, 使用它成為Web和移動開發者的共同選擇。

官網地址
·官網文件
·Git hub

  • 微信小程式
  • mpvue

mpvue是美團開發的一個使用Vue.js開發小程式的前端框架, 目前支援微信小程式、百度智慧小程式,頭條小程式和支付寶小程式。框架基於Vue.js, 修改了的執行時框架runtime和程式碼編譯器compiler實現, 使其可執行在小程式環境中, 從而為小程式開發引入了Vue.js開發體驗。
·官網地址
·Git hub
備註:完備的Vue開發體驗, 井且支援多平臺的小程式開發, 推薦使用

WeUI

WeUI是一套同微信原生視覺體驗一致的基礎樣式庫, 由微信官方設計團隊為微信內網頁和微信小程式量身設計, 令使用者的使用感知更加統一。包含button、cell、dialog、toast、article、icon等各式元素。

  • 官網地址
  • Github

三、瞭解前後分離的演變史

為什麼需要前後分離

3.1、後端為主的MVC時代

為了降低開發的複雜度, 以後端為出發點, 比如:Struts、Spring MVC等框架的使用, 就是後端的MVC時代;
以SpringMVC流程為例:

  • 發起請求到前端控制器(Dispatcher Servlet)
  • 前端控制器請求HandlerMapping查詢Handler,可以根據xml配置、註解進行查詢
  • 處理器對映器HandlerMapping向前端控制器返回Handler
  • 前端控制器呼叫處理器介面卡去執行Handler
  • 處理器介面卡去執行Handler
  • Handler執行完成給介面卡返回ModelAndView
  • 處理器介面卡向前端控制器返回ModelAndView,ModelAndView是SpringMvc框架的一個底層物件,包括Model和View
  • 前端控制器請求檢視解析器去進行檢視解析,根據邏輯檢視名解析成真正的檢視(JSP)
  • 檢視解析器向前端控制器返回View
  • 前端控制器進行檢視渲染,檢視渲染將模型資料(在ModelAndView物件中)填充到request域
  • 前端控制器向用戶響應結果

優點
MVC是一個非常好的協作模式, 能夠有效降低程式碼的耦合度從架構上能夠讓開發者明白程式碼應該寫在哪裡。為了讓View更純粹, 還可以使用Thyme leaf、Frree marker等模板引擎, 使模板裡無法寫入Java程式碼, 讓前後端分工更加清晰。
缺點

  • 前端開發重度依賴開發環境,開發效率低,這種架構下,前後端協作有兩種模式:
  • 第一種是前端寫DEMO, 寫好後, 讓後端去套模板。好處是DEMO可以本地開發, 很高效。不足是還需要後端套模板,有可能套錯,套完後還需要前端確定,來回溝通調整的成本比較大;
  • 另一種協作模式是前端負責瀏覽器端的所有開發和伺服器端的View層模板開發。好處是UI相關的程式碼都是前端去寫就好,後端不用太關注,不足就是前端開發重度繫結後端環境,環境成為影響前端開發效率的重要因素。
  • 前後端職責糾纏不清:模板引擎功能強大,依舊可以通過拿到的上下文變數來實現各種業務邏輯。這樣,只要前端弱勢一點,往往就會被後端要求在模板層寫出不少業務程式碼,還有一個很大的灰色地帶是Controller, 頁面路由等功能本應該是前端最關注的, 但卻是由後端來實現。Controller本身與Model往往也會糾纏不清,看了讓人咬牙的業務程式碼經常會出現在Controller層。這些問題不能全歸結於程式設計師的素養, 否則JSP就夠了。
  • 對前端發揮的侷限性:效能優化如果只在前端做空間非常有限,於是我們經常需要後端合作,但由於後端框架限制,我們很難使用[Comet】、【Big Pipe】等技術方案來優化效能。

注:在這期間(2005年以前) , 包括早期的JSP、PHP可以稱之為Web 1.0時代。在這裡想說一句, 如果你是一名Java初學者, 請你不要再把一些陳舊的技術當回事了, 比如JSP, 因為時代在變、技術在變、什麼都在變(引用扎克伯格的一句話:唯一不變的是變化本身);當我們去給大學做實訓時,有些同學會認為我們沒有講什麼乾貨,其實不然,只能說是你認知裡的乾貨對於市場來說早就過時了而已

3.2、基於AJAX帶來的SPA時代

時間回到2005年A OAX(Asynchronous JavaScript And XML, 非同步JavaScript和XML,老技術新用法)被正式提出並開始使用CDN作為靜態資源儲存, 於是出現了JavaScript王者歸來(在這之前JS都是用來在網頁上貼狗皮膏藥廣告的) 的SPA(Single Page Application) 單頁面應用時代。

優點
這種模式下, 前後端的分工非常清晰, 前後端的關鍵協作點是AJAX介面。看起來是如此美妙, 但回過頭來看看的話, 這與JSP時代區別不大。複雜度從服務端的JSP裡移到了瀏覽器的JavaScript,瀏覽器端變得很複雜。類似Spring MVC, 這個時代開始出現瀏覽器端的分層架構:

缺點

  • 前後端介面的約定:如果後端的介面一塌糊塗,如果後端的業務模型不夠穩定,那麼前端開發會很痛苦;不少團隊也有類似嘗試,通過介面規則、介面平臺等方式來做。有了和後端一起沉澱的介面規則,還可以用來模擬資料,使得前後端可以在約定介面後實現高效並行開發。
  • 前端開發的複雜度控制:SPA應用大多以功能互動型為主,JavaScript程式碼過十萬行很正常。大量JS程式碼的組織,與View層的繫結等,都不是容易的事情。

3.3、前端為主的MV*時代

此處的MV*模式如下:

  • MVC(同步通訊為主) :Model、View、Controller
  • MVP(非同步通訊為主) :Model、View、Presenter
  • MVVM(非同步通訊為主):Model、View、View Model為了降低前端開發複雜度,湧現了大量的前端框架,比如:Angular JS、React、Vue.js、Ember JS等, 這些框架總的原則是先按型別分層, 比如Templates、Controllers、Models, 然後再在層內做切分,如下圖:

優點

  • 前後端職責很清晰:前端工作在瀏覽器端,後端工作在服務端。清晰的分工,可以讓開發並行,測試資料的模擬不難, 前端可以本地開發。後端則可以專注於業務邏輯的處理, 輸出RESTful等介面。
  • 前端開發的複雜度可控:前端程式碼很重,但合理的分層,讓前端程式碼能各司其職。這一塊蠻有意思的,簡單如模板特性的選擇,就有很多很多講究。並非越強大越好,限制什麼,留下哪些自由,程式碼應該如何組織,所有這一切設計,得花一本書的厚度去說明。
  • 部署相對獨立:可以快速改進產品體驗缺點
  • 程式碼不能複用。比如後端依舊需要對資料做各種校驗,校驗邏輯無法複用瀏覽器端的程式碼。如果可以複用,那麼後端的資料校驗可以相對簡單化。
  • 全非同步, 對SEO不利。往往還需要服務端做同步渲染的降級方案。
  • 效能並非最佳,特別是移動網際網路環境下。
  • SPA不能滿足所有需求, 依舊存在大量多頁面應用。URL Design需要後端配合, 前端無法完全掌控。

3.4、Node JS帶來的全棧時代

前端為主的MV*模式解決了很多很多問題, 但如上所述, 依舊存在不少不足之處。隨著Node JS的興起, JavaScript開始有能力執行在服務端。這意味著可以有一種新的研發模式:

在這種研發模式下,前後端的職責很清晰。對前端來說,兩個UI層各司其職:

  • Front-end Ul layer處理瀏覽器層的展現邏輯。通過CSS渲染樣式, 通過JavaScript新增互動功能, HTML的生成也可以放在這層, 具體看應用場景。
  • Back-end Ul layer處理路由、模板、資料獲取、Cookie等。通過路由, 前端終於可以自主把控URL Design, 這樣無論是單頁面應用還是多頁面應用, 前端都可以自由調控。後端也終於可以擺脫對展現的強關注,轉而可以專心於業務邏輯層的開發。通過Node, WebServer層也是JavaScript程式碼, 這意味著部分程式碼可前後複用, 需要SEO的場景可以在服務端同步渲染,由於非同步請求太多導致的效能問題也可以通過服務端來緩解。前一種模式的不足,通過這種模式幾乎都能完美解決掉。與JSP模式相比, 全棧模式看起來是一種迴歸, 也的確是一種向原始開發模式的迴歸, 不過是一種螺旋上升式的迴歸。**基於Node JS的全棧模式, 依舊面臨很多挑戰:
  • 需要前端對服務端程式設計有更進一步的認識。比如TCP/IP等網路知識的掌握。
  • Node JS層與Java層的高效通訊。Node JS模式下, 都在伺服器端, RESTful HTTP通訊未必高效, 通過SOAP等方式通訊更高效。一切需要在驗證中前行。
  • 對部著、運維層面的熟練了解,需要更多知識點和實操經驗。
  • 大量歷史遺留問題如何過渡。這可能是最大最大的阻力。
  • 注:看到這裡,相信很多同學就可以理解,為什麼我總在課堂上說:“前端想學後臺很難,而我們後端程式設計師學任何東西都很簡單”;就是因為我們後端程式設計師具備相對完善的知識體系。

全棧!So Easy!

3.5、總結

綜上所述,模式也好,技術也罷,沒有好壞優劣之分,只有適合不適合;前後分離的開發思想主要是基於Soc(關注度分離原則),上面種種模式,都是讓前後端的職責更清晰,分工更合理高效。

四、第一個Vue程式

4.1、什麼是MVVM

MVVM(Model-View-ViewModel)是一種軟體設計模式,由微軟WPF(用於替代WinForm,以前就是用這個技術開發桌面應用程式的)和Silverlight(類似於Java Applet,簡單點說就是在瀏覽器上執行WPF)的架構師Ken Cooper和Ted Peters開發,是一種簡化使用者介面的事件驅動程式設計方式。由John Gossman(同樣也是WPF和Sliverlight的架構師)與2005年在他的部落格上發表。

MVVM源自於經典的MVC(Model-View-Controller)模式。MVVM的核心是ViewModel層,負責轉換Model中的資料物件來讓資料變得更容易管理和使用。其作用如下:

  • 該層向上與檢視層進行雙向資料繫結
  • 向下與Model層通過介面請求進行資料互動

MVVM已經相當成熟了,主要運用但不僅僅在網路應用程式開發中。當下流行的MVVM框架有Vue.js,Anfular JS

4.2、為什麼要使用MVVM

MVVM模式和MVC模式一樣,主要目的是分離檢視(View)和模型(Model),有幾大好處

  • 低耦合:檢視(View)可以獨立於Model變化和修改,一個ViewModel可以繫結到不同的View上,當View變化的時候Model可以不變,當Model變化的時候View也可以不變。
  • 可複用:你可以把一些檢視邏輯放在一個ViewModel裡面,讓很多View重用這段檢視邏輯。
  • 獨立開發:開發人員可以專注於業務邏輯和資料的開發(ViewMode),設計人員可以專注於頁面設計。
  • 可測試:介面素來是比較難以測試的,而現在測試可以針對ViewModel來寫。

(1)View

View是檢視層, 也就是使用者介面。前端主要由HTH L和csS來構建, 為了更方便地展現vi eu to del或者Hodel層的資料, 已經產生了各種各樣的前後端模板語言, 比如FreeMarker,Thyme leaf等等, 各大MV VM框架如Vue.js.Angular JS, EJS等也都有自己用來構建使用者介面的內建模板語言。

(2)Model

Model是指資料模型, 泛指後端進行的各種業務邏輯處理和資料操控, 主要圍繞資料庫系統展開。這裡的難點主要在於需要和前端約定統一的介面規則

(3)ViewModel

ViewModel是由前端開發人員組織生成和維護的檢視資料層。在這一層, 前端開發者對從後端獲取的Model資料進行轉換處理, 做二次封裝, 以生成符合View層使用預期的檢視資料模型。
  需要注意的是View Model所封裝出來的資料模型包括檢視的狀態和行為兩部分, 而Model層的資料模型是隻包含狀態的

  • 比如頁面的這一塊展示什麼,那一塊展示什麼這些都屬於檢視狀態(展示)
  • 頁面載入進來時發生什麼,點選這一塊發生什麼,這一塊滾動時發生什麼這些都屬於檢視行為(互動)

檢視狀態和行為都封裝在了View Model裡。這樣的封裝使得View Model可以完整地去描述View層。由於實現了雙向繫結, View Model的內容會實時展現在View層, 這是激動人心的, 因為前端開發者再也不必低效又麻煩地通過操縱DOM去更新檢視。
  MVVM框架已經把最髒最累的一塊做好了, 我們開發者只需要處理和維護View Model, 更新資料檢視就會自動得到相應更新,真正實現事件驅動程式設計。
  View層展現的不是Model層的資料, 而是ViewModel的資料, 由ViewModel負責與Model層互動,獲取和更新資料, 這就完全解耦了View層和Model層, 這個解耦是至關重要的, 它是前後端分離方案實施的重要一環。

4.3、Vue

Vue(讀音/vju/, 類似於view) 是一套用於構建使用者介面的漸進式框架, 釋出於2014年2月。與其它大型框架不同的是, Vue被設計為可以自底向上逐層應用。Vue的核心庫只關注檢視層, 不僅易於上手, 還便於與第三方庫(如:vue-router,vue-resource,vue x) 或既有專案整合。

(1)MVVM模式的實現者

  • Model:模型層, 在這裡表示JavaScript物件
  • View:檢視層, 在這裡表示DOM(HTML操作的元素)
  • ViewModel:連線檢視和資料的中介軟體, Vue.js就是MVVM中的View Model層的實現者

在MVVM架構中, 是不允許資料和檢視直接通訊的, 只能通過ViewModel來通訊, 而View Model就是定義了一個Observer觀察者

  • ViewModel能夠觀察到資料的變化, 並對檢視對應的內容進行更新
  • ViewModel能夠監聽到檢視的變化, 並能夠通知資料發生改變

至此, 我們就明白了, Vue.js就是一個MV VM的實現者, 他的核心就是實現了DOM監聽與資料繫結

(2)為什麼要使用Vue.js

  • 輕量級, 體積小是一個重要指標。Vue.js壓縮後有只有20多kb(Angular壓縮後56kb+,React壓縮後44kb+)
  • 移動優先。更適合移動端, 比如移動端的Touch事件
  • 易上手,學習曲線平穩,文件齊全
  • 吸取了Angular(模組化) 和React(虛擬DOM) 的長處, 並擁有自己獨特的功能,如:計算屬性
  • 開源,社群活躍度高

4.4、第一個Vue程式

【說明】IDEA可以安裝Vue的外掛!
  注意:Vue不支援IE 8及以下版本, 因為Vue使用了IE 8無法模擬的ECMAScript 5特性。但它支援所有相容ECMAScript 5的瀏覽器。

(1)下載地址

開發版本

CDN

(2)程式碼編寫

Vue.js的核心是實現了MVVM模式, 她扮演的角色就是View Model層, 那麼所謂的第一個應用程式就是展示她的資料繫結功能,操作流程如下:

1、建立一個HTML檔案

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

</body>
</html>

2、引入Vue.js

<!--1.匯入Vue.js-->
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.min.js"></script>

3、建立一個Vue例項

<script type="text/javascript">
    var vm = new Vue({
        el:"#app",
        /*Model:資料*/
        data:{
            message:"hello,vue!"
        }
    });
</script>

說明:

  • el: '#vue':繫結元素的ID
  • data:{message:'Hello Vue!'}:資料物件中有一個名為message的屬性,並設定了初始值 Hello Vue!

4、將資料繫結到頁面元素

<!--view層,模板-->
<div id="app">
    {{message}}
</div>

(3)完整的HTML

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>

</head>
<body>

<!--view層,模板-->
<div id="app">
    {{message}}
</div>

<!--1.匯入Vue.js-->
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.min.js"></script>
<script type="text/javascript">
    var vm = new Vue({
        el:"#app",
        /*Model:資料*/
        data:{
            message:"hello,vue!"
        }
    });
</script>
</body>
</html>

(4)測試

為了能夠更直觀的體驗Vue帶來的資料繫結功能, 我們需要在瀏覽器測試一番, 操作流程如下:
  1、在瀏覽器上執行第一個Vue應用程式, 進入開發者工具
  2、在控制檯輸入vm.message=‘HelloWorld’, 然後回車, 你會發現瀏覽器中顯示的內容會直接變成HelloWorld
  此時就可以在控制檯直接輸入vm.message來修改值, 中間是可以省略data的, 在這個操作中, 我並沒有主動操作DOM, 就讓頁面的內容發生了變化, 這就是藉助了Vue的資料繫結功能實現的; MV VM模式中要求View Model層就是使用觀察者模式來實現資料的監聽與繫結, 以做到資料與檢視的快速響應。

五、基礎語法指令

4.1、v-bind

我們已經成功建立了第一個Vue應用!看起來這跟渲染一個字串模板非常類似, 但是Vue在背後做了大量工作。現在資料和DOM已經被建立了關聯, 所有東西都是響應式的。我們在控制檯操作物件屬性,介面可以實時更新!
  我們還可以使用v-bind來繫結元素特性!

<!DOCTYPE html>
<html lang="en" xmlns:v-bind="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="UTF-8">
    <title>Title</title>

</head>
<body>

<!--view層,模板-->
<div id="app">
    <span v-bind:title="message">
    滑鼠懸停幾秒鐘檢視此處動態繫結的提示資訊!
  </span>
</div>

<!--1.匯入Vue.js-->
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.min.js"></script>
<script type="text/javascript">
    var vm = new Vue({
        el:"#app",
        /*Model:資料*/
        data:{
            message: '頁面加載於 ' + new Date().toLocaleString()
        }
    });
</script>
</body>
</html>

你看到的v-bind等被稱為指令。指令帶有字首v以表示它們是Vue提供的特殊特性。可能你已經猜到了, 它們會在渲染的DOM上應用特殊的響應式行為在這裡,該指令的意思是:“將這個元素節點的title特性和Vue例項的message屬性保持一致”。
  如果你再次開啟瀏覽器的JavaScript控制檯, 輸入app, message=‘新訊息’,就會再一次看到這個綁定了title特性的HTML已經進行了更新。

4.2、v-if, v-else

什麼是條件判斷語句,就不需要我說明了吧,以下兩個屬性!

v-if
v-else
上程式碼

<!DOCTYPE html>
<html lang="en" xmlns:v-bind="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<!--view層,模板-->
<div id="app">
    <h1 v-if="ok">Yes</h1>
    <h1 v-else>No</h1>
   
</div>

<!--1.匯入Vue.js-->
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.min.js"></script>
<script type="text/javascript">
    var vm = new Vue({
        el:"#app",
        /*Model:資料*/
        data:{
            type: true
        }
    });
</script>
</body>
</html>

測試:
1.在瀏覽器上執行,開啟控制檯!
2.在控制檯輸入vm.ok=false然後回車,你會發現瀏覽器中顯示的內容會直接變成NO
  注:使用v-*屬性繫結資料是不需要雙花括號包裹的

v-else-if

v-if
v-else-if
v-else

注:===三個等號在JS中表示絕對等於(就是資料與型別都要相等)上程式碼:

<!DOCTYPE html>
<html lang="en" xmlns:v-bind="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<!--view層,模板-->
<div id="app">
    <h1 v-if="type==='A'">A</h1>
    <h1 v-else-if="type==='B'">B</h1>
    <h1 v-else-if="type==='D'">D</h1>
    <h1 v-else>C</h1>

</div>

<!--1.匯入Vue.js-->
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.min.js"></script>
<script type="text/javascript">
    var vm = new Vue({
        el:"#app",
        /*Model:資料*/
        data:{
            type: 'A'
        }
    });
</script>
</body>
</html>

4.3、v-for

  • v-for

格式說明

<div id="app">
    <li v-for="(item,index) in items">
        {{item.message}}---{{index}}
    </li>

</div>

注:items是陣列,item是陣列元素迭代的別名。我們之後學習的Thymeleaf模板引擎的語法和這個十分的相似!
  上程式碼:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<!--view層,模板-->
<div id="app">
    <li v-for="(item,index) in items">
        {{item.message}}---{{index}}
    </li>

</div>

<!--1.匯入Vue.js-->
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.min.js"></script>
<script type="text/javascript">
    var vm = new Vue({
        el:"#app",
        /*Model:資料*/
        data:{
            items:[
                {message:'狂神說Java'},
                {message:'狂神說前端'},
                {message:'狂神說運維'}
            ]
        }
    });
</script>
</body>
</html>

測試:在控制檯輸入vm.items.push({message:'狂神說運維'}),嘗試追加一條資料,你會發現瀏覽器中顯示的內容會增加一條狂神說運維.

4.4、v-on

v-on監聽事件
 emsp;事件有Vue的事件、和前端頁面本身的一些事件!我們這裡的click是vue的事件, 可以繫結到Vue中的methods中的方法事件!
  上程式碼:

<!DOCTYPE html>
<html lang="en" xmlns:v-on="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

<div id="app">
    <button v-on:click="sayHi">點我</button>
</div>

<script src="../js/vue.js"></script>
<script type="text/javascript">
    var vm = new Vue({
        el:"#app",
        data:{
            message:'Hello World'
        },
        methods:{
            sayHi:function(event){
                //'this'在方法裡面指向當前Vue例項
                alert(this.message);
            }
        }
    });
</script>
</body>
</html>

點選測試
  Vue還有一些基本的使用方式, 大家有需要的可以再跟著官方文件看看, 因為這些基本的指令幾乎我們都見過了,一通百通!掌握學習的方式!

六、表單雙綁、元件

6.1、什麼是雙向資料繫結

Vue.js是一個MV VM框架, 即資料雙向繫結, 即當資料發生變化的時候, 檢視也就發生變化, 當檢視發生變化的時候,資料也會跟著同步變化。這也算是Vue.js的精髓之處了。
  值得注意的是,我們所說的資料雙向繫結,一定是對於UI控制元件來說的非UI控制元件不會涉及到資料雙向繫結。單向資料繫結是使用狀態管理工具的前提。如果我們使用vue x那麼資料流也是單項的,這時就會和雙向資料繫結有衝突。

(1)為什麼要實現資料的雙向繫結

在Vue.js中,如果使用vuex, 實際上資料還是單向的, 之所以說是資料雙向繫結,這是用的UI控制元件來說, 對於我們處理表單, Vue.js的雙向資料繫結用起來就特別舒服了。即兩者並不互斥,在全域性性資料流使用單項,方便跟蹤;區域性性資料流使用雙向,簡單易操作。

6.2、在表單中使用雙向資料繫結

你可以用v-model指令在表單、及元素上建立雙向資料繫結。它會根據控制元件型別自動選取正確的方法來更新元素。儘管有些神奇, 但v-model本質上不過是語法糖。它負責監聽使用者的輸入事件以更新資料,並對一些極端場景進行一些特殊處理。
  注意:v-model會忽略所有表單元素的value、checked、selected特性的初始值而總是將Vue例項的資料作為資料來源。你應該通過JavaScript在元件的data選項中宣告初始值!

(1)單行文字

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id="app">
    輸入的文字:<input type="text" v-model="message" value="hello">{{message}}
</div>

<script src="../js/vue.js"></script>
<script type="text/javascript">
    var vm = new Vue({
        el:"#app",
        data:{
            message:""
        }
    });
</script>
</body>
</html>

(2)多行文字

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id="app">
   多行文字:<textarea v-model="pan"></textarea>&nbsp;&nbsp;多行文字是:{{pan}}
</div>

<script src="../js/vue.js"></script>
<script type="text/javascript">
    var vm = new Vue({
        el:"#app",
        data:{
            message:"Hello hello!"
        }
    });
</script>
</body>
</html>

(3)單複選框

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

<div id="app">
    單複選框:
    <input type="checkbox" id="checkbox" v-model="checked">
    &nbsp;&nbsp;
    <label for="checkbox">{{checked}}</label>
</div>

<script src="../js/vue.js"></script>
<script type="text/javascript">
    var vm = new Vue({
        el:"#app",
        data:{
            checked:false
        }
    });
</script>
</body>
</html>

(4)多複選框

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

<div id="app">
    多複選框:
    <input type="checkbox" id="jack" value="Jack" v-model="checkedNames">
    &nbsp;&nbsp;
    <label for="jack">Jack</label>
    <input type="checkbox" id="join" value="Join" v-model="checkedNames">
    &nbsp;&nbsp;
    <label for="join">Jack</label>
    <input type="checkbox" id="mike" value="Mike" v-model="checkedNames">
    &nbsp;&nbsp;
    <label for="mike">Mike</label>
    <span>選中的值:{{checkedNames}}</span>
</div>

<script src="../js/vue.js"></script>
<script type="text/javascript">
    var vm = new Vue({
        el:"#app",
        data:{
            checkedNames:[]
        }
    });
</script>
</body>
</html>

(6)單選按鈕

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

<div id="app">
    單選框按鈕
    <input type="radio" id="one" value="One" v-model="picked">
    <label for="one">One</label>
    <input type="radio" id="two" value="Two" v-model="picked">
    <label for="two">Two</label>
    <span>選中的值:{{picked}}</span>
</div>

<script src="../js/vue.js"></script>
<script type="text/javascript">
    var vm = new Vue({
        el:"#app",
        data:{
            picked:'Two'
        }
    });
</script>
</body>
</html>

(7)下拉框

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id="app">
<!--    性別:
    <input type="radio" name="sex" value="男" v-model="pan">男
    <input type="radio" name="sex" value="女" v-model="pan">女
    <p>選中了:{{pan}}</p>-->

    下拉框:
    <select v-model="pan">
        <option value="" disabled>---請選擇---</option>
        <option>A</option>
        <option>B</option>
        <option>C</option>
        <option>D</option>
    </select>
    <span>value:{{pan}}</span>



</div>

<script src="../js/vue.js"></script>
<script type="text/javascript">
    var vm = new Vue({
        el:"#app",
        data:{
            pan:"A"
        }
    });
</script>
</body>
</html>

注意:v-model表示式的初始值未能匹配任何選項,元系將被渲染為“未選中”狀態。 在iOS中, 這會使使用者無法選擇第一個選項,因為這樣的情況下,iOS不會觸發change事件。因此,更推薦像上面這樣提供一個值為空的禁用選項。

6.3、什麼是元件

元件是可複用的Vue例項, 說白了就是一組可以重複使用的模板, 跟JSTL的自定義標籤、Thymeleal的th:fragment等框架有著異曲同工之妙,通常一個應用會以一棵巢狀的元件樹的形式來組織:

例如,你可能會有頁頭、側邊欄、內容區等元件,每個元件又包含了其它的像導航連結、博文之類的元件。

(1)第一個Vue元件

注意:在實際開發中,我們並不會用以下方式開發元件,而是採用vue-cli建立,vue模板檔案的方式開發,以下方法只是為了讓大家理解什麼是元件。
  使用Vue.component()方法註冊元件,格式如下:

<div id="app">
  <pan></pan>
</div>

<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.min.js"></script>
<script type="text/javascript">
    //先註冊元件
    Vue.component("pan",{
        
        template:'<li>Hello</li>'

    });
    //再例項化Vue
    var vm = new Vue({
        el:"#app",
    });
</script>

說明:

Vue.component():註冊元件
pan:自定義元件的名字
template:元件的模板

(2)使用props屬性傳遞引數

像上面那樣用元件沒有任何意義,所以我們是需要傳遞引數到元件的,此時就需要使用props屬性了!
  注意:預設規則下props屬性裡的值不能為大寫;

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

<div id="app">
    <!--元件:傳遞給元件中的值:props-->
  <pan v-for="item in items" v-bind:panh="item"></pan>
</div>

<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.min.js"></script>
<script type="text/javascript">
    //定義元件
    Vue.component("pan",{
        props:['panh'],
        template:'<li>{{panh}}</li>'

    });
    var vm = new Vue({
        el:"#app",
        data:{
            items:["java","Linux","前端"]
        }
    });
</script>
</body>
</html>

說明:

  • v-for="item in items":遍歷Vue例項中定義的名為items的陣列,並建立同等數量的元件
  • v-bind:panh="item":將遍歷的item項繫結到元件中props定義名為item屬性上;= 號左邊的panh為props定義的屬性名(隨便定義的),右邊的為item in items 中遍歷的item項的值

七、Axios非同步通訊

7.1、什麼是Axios

Axios是一個開源的可以用在瀏覽器端和Node JS的非同步通訊框架, 她的主要作用就是實現AJAX非同步通訊,其功能特點如下:

從瀏覽器中建立XMLHttpRequests
從node.js建立http請求
支援Promise API[JS中鏈式程式設計]
攔截請求和響應
轉換請求資料和響應資料
取消請求
自動轉換JSON資料
客戶端支援防禦XSRF(跨站請求偽造)
GitHub:https://github.com/axios/axios
  中文文件:http://www.axios-js.com/

7.2、為什麼要使用Axios

由於Vue.js是一個檢視層框架並且作者(尤雨溪) 嚴格準守SoC(關注度分離原則)所以Vue.js並不包含AJAX的通訊功能, 為了解決通訊問題, 作者單獨開發了一個名為vue-resource的外掛, 不過在進入2.0版本以後停止了對該外掛的維護並推薦了Axios框架。少用jQuery, 因為它操作Dom太頻繁!

7.3、第一個Axios應用程式

咱們開發的介面大部分都是採用JSON格式, 可以先在專案裡模擬一段JSON資料, 資料內容如下:建立一個名為data.json的檔案並填入上面的內容, 放在專案的根目錄下

1.data.json

{
  "name": "狂神說Java",
  "url": "https://blog.kuangstudy.com",
  "page": 1,
  "isNonProfit": true,
  "address": {
    "street": "含光門",
    "city": "陝西西安",
    "country": "中國"
  },
  "links": [
    {
      "name": "bilibili",
      "url": "https://space.bilibili.com/95256449"
    },
    {
      "name": "狂神說Java",
      "url": "https://blog.kuangstudy.com"
    },
    {
      "name": "百度",
      "url": "https://www.baidu.com/"
    }
  ]
}

2.測試程式碼

<!DOCTYPE html>
<html lang="en" xmlns:v-binf="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <!--v-cloak 解決閃爍問題-->
    <style>
        [v-cloak]{
            display: none;
        }
    </style>
</head>
<body>
<div id="vue">
    <div>地名:{{info.name}}</div>
    <div>地址:{{info.address.country}}--{{info.address.city}}--{{info.address.street}}</div>
    <div>連結:<a v-binf:href="info.url" target="_blank">{{info.url}}</a> </div>
</div>

<!--引入js檔案-->
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.min.js"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script type="text/javascript">
    var vm = new Vue({
        el:"#vue",
        //data:屬性:vm
        data(){
            return{
                info:{
                    name:null,
                    address:{
                        country:null,
                        city:null,
                        street:null
                    },
                    url:null
                }
            }
        },
        mounted(){//鉤子函式
            axios
                .get('data.json')
                .then(response=>(this.info=response.data));
        }
    });
</script>
</body>
</html>

說明:

  1. 在這裡使用了v-bind將a:href的屬性值與Vue例項中的資料進行繫結
  2. 使用axios框架的get方法請求AJAX並自動將資料封裝進了Vue例項的資料物件中
  3. 我們在data中的資料結構必須和Ajax響應回來的資料格式匹配!

7.4、Vue的生命週期

官方文件:https://cn.vuejs.org/v2/guide/instance.html#生命週期圖示
  Vue例項有一個完整的生命週期,也就是從開始建立初始化資料、編譯模板、掛載DOM、渲染一更新一渲染、解除安裝等一系列過程,我們稱這是Vue的生命週期。通俗說就是Vue例項從建立到銷燬的過程,就是生命週期。
  在Vue的整個生命週期中,它提供了一系列的事件,可以讓我們在事件觸發時註冊JS方法,可以讓我們用自己註冊的JS方法控制整個大局,在這些事件響應方法中的this直接指向的是Vue的例項。

八、計算屬性、內容分發、自定義事件

8.1、什麼是計算屬性

計算屬性的重點突出在屬性兩個字上(屬性是名詞),首先它是個屬性其次這個屬性有計算的能力(計算是動詞),這裡的計算就是個函式:簡單點說,它就是一個能夠將計算結果快取起來的屬性(將行為轉化成了靜態的屬性),僅此而已;可以想象為快取!

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<!--view層,模板-->
<div id="app">
    <p>currentTime1:{{currentTime1()}}</p>
    <p>currentTime2:{{currentTime2}}</p>
</div>

<!--1.匯入Vue.js-->
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.min.js"></script>
<script type="text/javascript">
    var vm = new Vue({
        el:"#app",
        data:{
          message:"pan"
        },
        methods:{
            currentTime1:function(){
                return Date.now();//返回一個時間戳
            }
        },
        computed:{
            currentTime2:function(){//計算屬性:methods,computed方法名不能重名,重名之後,只會呼叫methods的方法
                this.message;
                return Date.now();//返回一個時間戳
            }
        }
    });
</script>
</body>
</html>

注意:methods和computed裡的東西不能重名
說明:

  • methods:定義方法, 呼叫方法使用currentTime1(), 需要帶括號
  • computed:定義計算屬性, 呼叫屬性使用currentTime2, 不需要帶括號:this.message是為了能夠讓currentTime2觀察到資料變化而變化
  • 如何在方法中的值發生了變化,則快取就會重新整理!可以在控制檯使用vm.message=”q in jiang", 改變下資料的值,再次測試觀察效果!
  • 結論:
  • 呼叫方法時,每次都需要講行計算,既然有計算過程則必定產生系統開銷,那如果這個結果是不經常變化的呢?此時就可以考慮將這個結果快取起來,採用計算屬性可以很方便的做到這點,計算屬性的主要特性就是為了將不經常變化的計算結果進行快取,以節約我們的系統開銷;

8.2、內容分發

在Vue.js中我們使用元素作為承載分發內容的出口,作者稱其為插槽,可以應用在組合元件的場景中;

測試
比如準備製作一個待辦事項元件(todo) , 該元件由待辦標題(todo-title) 和待辦內容(todo-items)組成,但這三個元件又是相互獨立的,該如何操作呢?
  第一步定義一個待辦事項的元件

<div id="app">
    <todo></todo>
</div>
<!--1.匯入Vue.js-->
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.min.js"></script>
<script type="text/javascript">
    Vue.component('todo',{
        template:'<div>\
                <div>代辦事項</div>\
                <ul>\
                    <li>學習狂神說Java</li>\
                </ul>\
            </div>'
    })
</script>

第二步 我們需要讓,代辦事項的標題和值實現動態繫結,怎麼做呢?我們可以留一個插槽!
  1-將上面的程式碼留出一個插槽,即slot

 Vue.component('todo',{
        template:'<div>\
                <slot name="todo-title"></slot>\
                <ul>\
                    <slot name="todo-items"></slot>\
                </ul>\
            </div>'
    });

2-定義一個名為todo-title的待辦標題元件 和 todo-items的待辦內容元件

Vue.component('todo-title',{
        props:['title'],
        template:'<div>{{title}}</div>'
    });
   
12345
//這裡的index,就是陣列的下標,使用for迴圈遍歷的時候,可以迴圈出來!
    Vue.component("todo-items",{
        props:["item","index"],
        template:"<li>{{index+1}},{{item}}</li>"
    });

3-例項化Vue並初始化資料

 var vm = new Vue({
        el:"#vue",
        data:{
            todoItems:['test1','test2','test3']
        }
    });

4-將這些值,通過插槽插入

<div id="vue">
    <todo>
        <todo-title slot="todo-title" title="秦老師系列課程"></todo-title>
        <!--<todo-items slot="todo-items" v-for="{item,index} in todoItems" v-bind:item="item"></todo-items>-->
        <!--如下為簡寫-->
        <todo-items slot="todo-items" v-for="item in todoItems" :item="item"></todo-items
    </todo>
</div>

說明:我們的todo-title和todo-items元件分別被分發到了todo元件的todo-title和todo-items插槽中
  完整程式碼如下:

程式碼

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<!--view層,模板-->
<div id="vue">
    <todo>
        <todo-title slot="todo-title" title="title"></todo-title>
        <!--<todo-items slot="todo-items" v-for="{item,index} in todoItems" v-bind:item="item"></todo-items>-->
        <!--如下為簡寫-->
        <todo-items slot="todo-items" v-for="item in todoItems" :item="item"></todo-items
    </todo>
</div>
<!--1.匯入Vue.js-->
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.min.js"></script>
<script type="text/javascript">
    Vue.component('todo',{
        template:'<div>\
                <slot name="todo-title"></slot>\
                <ul>\
                    <slot name="todo-items"></slot>\
                </ul>\
            </div>'
    });
    Vue.component('todo-title',{
        props:['title'],
        template:'<div>{{title}}</div>'
    });
    //這裡的index,就是陣列的下標,使用for迴圈遍歷的時候,可以迴圈出來!
    Vue.component("todo-items",{
        props:["item","index"],
        template:"<li>{{index+1}},{{item}}</li>"
    });

    var vm = new Vue({
        el:"#vue",
        data:{
            title:"秦老師系列課程",
            todoItems:['test1','test2','test3']
        }
    });
</script>
</body>
</html>

8.3、自定義事件

通以上程式碼不難發現,資料項在Vue的例項中, 但刪除操作要在元件中完成, 那麼元件如何才能刪除Vue例項中的資料呢?此時就涉及到引數傳遞與事件分發了, Vue為我們提供了自定義事件的功能很好的幫助我們解決了這個問題; 使用this.$emit(‘自定義事件名’, 引數) , 操作過程如下:
  1-在vue的例項中增加了methods物件並定義了一個名為removeTodoltems的方法

var vm = new Vue({
        el:"#vue",
        data:{
            title_text:"秦老師系列課程",
            todoItems:['test1','test2','test3']
        },
        methods:{
            removeItems:function(index){
                console.log("刪除了"+this.todoItems[index]+"OK");
                //splice() 方法向/從陣列中新增/刪除專案,然後返回被刪除的專案,其中index
                this.todoItems.splice(index,1);
            }
        }
    });

2-修改todo-items待辦內容元件的程式碼,增加一個刪除按鈕,並且繫結事件!

 Vue.component("todo-items",{
        props:["item_p","index_p"],
        template:"<li>{{index_p+1}},{{item_p}} <button @click='remove'>刪除</button></li>",
        methods:{
            remove:function (index) {
            //這裡的remove是自定義事件名稱,需要在HTML中使用v-on:remove的方式
                //this.$emit 自定義事件分發
                this.$emit('remove',index);
            }
        }
    });

3-修改todo-items待辦內容元件的HTML程式碼,增加一個自定義事件,比如叫remove,可以和元件的方法繫結,然後繫結到vue的方法!

<!--增加了v-on:remove="removeTodoItems(index)"自定義事件,該元件會呼叫Vue例項中定義的-->
<todo-items slot="todo-items" v-for="(item,index) in todoItems"
                    :item_p="item" :index_p="index" v-on:remove="removeItems(index)" :key="index"></todo-items>

對上一個程式碼進行修改,實現刪除功能

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<!--view層,模板-->
<div id="vue">
    <todo>
        <todo-title slot="todo-title" :title="title_text"></todo-title>
        <!--<todo-items slot="todo-items" v-for="(item,index) in todoItems" v-bind:item="item"></todo-items>-->
        <!--如下為簡寫-->
        <todo-items slot="todo-items" v-for="(item,index) in todoItems"
                    :item_p="item" :index_p="index" v-on:remove="removeItems(index)" :key="index"></todo-items>
    </todo>
</div>
<!--1.匯入Vue.js-->
<script src="../js/vue.js"></script>
<script type="text/javascript">
    Vue.component('todo',{
        template:'<div>\
                <slot name="todo-title"></slot>\
                <ul>\
                    <slot name="todo-items"></slot>\
                </ul>\
            </div>'
    });
    Vue.component('todo-title',{
        props:['title'],
        template:'<div>{{title}}</div>'
    });
    //這裡的index,就是陣列的下標,使用for迴圈遍歷的時候,可以迴圈出來!
    Vue.component("todo-items",{
        props:["item_p","index_p"],
        template:"<li>{{index_p+1}},{{item_p}} <button @click='remove_methods'>刪除</button></li>",
        methods:{
            remove_methods:function (index) {
                //this.$emit 自定義事件分發
                this.$emit('remove',index);
            }
        }
    });

    var vm = new Vue({
        el:"#vue",
        data:{
            title_text:"秦老師系列課程",
            todoItems:['test1','test2','test3']
        },
        methods:{
            removeItems:function(index){
                console.log("刪除了"+this.todoItems[index]+"OK");
                this.todoItems.splice(index,1);
            }
        }
    });
</script>
</body>
</html>

8.4、Vue入門小結

核心:資料驅動,元件化

優點:借鑑了AngularJS的模組化開發React的虛擬Dom,虛擬Dom就是把Demo操作放到記憶體中執行;

常用的屬性:

  • v-if
  • v-else-if
  • v-else
  • v-for
  • v-on繫結事件,簡寫@
  • v-model資料雙向繫結
  • v-bind給元件繫結引數,簡寫:

元件化:

  • 組合元件slot插槽
  • 元件內部繫結事件需要使用到this.$emit("事件名",引數);
  • 計算屬性的特色,快取計算資料

遵循SoC關注度分離原則,Vue是純粹的檢視框架,並不包含,比如Ajax之類的通訊功能,為了解決通訊問題,我們需要使用Axios框架做非同步通訊;

說明
Vue的開發都是要基於NodeJS,實際開發採用Vue-cli腳手架開發,vue-router路由,vuex做狀態管理;Vue UI,介面我們一般使用ElementUI(餓了麼出品),或者ICE(阿里巴巴出品)來快速搭建前端專案~~

官網:

九、第一個vue-cli專案

9.1、什麼是vue-cli

vue-cli官方提供的一個腳手架,用於快速生成一個vue的專案模板;
  預先定義好的目錄結構及基礎程式碼,就好比咱們在建立Maven專案時可以選擇建立一個骨架專案,這個估計專案就是腳手架,我們的開發更加的快速;
  專案的功能

統一的目錄結構
本地除錯
熱部署
單元測試
整合打包上線

9.2、需要的環境

建議不要直接在預設的c盤中,下載先點選這個看

Node.js:http://nodejs.cn/download/
安裝就是無腦的下一步就好,安裝在自己的環境目錄下
Git:https://git-scm.com/doenloads
映象:https://npm.taobao.org/mirrors/git-for-windows/
確認nodejs安裝成功:

cmd下輸入node -v,檢視是否能夠正確打印出版本號即可!
cmd下輸入npm -v,檢視是否能夠正確打印出版本號即可!
這個npm,就是一個軟體包管理工具,就和linux下的apt軟體安裝差不多!
  安裝Node.js淘寶映象加速器(cnpm)
  這樣的話,下載會快很多~

# -g 就是全域性安裝
npm install cnpm -g

# 或使用如下語句解決npm速度慢的問題
npm install --registry=https://registry.npm.taobao.org

安裝的過程可能有點慢~,耐心等待!雖然安裝了cnpm,但是儘量少用!
  安裝的位置:C:\Users\administrator\AppData\Roaming\npm

安裝vue-cli

cnpm instal1 vue-cli-g
#測試是否安裝成功#檢視可以基於哪些模板建立vue應用程式,通常我們選擇webpack
vue list

9.3、第一個vue-cli應用程式

1.建立一個Vue專案,我們隨便建立一個空的資料夾在電腦上,我這裡在D盤下新建一個目錄

D:\Project\vue-study;

2.建立一個基於webpack模板的vue應用程式

#1、首先需要進入到對應的目錄 cd D:\Project\vue-study
#2、這裡的myvue是頂日名稱,可以根據自己的需求起名
vue init webpack myvue

一路都選擇no即可;
  說明:

Project name:專案名稱,預設回車即可
Project description:專案描述,預設回車即可
Author:專案作者,預設回車即可
Install vue-router:是否安裝vue-router,選擇n不安裝(後期需要再手動新增)
Use ESLint to lint your code:是否使用ESLint做程式碼檢查,選擇n不安裝(後期需要再手動新增)
Set up unit tests:單元測試相關,選擇n不安裝(後期需要再手動新增)
Setupe2etests with Nightwatch:單元測試相關,選擇n不安裝(後期需要再手動新增)
Should we run npm install for you after the,project has been created:建立完成後直接初始化,選擇n,我們手動執行;執行結果!
(1)初始化並執行

cd myvue
npm install
npm run dev

執行完成後,目錄多了很多依賴

當出現問題時,可以檢視提示進行處理如下

十、webpack使用

10.1、什麼是Webpack

本質上, webpack是一個現代JavaScript應用程式的靜態模組打包器(module bundler) 。當webpack處理應用程式時, 它會遞迴地構建一個依賴關係圖(dependency graph) , 其中包含應用程式需要的每個模組, 然後將所有這些模組打包成一個或多個bundle.
  Webpack是當下最熱門的前端資源模組化管理和打包工具, 它可以將許多鬆散耦合的模組按照依賴和規則打包成符合生產環境部署的前端資源。還可以將按需載入的模組進行程式碼分離,等到實際需要時再非同步載入。通過loader轉換, 任何形式的資源都可以當做模組, 比如Commons JS、AMD、ES 6、CSS、JSON、Coffee Script、LESS等;
  伴隨著移動網際網路的大潮, 當今越來越多的網站已經從網頁模式進化到了WebApp模式。它們執行在現代瀏覽器裡, 使用HTML 5、CSS 3、ES 6等新的技術來開發豐富的功能, 網頁已經不僅僅是完成瀏覽器的基本需求; WebApp通常是一個SPA(單頁面應用) , 每一個檢視通過非同步的方式載入,這導致頁面初始化和使用過程中會載入越來越多的JS程式碼,這給前端的開發流程和資源組織帶來了巨大挑戰。
  前端開發和其他開發工作的主要區別,首先是前端基於多語言、多層次的編碼和組織工作,其次前端產品的交付是基於瀏覽器的,這些資源是通過增量載入的方式執行到瀏覽器端,如何在開發環境組織好這些碎片化的程式碼和資源,並且保證他們在瀏覽器端快速、優雅的載入和更新,就需要一個模組化系統,這個理想中的模組化系統是前端工程師多年來一直探索的難題。

10.2、模組化的演進

Script標籤

    <script src = "module1.js"></script>
    <script src = "module2.js"></script>
    <script src = "module3.js"></script>

這是最原始的JavaScript檔案載入方式,如果把每一個檔案看做是一個模組,那麼他們的介面通常是暴露在全域性作用域下,也就是定義在window物件中,不同模組的呼叫都是一個作用域。
  這種原始的載入方式暴露了一些顯而易見的弊端:

全域性作用域下容易造成變數衝突
檔案只能按照