你們好,這裏是「 從零開始學 Web 系列教程 」,並在下列地址同步更新......html
- github:https://github.com/Daotin/Web
- 微信公衆號:Web前端之巔
- 博客園:http://www.cnblogs.com/lvonve/
- CSDN:https://blog.csdn.net/lvonve/
在這裏我會從 Web 前端零基礎開始,一步步學習 Web 相關的知識點,期間也會分享一些好玩的項目。如今就讓咱們一塊兒進入 Web 前端學習的冒險之旅吧!前端
Vue.js 是目前最火的一個前端框架,React是最流行的一個前端框架(React除了開發網站,還能夠開發手機App, Vue語法也是能夠用於進行手機App開發的,須要藉助於Weex)vue
Vue.js 是前端的主流框架之一,和Angular.js、React.js 一塊兒,併成爲前端三大主流框架!git
Vue.js 是一套構建用戶界面的框架,只關注視圖層,它不只易於上手,還便於與第三方庫或既有項目整合。(Vue有配套的第三方類庫,能夠整合起來作大型項目的開發)。程序員
在Vue中,一個核心的概念,就是讓用戶再也不操做DOM元素,解放了用戶的雙手,讓程序員能夠更多的時間去關注業務邏輯;github
框架:是一套完整的解決方案;對項目的侵入性較大,項目若是須要更換框架,則須要從新架構整個項目。後端
庫(插件):提供某一個小功能,對項目的侵入性較小,若是某個庫沒法完成某些需求,能夠很容易切換到其它庫實現需求。(好比從 jQuery 切換到 Zepto 等)數組
MVC 是後端的分層開發概念;瀏覽器
M 爲數據層,V 視圖層,C 邏輯層。前端框架
MVVM是前端視圖層的概念,主要關注於 視圖層分離,也就是說:MVVM把前端的視圖層,分爲了 三部分 Model, View , VM ViewModel。
其中 VM 是中間層,負責協調 V 層 和 M 層,V 層即視圖層(對應的就是DOM元素),就是咱們的網頁 html 結構,M 層就是網頁裏面的數據(對應的就是JavaScript對象)。
下圖爲 MVC 和 MVVM 的聯繫圖示:
Vue.js 的基本結構主要分三塊:
一、導入 Vue 的包;
二、body 中的設置一個被 vue 控制的區域(元素);
三、在 script 中 new 一個 vue 實例,參數爲一個對象,對象中通常有三個元素爲 el
,data
,methods
el 則關聯 body 中被 vue 控制的元素的 id 或 類名。
data 則存放頁面的數據;
methods 爲頁面事件對象集合。
示例:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> <!-- 1. 導入Vue的包 --> <script src="./lib/vue-2.4.0.js"></script> </head> <body> <!-- 未來 new 的Vue實例,會控制這個 元素中的全部內容 --> <!-- Vue 實例所控制的這個元素區域,就是咱們的 V --> <div id="app"> <p>{{ msg }}</p> </div> <script> // 2. 建立一個Vue的實例 // 當咱們導入包以後,在瀏覽器的內存中,就多了一個 Vue 構造函數 // 注意:咱們 new 出來的這個 vm 對象,就是咱們 MVVM中的 VM調度者 var vm = new Vue({ el: '#app', // 表示,當前咱們 new 的這個 Vue 實例,要控制頁面上的哪一個區域 // 這裏的 data 就是 MVVM中的 M,專門用來保存 每一個頁面的數據的 data: { // data 屬性中,存放的是 el 中要用到的數據 msg: '歡迎學習Vue'; // 經過 Vue 提供的指令,很方便的就能把數據渲染到頁面上,程序員再也不手動操做DOM元素了【前端的Vue之類的框架,不提倡咱們去手動操做DOM元素了】 } }) </script> </body> </html>
{{ msg }} :在 html 中能夠直接使用 雙重大括號 的方式使用 data 中的數據。
插值表達式就是以雙重大括號 ,相似 {{ msg }}
的形式插入到 html 代碼中。
在 使用 {{ msg }}
的方式插入數據的時候,若是網速特別慢的話, {{ msg }}
所表明的值不會當即顯示出來,而會顯示 {{ msg }} 這個字符串自己,怎麼解決這個問題呢?
使用 v-cloak 和 CSS 表達式結合,可以解決插值表達式閃爍的問題,這樣會在網絡未加載完時,不顯示字符串自己。
示例:
<style> [v-cloak] { display: none; } </style> ... <p v-cloak> {{ msg }} </p>
默認 v-text 是沒有閃爍問題的,可是 v-text 會覆蓋元素中本來的內容,而 v-cloak 只會替換插值表達式,不會把 整個元素的內容清空。
<span v-text="msg"></span>
v-text 知識插入的純文本格式內容,而 v-html 能夠插入爲 html 標籤的代碼,並解析出來。
<span v-html="msg"></span> ... data: { msg: '<h1>哈哈,我是一個大大的H1, 我大,我驕傲</h1>' },
v-bind 是 Vue中,提供的用於綁定屬性的指令。
注意:
v-bind:
指令能夠被簡寫爲:
<input type="button" value="按鈕" v-bind:title="mytitle + '123'"> ... data: { mytitle: '這是一個本身定義的title' },
title 裏面的內容就不是字符串了,而是會將 data 中的變量進行替換獲得一個字符串總體。
v-on 是 Vue 中的事件綁定機制。
注意:
v-on:
指令能夠被簡寫爲@
<input type="button" value="按鈕" :title="mytitle + '123'" v-on:click="show"> ... data: { mytitle: '這是一個本身定義的title' }, methods: { // 這個 methods屬性中定義了當前Vue實例全部可用的方法 show: function () { alert('Hello') } }
在點擊按鈕的時候,會自動調用 methods 中的 show 方法。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> <script src="./lib/vue-2.4.0.js"></script> </head> <body> <div id="box"> <input type="button" value="搖起來" id="btn1" @click="move"> <input type="button" value="停下來" id="btn2" @click="stop"> <h2 v-text="msg"></h2> </div> <script> var vm = new Vue({ el: "#box", data: { msg: "落霞與孤鶩齊飛,秋水共長天一色。", timeId: null }, methods: { move: function () { if (this.timeId != null) { clearInterval(this.timeId); } var that = this; this.timeId = setInterval(function () { var start = that.msg.substring(0, 1); var end = that.msg.substring(1); that.msg = end + start; }, 200); }, stop: function () { clearInterval(this.timeId); } } }); </script> </body> </html>
注意:
一、在 VM 對象實例中,若是想要獲取 data 上的數據,或者 想要調用 methods 中的 方法,必須經過
this.數據屬性名
或this.方法名
來進行訪問,這裏的 this,就表示 咱們 new 出來的 VM 實例對象。二、VM實例,會自動監聽本身身上 data 中全部數據的改變,只要數據一發生變化,就會自動把最新的數據,從data 上同步到頁面中去;【好處:程序員只須要關心數據,不須要考慮如何從新渲染DOM頁面】
v-bind 只能實現數據的單向綁定,從 M 自動綁定到 V(即修改 data 的數據,自動同步到 html), 沒法實現數據的雙向綁定。
使用 v-model 指令,能夠實現 表單元素和 Model 中數據的雙向數據綁定(不只能夠修改 data 的數據,自動同步到 html,也能夠修改 html 的代碼,同步到 data 數據)。
注意: v-model 只能運用在 表單元素中。
示例:
<input type="text" style="width:100%;" v-model="msg"> ... data: { msg: 'hello vue.' },
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <script src="./lib/vue-2.4.0.js"></script> </head> <body> <div id="app"> <input type="text" v-model="n1"> <select v-model="opt"> <option value="+">+</option> <option value="-">-</option> <option value="*">*</option> <option value="/">/</option> </select> <input type="text" v-model="n2"> <input type="button" value="=" @click="calc"> <input type="text" v-model="result"> </div> <script> // 建立 Vue 實例,獲得 ViewModel var vm = new Vue({ el: '#app', data: { n1: 0, n2: 0, result: 0, opt: '+' }, methods: { calc: function() { // 計算器算數的方法 // 邏輯: switch (this.opt) { case '+': this.result = parseFloat(this.n1) + parseFloat(this.n2) break; case '-': this.result = parseFloat(this.n1) - parseFloat(this.n2) break; case '*': this.result = parseFloat(this.n1) * parseFloat(this.n2) break; case '/': this.result = parseFloat(this.n1) / parseFloat(this.n2) break; } } } }); </script> </body> </html>
8.一、v-for 循環普通數組
咱們以前若是要循環賦值給 p 標籤 data中 list=[1,2,3,4,5,6]; 數組的話,會這樣寫:
<body> <div id="app"> <p>{{list[0]}}</p> <p>{{list[1]}}</p> <p>{{list[2]}}</p> <p>{{list[3]}}</p> <p>{{list[4]}}</p> </div> <script> var vm = new Vue({ el: '#app', data: { list: [1, 2, 3, 4, 5, 6] }, methods: {} }); </script> </body>
這樣的話,就會很繁瑣。而 v-for 會提供循環遍歷 list 數組來給 p 標籤賦值。以下:
<body> <div id="app"> <p v-for="(item, i) in list">索引:{{i}} --- 項:{{item}}</p> <!-- 索引:0 --- 項:1 索引:1 --- 項:2 索引:2 --- 項:3 索引:3 --- 項:4 索引:4 --- 項:5 索引:5 --- 項:6 --> </div> <script> var vm = new Vue({ el: '#app', data: { list: [1, 2, 3, 4, 5, 6] }, methods: {} }); </script> </body>
8.二、v-for 循環對象數組
<body> <div id="app"> <p v-for="(user, i) in list">Id:{{ user.id }} --- 名字:{{ user.name }} --- 索引:{{i}}</p> </div> <script> var vm = new Vue({ el: '#app', data: { list: [ { id: 1, name: 'zs1' }, { id: 2, name: 'zs2' }, { id: 3, name: 'zs3' }, { id: 4, name: 'zs4' } ] }, methods: {} }); </script> </body>
8.三、v-for 循環對象
<body> <div id="app"> <!-- 注意:在遍歷對象身上的鍵值對的時候, 除了 有 val key ,在第三個位置還有 一個 索引 --> <p v-for="(val, key, i) in user">值是: {{ val }} --- 鍵是: {{key}} -- 索引: {{i}}</p> </div> <script> var vm = new Vue({ el: '#app', data: { user: { id: 1, name: 'Tony Stark', gender: '男' } }, methods: {} }); </script> </body>
8.四、v-for 循環數字
<body> <div id="app"> <!-- in 後面咱們放過普通數組,對象數組,對象,還能夠放數字 --> <p v-for="count in 10">這是第 {{ count }} 次循環</p> </div> <script> // 建立 Vue 實例,獲得 ViewModel var vm = new Vue({ el: '#app', data: {}, methods: {} }); </script> </body>
注意:若是使用 v-for 迭代數字的話,前面的 count 值從 1 開始。
8.五、v-for 循環 key 屬性
key 屬性可使得每一遍歷的項是惟一的。
<body> <div id="app"> <div> <label>Id: <input type="text" v-model="id"> </label> <label>Name: <input type="text" v-model="name"> </label> <input type="button" value="添加" @click="add"> </div> <!-- 注意: v-for 循環的時候,key 屬性只能使用 number或者string --> <!-- 注意: key 在使用的時候,必須使用 v-bind 屬性綁定的形式,指定 key 的值 --> <!-- 在組件中,使用v-for循環的時候,或者在一些特殊狀況中,若是 v-for 有問題,必須在使用 v-for 的同時,指定 惟一的 字符串/數字 類型 :key 值 --> <p v-for="item in list" :key="item.id"> <input type="checkbox">{{item.id}} --- {{item.name}} </p> </div> <script> // 建立 Vue 實例,獲得 ViewModel var vm = new Vue({ el: '#app', data: { id: '', name: '', list: [ { id: 1, name: '李斯' }, { id: 2, name: '嬴政' }, { id: 3, name: '趙高' }, { id: 4, name: '韓非' }, { id: 5, name: '荀子' } ] }, methods: { add() { // 添加方法 this.list.unshift({ id: this.id, name: this.name }) } } }); </script> </body>
v-if 和 v-show 均可以控制元素的顯示與否。可是實現原理不一樣。
v-if:每次都會從新刪除或建立元素。
v-show : 每次不會從新進行DOM的刪除和建立操做,只是切換了元素的 display:none 樣式。
因此,若是元素涉及到頻繁的切換,最好不要使用 v-if, 而是推薦使用 v-show;
若是元素可能永遠也不會被顯示出來被用戶看到,則推薦使用 v-if。
<h3 v-if="true">這是用v-if控制的元素</h3> <h3 v-show="true">這是用v-show控制的元素</h3>
.stop
: 阻止冒泡
.prevent
: 阻止默認事件(好比點擊超連接,阻止跳轉到默認網頁)
.capture
: 添加事件偵聽器時使用事件捕獲模式(與冒泡模式相反)
.self
:只當事件在該元素自己(好比不是子元素)觸發時觸發回調
.once
:事件只觸發一次,以後還原標籤自己的行爲。
示例:
<div id="app"> <!-- 使用 .stop 阻止冒泡 --> <div class="inner" @click="div1Handler"> <input type="button" value="戳他" @click.stop="btnHandler"> </div> <!-- 使用 .prevent 阻止默認行爲(跳轉到百度首頁) --> <a href="http://www.baidu.com" @click.prevent="linkClick">有問題,先去百度</a> <!-- 使用 .capture 實現捕獲觸發事件的機制:跟冒泡相反,從外到裏--> <div class="inner" @click.capture="div1Handler"> <input type="button" value="戳他" @click="btnHandler"> </div> <!-- 使用 .self 實現只有點擊當前元素時候,纔會觸發事件處理函數 --> <div class="inner" @click.self="div1Handler"> <input type="button" value="戳他" @click="btnHandler"> </div> <!-- 使用 .once 只觸發一次事件處理函數(以下案例只觸發一次點擊事件,以後還原標籤自己的行爲) --> <a href="http://www.baidu.com" @click.prevent.once="linkClick">有問題,先去百度</a> </div>
.stop
和 .self
的區別:
<!-- stop 會阻止冒泡行爲 --> <div class="outer" @click="div2Handler"> <div class="inner" @click="div1Handler"> <input type="button" value="戳他" @click.stop="btnHandler"> </div> </div> <!-- .self 只會阻止本身身上冒泡行爲的觸發,並不會真正阻止冒泡的行爲 --> <div class="outer" @click="div2Handler"> <div class="inner" @click.self="div1Handler"> <input type="button" value="戳他" @click="btnHandler"> </div> </div>
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <script src="./lib/vue-2.4.0.js"></script> <style> .red { color: red; } .thin { font-weight: 200; } .italic { font-style: italic; } .active { letter-spacing: 0.5em; } </style> </head> <body> <div id="app"> <!-- <h1 class="red thin">這是一個很大很大的H1,大到你沒法想象!!!</h1> --> <!-- 第一種使用方式,直接傳遞一個數組,注意: 這裏的 class 須要使用 v-bind 作數據綁定 --> <h1 :class="['thin', 'italic']">這是一個很大很大的H1</h1> <!-- 在數組中使用三元表達式 --> <h1 :class="['thin', 'italic', flag?'active':'']">這是一個很大很大的H1</h1> <!-- 在數組中使用對象來代替三元表達式,提升代碼的可讀性 --> <h1 :class="['thin', 'italic', {active:flag} ]">這是一個很大很大的H1</h1> <!-- 在爲 class 使用 v-bind 綁定 對象的時候,對象的屬性是類名,因爲 對象的屬性可帶引號,也可不帶引號,因此 這裏我沒寫引號; 屬性的值 是一個標識符 --> <h1 :class="classObj">這是一個很大很大的H1</h1> </div> <script> // 建立 Vue 實例,獲得 ViewModel var vm = new Vue({ el: '#app', data: { flag: true, classObj: { red: true, thin: true, italic: false, active: false } }, methods: {} }); </script> </body> </html>
注意:
一、class 樣式須要使用 v-bind 綁定。
二、class 類樣式能夠是數組和對象集合。
能夠是對象,也能夠是對象數組。
<body> <div id="app"> <!-- 對象就是無序鍵值對的集合 --> <h1 :style="styleObj1">這是一個h1</h1> <h1 :style="[ styleObj1, styleObj2 ]">這是一個h1</h1> </div> <script> var vm = new Vue({ el: '#app', data: { styleObj1: { color: 'red', 'font-weight': 200 }, styleObj2: { 'font-style': 'italic' } }, methods: {} }); </script> </body>
注意:要綁定到 style 樣式。