基本介紹
vue是什么
目標:了解vue的一些基礎概念。
官方網站: https://cn.vuejs.org/
vue是:漸進式javascript框架。
兩組概念
(1)框架
- 庫。只提供一些API給開發者使用。jquery 是一個js庫
- 框架。擁有自己的規則和元素,它比庫要更加強大一些。
- UI框架 - bootstrap。包含 js html css 主要實現了一套支撐網站開發的常用控件(對話框,彈出框,tab頁簽…)
- JS框架 - 純js編寫,提供了開發網站功能的標準(規則),約定開發規則,通過這些規則組織你的功能代碼,。
(2)漸進式
- 它可以很簡單,幫助,確保最快上手,最快使用
- 它也可以很復雜,配合不同的工具,在各種復雜的應用場合下工作。
上得廳堂,下得廚房
文可提筆安天下,武可上馬定江山
能做什么
- 充當模板引擎,渲染數據,制作網頁
網頁上的四個要素
- 結構 — html
- 樣式 — css
- 行為 — js
- 數據 — 后端接口返回的json數據
- 通過腳手架工具,開發單頁應用。直接用它來開發網站!
- 在其它框架下開發微信小程序或者跨端,跨平臺應用
小結:啥都能做!
安裝vue
在不同的學習階段有不同的使用方式:
-
基礎階段:直接當做一個普通的js庫來引入使用(與jquery類似)
- 本地方式
- 先下載:https://cn.vuejs.org/js/vue.js
- 然后在你的.html文件中引入:
<script src="./vue.js"></script>
- 直接引入公網中的js
- 引入:
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
- 本地方式
-
項目階段:以npm包的方式來引入
- 安裝
npm i vue
- 導入后使用即可
- 安裝
總結:在基礎學習階段,使用本地下載引入的方式或者公網中的js均可。
體驗vue
第一個vue程序。
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><!-- 2. 視圖 --><div id="app"><h3>{{msg}}</h3><input v-model="msg" type="text"></div><!-- 引入VUE核心js文件 --><script src="./vue.js"></script><!-- 功能代碼 --><script>// 需要把數據渲染到頁面上// 頁面上輸入的內容,收集到數據中// 2. 控制數據模型和視圖管理者const vm = new Vue({el: '#app',// 1. 數據模型data: {msg: 'hi vue'}})</script>
</body>
</html>
安裝live-server插件
在我們寫一些頁面功能時,如果希望實時觀察到效果,可以安裝這個插件。(與學習vue無關)
功能說明
它是一個vscode的插件,它會監聽代碼的改動,一旦我們修改了代碼,它會立即刷新網頁。
安裝過程
使用步驟
- 使用vscode打開某個文件夾 (不是打開單個文件!)
- 打開某個.html文件上,右鍵,在彈出的菜單上選擇
open with live server
此時,它會自動調起瀏覽器,并打開我們當前選擇的.html文件。
補充
另一種打開方式
在當前的.html打開時,在vscode的狀態欄上找到liver-server 的圖標,點擊一次。
更友好的工作模式
在你的電腦屏幕上同時打開vscode和瀏覽器,一邊寫代碼一看效果。
vue的特點
聲明式渲染
允許采用簡潔的模板語法來聲明式地將數據渲染進 DOM 的系統。
<div id="app">{{ message }}
</div>
數據驅動視圖
在vue中,通過修改數據即可更新視圖(頁面),大大解放了操作dom的時間,把精力放在業務上。 所以,我們在寫vue代碼時,會更加關心數據的構成。
雙向數據綁定
vue是一個典型的 MVVM 思想的框架
- M 是數據模型 model
- V 是視圖(界面)view
- VM 是控制數據模型和視圖的管理者
把上面的代碼,可以拆分成,M + V + VM 結構。
數據可以影響視圖變化,視圖變化也會影響數據變化。
組件化開發
把一個網站功能,分割若干個組件,相同類型的組件可復用,組件功能是獨立的,可維護性高。
vue實例和它的三大件
-
el
-
data
-
methods
vue實例
const vm = new Vue({el: ,data: ,methods: ,
})
理解:
- Vue(V是大寫的)是一個構造器,用它來創建vue實例。
- vm就是創建出來的實例對象,
- 這個構造器只有一個參數,這個參數是一個對象,其中的屬性名和屬性值都有特定的含義。
el選項
el選項,用來指定vue實例管理的容器。
<body>{{msg}}<div id="app">{{msg}}<!-- 被管理的容器才可以使用vue提供的功能 --></div><script src="./vue.js"></script><script>// 初始化vue實例,vue實例就是vm的意思const vm = new Vue({// 初始化的配置對象,里面有很多選項// el === element 元素,標簽,容器// el指定當前vue實例管理的容器是誰。// 值是:選擇器 | dom元素// el: '#app',// el: document.querySelector('#app'),// Do not mount Vue to <html> or <body> - mount to normal elements instead.// el不能指定 html 和 body 容器el: 'body',data: {msg: 'hi vue'}})</script>
</body>
</html>
要點:
- 可以是選擇器,也可以是某個dom元素
- 只能是普通的dom(div,p),不能是 html,body 容器
- 不在此容器內的部分,不會受到vue實例影響
data選項
作用:它是一個對象,它用來規定數據。
<div id="app"><h3>理解data</h3><p>姓名:{{name}}</p><p>愛好1:{{aihao[0]}}</p><p>愛好2:{{aihao[1]}}</p><ul><li>QQ:{{lianxi.QQ}}</li><li>email:{{lianxi.email}}</li><li>weixin:{{lianxi.weixin}}</li></ul></div><script>// data: 它是一個對象,用來規定數據。// 現在是把vue當作一個模板引擎來使用。// 它的作用是把數據顯示在頁面上。data就是用來// 約定數據的。// 在后面的學習的,這個部分的數據會是// 從ajax接口中獲取到的// 訪問數據:// 方法一:在視圖中,通過{{}}插值表達式 直接訪問。/// 不要寫data.XXX - 不要寫data - 不要寫data// 方法二:通過Vue實例vm來訪問// vm.XXXconst vm = new Vue({el: "#app",// el: document.getElementById("app"),data: {name: '凡哥-凡叔',aihao:['聽音樂','讀書'],lianxi: {QQ:"123456",email:'xxxxxx',weixin:'yyyyyy'}}})console.log(vm)console.log(vm.name)console.log(vm.aihao[1])console.log(vm.lianxi.QQ)</script>
訪問方式:
- 通過實例可以直接訪問data中的數據 vm.msg
- 在模板中使用數據的字段名稱即可。{{msg}}
注意:
- 在data中顯性聲明的數據,都是響應式數據,可以數據驅動視圖。
- 在模板中使用的數據,建議在data中提前聲明,即使沒有值也需要聲明。
methods選項
目標:知道vue選項中methods選項的使用方法和注意事項。
作用:為vue實例提供自定義函數的(大白話:自己的業務函數書寫位置)
調用方法:
- vue實例直接調用,且函數的this指向就是vue實例,就是vm
- 在vue實例管理的模板(管理的容器|視圖)中使用這些函數
// Vue構造器中的參數是一個對象,它有很多的屬性// el,// data// methods// ... 還有好多好多....// methods 是一個對象// 在對象中,正常定義函數// (1) 定義函數// (2) 調用函數// 1. 通過vm實例來調用// 2. 也可以在頁面上,通過{{函數名}}來調用 --不推薦--// 3. 當做事件的回調函數來使用。const vm = new Vue({el: "#app",data: {name: '凡哥-凡叔'},methods: {// 定義函數// 函數用來做你自己業務邏輯// 方法1:"changeName1": function() {console.log('changeName1')this.name = "小凡1"},// 方法2:推薦// es6中支持對對象中的方法的簡寫changeName2 () {console.log('changeName2')console.log(this == vm)this.name = "小凡2"},// 方法3:箭頭函數。// 其中的this是有問題!!// 這里的this指向的是window,而不是vm實例// 所以,不能使用this來操作數據。changeName3: () => {console.log('changeName3')console.log(this)this.name = "小凡3"}}})// console.log(vm)// vm.changeName2()// vm.changeName1()
注意:
書寫函數有很多方式
- 普通的寫法
- es6簡寫格式 (推薦使用)
- 有箭頭函數 (不使用。因為其中的this不指向vue實例)
在函數的內部(不是箭頭函數的情況)
- this會指向vue實例。
插值表達式
目標:了解vue術語插值表達式是什么和使用場景。
在vue中{{ }}
語法,叫做:插值表達式,大白話就是輸出值的語法。
在插值表達式中可以寫:
- 寫data數據字段名稱
- 寫methods函數的名稱,進行調用
- 對data數據字段進行表達式運算
- 加減運算
- 三元運算
- …
不能寫
- js語句:聲明變量,分支,循環
- 訪問在vue實例之外,自定義的全局變量
<div id="app"><h3>理解插值表達式</h3><p>姓名:{{name}}</p><!-- 字符串的拼接 --><p>{{name +',你好'}}</p><!-- 算術運算 --><p>{{num/5}}</p><p>{{num > 90 ? 'A+':'不是A+'}}</p><p>method:{{test1()}}</p><!-- 不能聲明變量 --><!-- {{var a = 1}} --><!-- 不能寫分支 --><!-- {{ if(true) {} }} --><!-- 不能訪問除了vm實例中聲明的數據 --><!-- {{num123}} --></div><script>// 插值表達式: {{}}// 作用:輸出值(把數據渲染到頁面)// {{}} 中可以寫什么// 1. data數據字段名// 2. methods函數名稱,進行調用// 3. data數據字段進行表達式運算// 算術// 字符串拼接// 三元// {{}} 不可以寫什么// 1. 不能寫js語句:聲明變量,分支,循環.....// 2. 不能訪問除了vm實例中聲明的數據// [Vue warn]: Property or method "num123" is not // defined on the instance(實例) but referenced(引用) // during rendervar num123 = 100const vm = new Vue({el: "#app",data: {name: 'vue',num: 80},methods: {test1 () {console.log('test1')}}})</script>
指令
指令(directive),其實就是一個以v-開頭的標簽屬性,例如:v-model
雙向綁定指令。
vue提供了一些指令,這些指令都是以v-開頭,他們可以擴展標簽的原有功能。這些指令的值,可以是js表達式,當關聯js表達式依賴的數據發生變化,對應的指令就會產生作用。
擴展功能:
- 輸入框雙向綁定
- 標簽的顯示隱藏
- 標簽顯示的內容
- …
學習vue,主要就是要學習兩個地方的內容:
- Vue實例(vue實例與三大件)
- 模板(視圖)中的規則:插件表達式,指令
v-text和v-html
目標:能夠使用v-text和v-html去更新標簽內容。
這組指令作用:
- 更新標簽的內容
- 根據數據進行更新
具體的作用:
- v-text 更新標簽的內容,格式是文本,和 innerText 相似。
- v-html 更新標簽的內容,格式是html,和 innerHTML 相似。
在代碼中體驗:
<div id="app"><h3>v-html,v-text</h3><!-- {{}}可以用來設置標簽中的部分內容 --><p>學習內容:{{str}}</p><p>{{str}}</p><!-- v-text:設置標簽中的 全部內容 --><p v-text="str"></p><!-- v-text:設置標簽中的 如果這里內容是html字符串,它會轉義一下,只是顯示字符串而不會顯示成對應的dom結構 --><div v-text="strHtml"></div><!-- v-html用來設置標簽中的內容。與v-text不同,它直接解析其中的html結構,并渲染 --><div v-html="strHtml"></div></div><script>// v-text : ===> innerText// v-html : ===> innerHTMLconst vm = new Vue({el: "#app",data: {str: 'vue',// 有時,從后端取回來的數據是一個html字符串。// 例如:獲取文章詳情,取回來就是一html字符串。strHtml: '<h1>vue</h1>'}})</script>
總結:
- v-text 更新 純文本
- v-html 更新 html內容
v-show和v-if
功能
能夠使用v-show和v-if去控制標簽的顯示隱藏。
格式
<元素 v-show="布爾值"></元素>
<元素 v-if="布爾值"></元素>
這對指令的共同點:都能控制元素的是否可見
這對指令的不同點:
- v-show是通過 display:none來控制隱藏
- v-if 是通過動態創建和移除元素。
示例
<div id="app"><h3>v-if,v-show</h3><div v-if="isVisiable">我是通過v-if來控制是否可見!</div><div v-show="isVisiable">我是通過v-show來控制是否可見!</div></div><script>// 作用:控制標簽的可見與不可見// 格式:// <元素 v-show="布爾值"></元素>// <元素 v-if="布爾值"></元素>// 如果是false,則不可見,如果是true,則可見// 區別:// 對于v-if,如果為false,則,在頁面根本就不生成這個dom。// 所以不可見。// 對于v-show,如果為false,則,在頁面有這個dom,display:none。// 所以不可見。const vm = new Vue({el: "#app",data: {isVisiable: false}})setInterval(function() {vm.isVisiable = !vm.isVisiable},5000)</script>
總結:區分下使用場景:
- v-show 性能較好,對應需要頻繁切換顯示與隱藏的功能,可以使用v-show。
- v-if 減少標簽,狀態切換次數少的時候,使用使用v-if
v-on
功能
v-on指令的作用是:指令監聽 DOM 事件,并在觸發時運行一些 JavaScript 代碼。
格式
三種使用格式
# 格式一:把要執行的代碼直接寫在""內部。適合少量代碼
<標簽 v-on:事件名="要執行的代碼"></標簽>
# 格式二:指向methods中的定義的函數
<標簽 v-on:事件名="methods中的函數"></標簽>
# 格式二:指向methods中的定義的函數,并傳入參數
<標簽 v-on:事件名="methods中的函數(實參)"></標簽>
說明:
- 能支持所有原生事件名:所有的原生js事件
- v-on可以簡寫成@
示例
<div id="app"><h3>v-on</h3><div v-show="isVisiable">內容</div><!-- 格式一:把要執行的代碼直接寫在""內部。適合少量代碼 --><button v-on:click="isVisiable=true">顯示內容</button><button v-on:click="isVisiable=false">隱藏內容</button><!-- 格式二:指向methods中的定義的函數 --><!-- 加與不加()一樣:v-on:click="f1()" 與 v-on:click="f1" --><button v-on:click="f1">調用methods中的函數</button>
<br><!-- 格式三:指向methods中的定義的函數 --><!-- 注意:1. 如果要傳入參數,則必須要加()2. 如果傳入當前這個事件的事件對象,則傳入固定名字 $event --><button v-on:click="f2(10)">調用methods中的函數傳入10</button><br><button v-on:click="f3(11,$event)">調用methods中的函數傳入11,傳入事件對象</button></div><script>// 功能: v-on 用來監聽事件// 格式:// 格式一:把要執行的代碼直接寫在""內部。適合少量代碼// <標簽 v-on:事件名="要執行的代碼"></標簽>// 事件名:就是所有的dom原生事件 // click,input,mouseenter,blur,......// 格式二:指向methods中的定義的函數// <標簽 v-on:事件名="methods中的函數"></標簽>// 格式三:指向methods中的定義的函數,并傳入參數// <標簽 v-on:事件名="methods中的函數(實參)"></標簽>const vm = new Vue({el: "#app",data: {isVisiable: false},methods: {f1 () {console.log("f1被調用")alert(1)this.isVisiable = true},f2 (m) {alert(m)console.log(m)},// 形參名m,eventObj。這兩名,是可以自己定義的。f3 (m, eventObj) {console.log(m, eventObj)}}})</script>
總結:綁定函數的時候帶不帶括號?
- 如果你需要接受事件觸發的默認傳參,不帶括號
- 如果你需要自己來進行傳參,需要帶括號,自己傳實參
- 如果什么參數都不要,帶不帶無所謂
案例-折疊面板
用v-on和v-show實現折疊面板
<div id="app"><h2>案例:折疊面板</h2><div class="box"><div class="title" ><h4>我是標題</h4><span class="btn" @click="isOpen=!isOpen">{{isOpen ? '收起' : '展開'}} </span> </div><div class="container" v-show="isOpen">我是內容<br>我是內容</div></div>
</div>
<script>var vm = new Vue({el: '#app',data: {isOpen: false}})
</script>
補充-修飾符
<div id="app"><h3>v-on 修飾符</h3><div v-on:click="hClickDiv">div<button @click="hClickBtn">按鈕</button><br><button v-on:click.stop="hClickBtn">點擊按鈕不會冒泡</button><br><a href="http://www.baidu.com" v-on:click="hClickA">百度</a><br><a href="http://www.baidu.com" v-on:click.prevent="hClickA">不跳轉百度</a><br><a href="http://www.baidu.com" v-on:click.prevent.stop="hClickA">不跳轉百度不冒泡</a></div> </div><script>// vue中的事件也有冒泡機制。// 在子元素上的點擊事件,也會觸發父元素上的點擊事件。// 如果要阻止冒泡,只需給事件添加個修飾符.stop// 格式: 事件名.stop// 示例:click.stop// 如果要阻止默認行為,只需給事件添加個修飾符.prevent// 格式: 事件名.prevent// 示例:click.prevent// 如果需要,也可以一起使用,相當于兩個效果疊加// 格式: 事件名.prevent.stop// 示例:click.prevent.stop// v-on: ----簡寫成---> @const vm = new Vue({el: "#app",methods: {hClickDiv () {console.log("hClickDiv")},hClickBtn (){console.log("hClickBtn")},hClickA () {console.log('hClickA')}}})</script>
v-for 列表渲染
功能
快速批量生成列表結構
格式
格式1:完整格式
<元素 v-for="(遍歷變量,索引變量) in 可遍歷的數據項" :key="唯一的id"></元素>
格式2:簡寫格式
在完整格式的基礎上,可以省略 :key 和 索引變量。
<元素 v-for="遍歷變量 in 可遍歷的數據項"></元素>
遍歷目標
對于v-for指令,可遍歷的數據項可以是:
- 數組
- 對象
- 數值
代碼
<div id="app"><h2>v-for</h2><div class="box"><h4>1. 對數組進行遍歷</h4><ul><li v-for="(item,idx) in hobbies">{{idx}} - {{item}}</li></ul></div><div class="box"><h4>2. 對對象進行遍歷</h4><span v-for="(item,prop,idx) in info">{{idx}}-{{prop}}-{{item}}</span></div><div class="box"><h4>3. 對數值進行遍歷</h4><span v-for="item in 10">{{item}},</span></div>
</div>
<script src="./vue.js"></script>
<script>var vm = new Vue({el: '#app',data: {info: {name: '小張', age: 18, height: '150'},hobbies: ['唱歌', '跳舞', '打籃球']}})
</script>
使用了v-for指令的元素,在其內部可以通過插值表達式來訪問遍歷變量和循環變量。
v-bind
作用
動態綁定標簽上的屬性的值。(標簽上的屬性不能使用插值表達式來設置)。
例如:如何動態設置img的內容?
格式
<元素 v-bind:屬性名1="值1" v-bind:屬性名2="值3"></元素>
v-bind指令有簡寫用法 :
冒號,例如:
<img :src="data數據">
演示代碼
<div id="app"><h3>v-bind</h3><!-- 如果去修改src屬性? --><!-- <img alt="se" src="http://img3m8.ddimg.cn/93/1/61888458-1_b_2.jpg"> --><img alt="se" :src="imgSrc" :title="title"><br><img alt="se" v-bind:src="imgSrc" v-bind:title="title"><button v-on:click="hClick">改成11</button></div><script>// 作用 : 動態綁定標簽上的屬性的值// 格式 :// <元素 v-bind:屬性名1="值1" v-bind:屬性名2="值2"></元素>// 簡寫:// v-bind: ----簡寫---> :const vm = new Vue({el: "#app",data: {title: 'se',imgSrc: 'http://img3m8.ddimg.cn/93/1/61888458-1_b_2.jpg'},methods: {hClick () {// 設為 11this.title = "11不香嗎?"this.imgSrc = 'http://img3m0.ddimg.cn/83/24/61887260-1_b_1.jpg'}}})</script>
練習題
如下兩種寫法的區別是什么?
<div id="myId"></div>
<div :id="myId"></div>
案例:購物車
素材代碼
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><style>h4,p {margin: 0;font-weight: normal;}a{text-decoration: none;}body{background-color: #eee;}#app{background-color:#fff;width: 900px;margin: 50px auto;text-align: center;box-shadow: 3px 3px 3px rgba(0 , 0, 0, 0.5);padding:1em 2em;}.list {padding: 1em;width: 100%;box-sizing: border-box;display: flex;flex-wrap:wrap;}.book {position: relative;flex-basis: 22%;margin-right:2%;margin-bottom:1em;text-align: center;background-color: #fff;padding: 1em 0;transition: all .2s linear;}.book:hover {box-shadow: 0 15px 30px rgba(0, 0, 0, .1);transform: translate3d(0, -2px, 0);}.title {line-height: 2em;margin: 0;padding: 0;}.figure img {width: 150px;height: 150px;}.desc {margin: 0;font-size: 16px;}.price {margin: 0;font-size: 14px;}.btn {cursor: pointer;position: absolute;right: 0.8em;top: 0.8em;border: none;color: #ff6700;padding: .5em .5em;font-size: 12px;}.btn:active {border: none;}.btn:hover {background-color: #ff6700;color: #fff}.cart {border: 1px solid #eee;background-color: #fff;text-align: center;position: fixed;padding: 1em;right: 100px;top: 200px;}</style>
</head><body><div id="app"><h3>我的購物車</h3><div class="list"><div class="book" title="當你學會獨處"><a href=""><div class="figure"><img src="http://img3m8.ddimg.cn/70/15/28522168-1_l_3.jpg" alt="當你學會獨處(學會獨處,學會與自己談話)"></div><h4 class="title" title="當你學會獨處">當你學會獨處</h4><p class="desc"></p><p class="price"><span class="num">29.9</span></p></a><button class='btn' title="移出購物車">-</button></div><div class="book" title="JavaScript高級程序設計"><a href=""><div class="figure"><img src="http://img3m3.ddimg.cn/2/21/22628333-1_b_2.jpg"alt=" JavaScript高級程序設計"></div><h4 class="title" title="JavaScript高級程序設計">JavaScript高級程序設計</h4><p class="desc"></p><p class="price"><span class="num">78</span></p></a><button class='btn' title="移出購物車">-</button></div><div class="book" title="斷舍離"><a href=""><div class="figure"><img alt="斷舍離" src="http://img3m3.ddimg.cn/68/20/23271503-1_l_10.jpg"title="斷舍離"></div><h4 class="title" title="斷舍離">斷舍離</h4><p class="desc"></p><p class="price"><span class="num">29.9</span></p></a><button class='btn' title="移出購物車">-</button></div><div class="book" title="王子與貧兒"><a href=""><div class="figure"><img src="http://img3m0.ddimg.cn/67/20/28535530-1_l_3.jpg"alt="王子與貧兒"></div><h4 class="title" title="王子與貧兒">王子與貧兒</h4><p class="desc"></p><p class="price"><span class="num">39.9</span></p></a><button class='btn' title="移出購物車">-</button></div><div class="book" title="高效能人士的七個習慣"><a href=""><div class="figure"><img src="http://img3m2.ddimg.cn/3/4/25253022-1_b_11.jpg"alt="高效能人士的七個習慣"></div><h4 class="title" title="高效能人士的七個習慣">高效能人士的七個習慣</h4><p class="desc"></p><p class="price"><span class="num">59.3</span></p></a><button class='btn' title="移出購物車">-</button></div></div></div><script>var bookList = [{name: '當你學會獨處',price: 29.9,picSrc: 'http://img3m8.ddimg.cn/70/15/28522168-1_l_3.jpg'},{name: 'JavaScript高級程序設計',price: 78,picSrc: 'http://img3m3.ddimg.cn/2/21/22628333-1_b_2.jpg'},{name: '斷舍離',price: 29.9,picSrc: 'http://img3m3.ddimg.cn/68/20/23271503-1_l_10.jpg'},{name: '王子與貧兒',price: 39.9,picSrc: 'http://img3m0.ddimg.cn/67/20/28535530-1_l_3.jpg'},{name: '高效能人士的七個習慣',price: 59.3,picSrc: 'http://img3m2.ddimg.cn/3/4/25253022-1_b_11.jpg'}]</script>
</body></html>
基本實現
-
v-for循環生成dom結構
-
:src,:title,:alt 綁定屬性
-
v-on:click綁定點擊