視頻筆記是根據B站 千鋒 濤哥 - SpringBoot+vue+前后端分離項目《鋒迷商城》實戰課-完結版 進行整理的
筆記可上 gitee倉庫 自取
千鋒 Vue 筆記整理
- 一、vue 的簡介
- 1.1 使用 JQuery 的復雜性問題
- 1.2 VUE 簡介
- 1.2.1 前端框架
- 1.2.2 MVVM
- 二、 vue 入門使用
- 2.1 vue 的引入
- 2.2 入門案例 -- Hello World
- 三、 vue 的語法
- 3.1 基本類型數據和字符串
- 3.2 對象類型數據
- 3.3 條件 v-if
- 3.4 循環 v-for
- 3.5 綁定標簽屬性 v-bind
- 3.6 表單標簽的雙向綁定 v-model
- 四、vue 實例
- 4.1 vue 實例的生命周期
- 4.2 鉤子函數
- 五、 計算屬性和偵聽器
- 5.1 計算屬性
- 5.2 偵聽器
- 六、class 與 style 綁定
- 6.1 class 綁定
- 6.2 style 綁定
- 七、條件與列表渲染
- 7.1 條件渲染
- 7.1.1 v-if
- 7.1.2 v-else
- 7.1.3 v-else-if
- 7.1.4 v-show
- 7.2 列表渲染
- 八、事件處理
- 8.1 使用 JS 函數傳值
- 8.2 使用 dataset 對象傳值 `(推薦)`
- 8.3 混合使用
- 8.4 事件修飾符
- 8.4.1 事件修飾符使用示例
- 8.4.2 事件修飾符
- 8.5 按鍵修飾符
- 8.6 系統修飾符
- 九、表單輸入綁定
- 十、組件
- 10.1 組件介紹及示例
- 10.1.1 組件注冊
- 10.1.2 組件引用
- 10.2 組件注冊
- 10.2.1 自定義組件的結構
- 10.2.2 組件的封裝
- 10.2.3 組件的復用
- 10.3 組件通信
- 10.3.1 父傳子
- 10.3.2 子傳父 -- 使用 `props` 屬性動態傳遞參數
- 10.3.3 總結
- 10.4 組件插槽
- 10.4.1 插槽的使用
- 10.4.2 具名插槽
- 10.4.3 插槽作用域
- 十一、axios 異步通信
- 11.1 axios 介紹
- 11.2 axios 入門使用
- 11.3 axios 異步請求方法
- 11.3.1 GET 格式的請求
- 11.3.2 POST 格式的請求
- 11.3.3 自定義請求
- 11.3.4 請求方法別名
- 11.4 并發請求
- 11.5 箭頭函數
- 11.5.1 axios 回調函數的參數 res
- 11.5.2 箭頭函數
- 十二、 路由 router
- 12.1 路由插件的引用
- 12.1.1 離線
- 12.1.2 在線 CDN
- 12.2 動態路由匹配
- 12.2.1 通配符
- 12.2.2 路由參數
- 12.2.3 優先級
- 12.3 嵌套路由
- 12.4 編程式導航
- 12.4.1 push()
- 12.4.2 push() 參數
- 12.4.3 replace()
- 12.4.4 go()
- 12.5 命名路由
- 12.6 命名視圖
- 12.7 重定向
- 12.7.1 重定向
- 12.7.2 路由別名
- 12.8 路由組件傳參
一、vue 的簡介
1.1 使用 JQuery 的復雜性問題
- 使用 JQuery 進行前后端分離開發,既可以實現前后端交互 (ajax) ,又可以完成數據渲染
- 存在的問題: JQuery 需要通過 HTML 標簽拼接、DOM 節點操作完成數據的顯示,開發效率低且容易出錯,渲染效率較低
- vue 是繼 JQuery 之后的又一優秀的前端框架:專注于前端數據的渲染 ———— 語法簡單、渲染效率高
1.2 VUE 簡介
1.2.1 前端框架
-
前端三框架:HTML、CSS、JavaScript
- HTML 決定網頁結構
- CSS 決定顯示效果
- JavaScript 決定網頁功能 (交互、數據顯示)
-
UI 框架:(只提供樣式、顯示效果)
- Bootstrap
- amazeUI
- Layui
-
JS 框架:
- JQuery (JQuery UI)
- React
- angular
- nodejs ---- 后端開發
- vue 集各種前端框架的優勢發展而來
1.2.2 MVVM
項目結構經歷的三個階段:
后端 MVC :可以理解為單體結構,流程控制是由后端控制器來完成
前端 MVC :前后端分離開發,后端只負責接收響應請求
MVVM是MVC的增強版,實質上和MVC沒有本質區別,只是代碼的位置變動而已
MVVM 前端請求后端接口,后端返回數據,前端接收數據,并將接收到的數據設置為 “VM”,HTML 從 vm 取值
- M model 數據模型,指的是后端接口返回的數據
- V view 視圖
- VM ViewModel 視圖模型 數據模型與視圖之間的橋梁,后端返回的 model 轉換前端所需的 vm,視圖層可以直接從 vm 中提取數據
二、 vue 入門使用
Vue (讀音 /vju?/,類似于 view) 是一套用于構建用戶界面的漸進式框架。與其它大型框架不同的是,Vue 被設計為可以自底向上逐層應用。Vue 的核心庫只關注視圖層,不僅易于上手,還便于與第三方庫或既有項目整合。另一方面,當與現代化的工具鏈以及各種支持類庫結合使用時,Vue 也完全能夠為復雜的單頁應用提供驅動。
2.1 vue 的引入
-
離線引用:下載 vue 的 js 文件,添加到前端項目,在網頁中通過 script 標簽引用 vue.js 文件
-
CDN 引用:
直接使用在線 CDN 的方式引入
<!-- 開發環境版本,包含了有幫助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
2.2 入門案例 – Hello World
文本:數據綁定最常見的形式就是使用“Mustache”語法 (雙大括號) 的文本插值:
{{message}}
-
創建一個 HTML 文件
-
引入 vue.js 文件
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
-
示例:
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title><!-- 引入vue.js--><script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
</head>
<body><div id="app-1">從 0 開始: {{message}}</div><script type="text/javascript">var vm = new Vue({el: '#app-1',data: {message: 'Hello World!'}})</script>
</body>
</html>
Mustache 標簽將會被替代為對應數據對象上 message
property 的值。無論何時,綁定的數據對象上 message
property 發生了改變,插值處的內容都會更新。
三、 vue 的語法
3.1 基本類型數據和字符串
<div id="app-2">{{code}}從 0 開始: {{message}}
</div><script type="text/javascript">var vm = new Vue({el: '#app-2',data: {code: 1_3_3,message: 'Hello World!'}})</script>
3.2 對象類型數據
- 支持 ognl 語法
<div id="app-3">學號:{{stu.stuNum}} <br />姓名:{{stu.stuName}} <br />性別:{{stu.stuGender}} <br />年齡:{{stu.stuAge}}
</div><script type="text/javascript">var vm = new Vue({el: '#app-3',data: {stu: {stuNum: '10001',stuName: '張三',stuGender: 'M',stuAge: 20}}})</script>
3.3 條件 v-if
v-if : 用來控制切換一個元素是否顯示 (底層控制是 DOM 元素,操作 DOM)
注:在瀏覽器中網頁打開這個文件 F12,從標簽上可以看到沒有 stu.stuGender == 'F'
對應的元素。即條件不成立,網頁不會渲染該 DOM,連標簽都不會有。
<div id="app-4">學號:{{stu.stuNum}} <br />姓名:{{stu.stuName}} <br />性別:<label v-if="stu.stuGender == 'M'">男</label><label v-if="stu.stuGender == 'F'">女</label><br />年齡:{{stu.stuAge}}</div><script type="text/javascript">var vm = new Vue({el: '#app-4',data: {stu: {stuNum: '10001',stuName: '張三',stuGender: 'M',stuAge: 20}}})</script>
3.4 循環 v-for
v-for
指令基于一個數組來渲染一個列表。在
v-for
塊中,我們可以訪問所有父作用域的 property。v-for
還支持一個可選的第二個參數,即當前項的索引。
<div id="app-5"><table border="1" cellspacing="0" width="400"><tr><th>序號</th><th>學號</th><th>姓名</th><th>性別</th><th>年齡</th></tr><tr v-for="(stu, index) in stus"><td>{{index + 1}}</td><td>{{stu.stuNum}}</td><td>{{stu.stuName}}</td><td><table v-if="stu.stuGender == 'M'">男</table><table v-if="stu.stuGender == 'F'">女</table></td><td>{{stu.stuAge}}</td></tr></table></div><script type="text/javascript">var vm = new Vue({el: '#app-5',data: {stus: [{stuNum: '10001',stuName: '張三',stuGender: 'M',stuAge: 20},{stuNum: '10002',stuName: '李四',stuGender: 'M',stuAge: 23},{stuNum: '10003',stuName: '鄭紅',stuGender: 'F',stuAge: 19}]}})</script>
3.5 綁定標簽屬性 v-bind
- v-bind:屬性名 縮寫:
:屬性名
<div id="app-6"><input type="text" v-bind:value="message"><hr /><br /><table border="1" cellspacing="0" width="400"><tr><th>序號</th><th>學號</th><th>姓名</th><th>性別</th><th>年齡</th></tr><tr v-for="(stu, index) in stus"><td>{{index + 1}}</td><td>{{stu.stuNum}}</td><td><img height="30" :src="stu.stuImg" /> </td><td>{{stu.stuName}}</td><td><table v-if="stu.stuGender == 'M'">男</table><table v-if="stu.stuGender == 'F'">女</table></td><td>{{stu.stuAge}}</td></tr></table></div><script type="text/javascript">var vm = new Vue({el: '#app-6',data: {message: 'Hello World!!',stus: [{stuNum: '10001',stuName: '張三',stuGender: 'M',stuAge: 20,stuImg: 'img/1.jpg'},{stuNum: '10002',stuName: '李四',stuGender: 'M',stuAge: 23,stuImg: 'img/2.jpg'},{stuNum: '10003',stuName: '鄭紅',stuGender: 'F',stuAge: 19,stuImg: 'img/3.jpg'}]}})</script>
3.6 表單標簽的雙向綁定 v-model
- 只能使用在表單輸入標簽
- v-model:value 可以簡寫為 v-model
<div id="app-7"><input type="text" v-model="message"><hr /><br />雙向綁定:{{message}}</div><script type="text/javascript">var vm = new Vue({el: '#app-7',data: {message: 'Hello World!!'}})</script>
四、vue 實例
每個使用 vue 進行數據渲染的網頁文檔都需要創建一個 vue 實例 — — ViewModel
4.1 vue 實例的生命周期
vue 實例生命周期 — — vue 實例從創建到銷毀的過程
- 創建 vue 實例 (初始化 data,加載 el)
- 數據掛載 (將 vue 實例 data 中的數據渲染到網頁 HTML 標簽)
- 重新渲染 (當 vue 的 data 數據發生變化,會重新渲染到 HTML 標簽)
- 銷毀實例
創建對象 ---- 屬性初始化 ---- 獲取屬性值 ----- GC 回收
4.2 鉤子函數
為了便于開發者在 vue 實例生命周期的不同階段進行特定的操作,vue 在生命周期四個階段的前后分別提供了一個函數,這個函數無需開發者調用,當 vue 實例到達生命周期的指定階段會自動調用對應的函數。
<div id="app-8"><label v-once>{{message}}</label><br /><label>{{message}}</label><br /><input type="text" v-model="message"></div><script type="text/javascript">var vm = new Vue({el: '#app-8',data: {message: 'Hello World!!'},beforeCreate: function () {// 1. data 初始化之前執行,不能操作 data},create: function () {// 2. data 初始化之后執行,模板加載之前,可以修改 / 獲取 data 中的值console.log(this.message);// this.message = 'Hello World!! create()';},beforeMount: function () {// 3. 模板加載之后,數據初始渲染(掛載)之前,可以修改 / 獲取 data 中的值// this.message = 'Hello World!! beforeMount';},mounted: function () {// 4. 數據初始渲染(掛載)之后,可以對 data 中的變量進行修改,但是不會影響 v-once 的渲染// this.message = "Hello World!! mounted";},beforeUpdate: function () {// 5. 數據渲染之后,當 data 中的數據發生變化觸發重新渲染,渲染之前執行此函數console.log("---" + this.message);this.message = 'Hello World!! beforeUpdate';},update: function () {// 6. data 數據被修改之后,重新渲染到頁面之后// this.message = "Hello World!! update";},beforeDestroy: function () {// 7. 實例銷毀之前},destroy: function () {// 8. 實例銷毀之后}})</script>
五、 計算屬性和偵聽器
5.1 計算屬性
data 中的屬性可以通過聲明獲得,也可以通過在 computed 計算屬性的 getter 獲得
特性:計算屬性所依賴的屬性值發生變化會影響計算屬性的值同時發生變化
示例
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title><script src="js/vue.js"></script>
</head>
<body><div id="app-9"><input type="text" v-model="message1"><br /><input type="text" v-model="message2"><br />{{message3}}</div><script type="text/javascript">var vm = new Vue({el: '#app-9',data: {message1: 'Hello',message2: 'World'},computed: {message3: function () {return this.message1 + this.message2;}}})</script>
</body>
</html>
5.2 偵聽器
偵聽器,就是 data 中屬性的偵聽器,當 data 中的屬性值發生變化就會觸發偵聽器函數的執行
雖然計算屬性在大多數情況下更合適,但有時也需要一個自定義的偵聽器。這就是為什么 Vue 通過 watch
選項提供了一個更通用的方法,來響應數據的變化。當需要在數據變化時執行異步或開銷較大的操作時,這個方式是最有用的。
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title><script src="js/vue.js"></script>
</head>
<body><div id="app-10"><input type="text" v-model="message1"><br /><input type="text" v-model="message2"><br />{{message3}}</div><script type="text/javascript">var vm = new Vue({el: '#app-10',data: {message1: 'Hello',message2: 'World',message3: 'Hello World'},watch: {message1: function () {this.message3 = this.message1 + this.message2;},message2: function () {this.message3 = this.message1 + this.message2;}}})</script>
</body>
</html>
六、class 與 style 綁定
6.1 class 綁定
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title><style>.my-style1 {width: 200px;height: 100px;background: orange;}.my-style2 {border-radius: 10px;}.my-style3 {width: 200px;height: 100px;background: black;}</style><script src="js/vue.js"></script>
</head>
<body><div id="app-11"><!-- 如果 message1 為 true, 就加載 my-style1,如果 message2 為 true, 就加載 my-style2 --><div :class="{'my-style1': message1, 'my-style2' : message2}"></div><hr /><!-- 為 class 屬性加載多個樣式名 --><div :class="[booleanValue1, booleanValue2]"></div><hr /><!-- 如果 message3 為 true, 則 class = 'my-style3',否則 class = 'my-style1'如果在三目運算中使用樣式名則需要加單引號,不加單引號則表示從 data 變量中獲取樣式名--><div :class="[message3 ? 'my-style3' : 'my-style1']"></div><div :class="[message1 ? booleanValue1 : booleanValue3]"></div></div><script type="text/javascript">var vm = new Vue({el: '#app-11',data: {message1: true,message2: true,message3: true,booleanValue1: "my-style1",booleanValue2: "my-style2",booleanValue3: "my-style3"}})</script>
</body>
</html>
6.2 style 綁定
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title><script src="js/vue.js"></script>
</head>
<body><div id="app-12"><!-- 當使用 v-bind 綁定內聯樣式時:1. 使用 {} 定義 style 樣式,才能獲取 data 的值, {} 要遵循 JSON 格式2. {} 中不在使用 style 樣式屬性名 “font-size”, 而要使用對應的 js 屬性名border-style-width --- borderStyleWidth--><div v-bind:style="{color: colorName, fontSize: fontsize + 'px' }">Hello World!</div><!-- 我們可以直接為 style 屬性綁定一個 data 中定義好的內聯樣式的字符串 --><div v-bind:style="myStyle1">Hello World!!</div><!-- 我們可以直接為 style 屬性綁定一個 data 中定義好的內聯樣式的對象 --><div v-bind:style="myStyle2">Hello World!!!</div><!-- 我們可以在同一個 style 屬性通過數組引用多個內聯樣式的對象 --><div v-bind:style="[myStyle2, myStyle3]">Hello World!!!!</div></div><script type="text/javascript">var vm = new Vue({el: '#app-12',data: {colorName: "yellow",fontsize: "40",myStyle1: "color: orange; font-size: 50px",myStyle2: {color: "blue",fontSize: "60px"},myStyle3: {textShadow: "orange 3px 3px 5px"}}})</script>
</body>
</html>
七、條件與列表渲染
7.1 條件渲染
條件判斷語句:
v-if
v-else-if
v-else
7.1.1 v-if
v-if
指令用于條件性地渲染一塊內容。這塊內容只會在指令的表達式返回 truthy 值的時候被渲染。
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title><script src="js/vue.js"></script>
</head>
<body><div id="app-13"><h3 v-if="code == 1">Hello :可以看到</h3><h3 v-if="flag">flag 為 true, 可以看到</h3></div><script type="text/javascript">var vm = new Vue({el: '#app-13',data: {code: 1,flag: false}})</script>
</body>
</html>
7.1.2 v-else
v-else
指令來表示v-if
的“else 塊”
<div id="app-13"><!-- v-else 標簽需要緊跟在 v-if 的標簽之后,中間不能有其他標簽, 否則它將不會被識別 --><h3 v-if="code == 1">Hello :可以看到</h3><h3 v-else>World :可以看到</h3></div><script type="text/javascript">var vm = new Vue({el: '#app-13',data: {code: 1}})</script>
7.1.3 v-else-if
<div id="app-13">分數 {{code}}對應的等級:<h3 v-if="code >= 90">優秀</h3><h3 v-else-if="code >= 80">良好</h3><h3 v-else-if="code >= 70">中等</h3><h3 v-else-if="code >= 60">及格</h3><h3 v-else>掛科</h3></div><script type="text/javascript">var vm = new Vue({el: '#app-13',data: {code: 85}})</script>
7.1.4 v-show
v-show
:同樣用于根據條件展示元素。從功能上 v-show 與 v-if 作用是相同的,只是渲染過程有區別。
v-if 與 v-show 的區別:
v-if
是“真正”的條件渲染,因為它會確保在切換過程中條件塊內的事件監聽器和子組件適當地被銷毀和重建。v-if
也是惰性的:如果在初始渲染時條件為假,則什么也不做——直到條件第一次變為真時,才會開始渲染條件塊。- 相比之下,
v-show
就簡單得多——不管初始條件是什么,元素總是會被渲染,并且只是簡單地基于 CSS 進行切換。 - 一般來說,
v-if
有更高的切換開銷,而v-show
有更高的初始渲染開銷。因此,如果需要非常頻繁地切換,則使用v-show
較好;如果在運行時條件很少改變,則使用v-if
較好。
7.2 列表渲染
編碼過程中,發現網頁出現報錯:
Uncaught Error: Bootstrap's JavaScript requires jQuery at bootstrap.min.js:6
解決方法:在引進JQuery文件時,將其放在 bootstrap 前面即可。
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title><script src="https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js"></script><!-- 最新版本的 Bootstrap 核心 CSS 文件 --><link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css" integrity="sha384-HSMxcRTRxnN+Bdg0JdbxYKrThecOKuH5zCYotlSAcp1+c8xmyTe9GYg1l9a69psu" crossorigin="anonymous"><!-- 最新的 Bootstrap 核心 JavaScript 文件 --><script src="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js" integrity="sha384-aJ21OjlMXNL5UyIl/XNwTMqvzeRMZH2w8c5cRVpzpU8Y5bApTppSuUkhZXN0VxHd" crossorigin="anonymous"></script><script src="js/vue.js"></script>
</head>
<body><div id="app-14"><ul><li v-for="c in categories"><a :href="'query?cid=' + c.cid">{{c.cname}}</a></li></ul><table class="table table-bordered"><tr><th>學號</th><th>照片</th><th>姓名</th><th>性別</th><th>年齡</th><th>操作</th></tr><template v-for="(s, index) in stu"><tr :id="'tr' + s.stuNum"><td>{{s.stuNum}}</td><td><img height="30" :src="s.stuImg" /></td><td>{{s.stuName}}</td><td><!-- {{s.stuGender == 'M' ? '男' : '女'}} --><img v-if="s.stuGender == 'M'" src="img/m.bmp"><img v-else src="img/f.bmp"></td><td>{{s.stuAge}}</td><td><a class="btn btn-danger" :href="'stu/delete?cid=' + s.stuNum">刪除</a><a class="btn btn-success" :href="'stu/update?cid=' + s.stuNum">修改</a></td></tr></template></table></div><script type="text/javascript">var vm = new Vue({el: '#app-14',data: {categories:[{cid: 1,cname: "華為"},{cid: 2,cname: "小米"},{cid: 3,cname: "OPPO"},{cid: 4,cname: "VIVO"}],stu: [{stuNum: "10010",stuImg: "img/1.jpg",stuName: "Tom",stuGender: "M",stuAge: 20},{stuNum: "10011",stuImg: "img/2.jpg",stuName: "Joker",stuGender: "M",stuAge: 21},{stuNum: "10012",stuImg: "img/3.jpg",stuName: "Ling",stuGender: "F",stuAge: 20},{stuNum: "10013",stuImg: "img/1.jpg",stuName: "Jack",stuGender: "F",stuAge: 18},]}})</script>
</body>
</html>
八、事件處理
在使用 vue 進行數據渲染時,如果使用原生 js 事件綁定 (例如 onclick),如果需要獲取 vue 實例中的數據并傳參則需要通過拼接來完成
vue 提供了 v-on 指令用于綁定各種事件 (v-on:click),簡化了從 vue 取值的過程,但是觸發的方法需要定義在 vue 實例的 methods 中
<button class="btn btn-danger" v-on:click="doDelete(s.stuNum,s.stuName)">刪除</button><script type="text/javascript">var vm = new Vue({el: '#app-15',data: {stu: [{stuNum: "10010",stuImg: "img/1.jpg",stuName: "Tom",stuGender: "M",stuAge: 20}]},methods: {doDelete: function (sNum, sName) {alert("---delete:" + sNum + " " + sName)}}}) </script>
v-on:click
可以簡寫為@click
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title><script src="https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js"></script><!-- 最新版本的 Bootstrap 核心 CSS 文件 --><link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css" integrity="sha384-HSMxcRTRxnN+Bdg0JdbxYKrThecOKuH5zCYotlSAcp1+c8xmyTe9GYg1l9a69psu" crossorigin="anonymous"><!-- 最新的 Bootstrap 核心 JavaScript 文件 --><script src="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js" integrity="sha384-aJ21OjlMXNL5UyIl/XNwTMqvzeRMZH2w8c5cRVpzpU8Y5bApTppSuUkhZXN0VxHd" crossorigin="anonymous"></script><script src="js/vue.js"></script>
</head>
<body><div id="app-15"><ul><li v-for="c in categories"><a :href="'query?cid=' + c.cid">{{c.cname}}</a></li></ul><table class="table table-bordered"><tr><th>學號</th><th>照片</th><th>姓名</th><th>性別</th><th>年齡</th><th>操作</th></tr><template v-for="(s, index) in stu"><tr :id="'tr' + s.stuNum"><td>{{s.stuNum}}</td><td><img height="30" :src="s.stuImg" /></td><td>{{s.stuName}}</td><td><!-- {{s.stuGender == 'M' ? '男' : '女'}} --><img v-if="s.stuGender == 'M'" src="img/m.bmp"><img v-else src="img/f.bmp"></td><td>{{s.stuAge}}</td><td><button class="btn btn-danger" v-on:click="doDelete(s.stuNum,s.stuName)">刪除</button><button class="btn btn-success" @click="doUpdate" :data-snum="s.stuNum":data-sname="s.stuName" :data-simg="s.stuImg">修改</button></td></tr></template></table></div><script type="text/javascript">var vm = new Vue({el: '#app-15',data: {categories:[{cid: 1,cname: "華為"},{cid: 2,cname: "小米"},{cid: 3,cname: "OPPO"},{cid: 4,cname: "VIVO"}],stu: [{stuNum: "10010",stuImg: "img/1.jpg",stuName: "Tom",stuGender: "M",stuAge: 20},{stuNum: "10011",stuImg: "img/2.jpg",stuName: "Joker",stuGender: "M",stuAge: 21},{stuNum: "10012",stuImg: "img/3.jpg",stuName: "Ling",stuGender: "F",stuAge: 20},{stuNum: "10013",stuImg: "img/1.jpg",stuName: "Jack",stuGender: "F",stuAge: 18},]},methods: {doDelete: function (sNum, sName) {alert("---delete:" + sNum + " " + sName)},doUpdate: function (event) {// 如果 v-on 綁定的 js 函數沒有參數,調用的時候可以省略 (), 同時可以給 js 函數一個 event 參數(事件對象)// 1. event 表示觸發當前函數的事件// 2. event.srcElement 表示發生事件的元素 --- 修改按鈕// 3. event.srcElement.dataset 表示按鈕上綁定的數據集 (data-開頭的屬性)alert("---update:");let stu = event.srcElement.dataset;}}})</script>
</body>
</html>
8.1 使用 JS 函數傳值
<button class="btn btn-danger" v-on:click="doDelete(s.stuNum,s.stuName)">刪除</button><script type="text/javascript">var vm = new Vue({el: '#app-15',data: {stu: [{stuNum: "10010",stuImg: "img/1.jpg",stuName: "Tom",stuGender: "M",stuAge: 20}]},methods: {doDelete: function (sNum, sName) {alert("---delete:" + sNum + " " + sName)}}})
</script>
8.2 使用 dataset 對象傳值 (推薦)
<button class="btn btn-success" @click="doUpdate" :data-snum="s.stuNum":data-sname="s.stuName" :data-simg="s.stuImg">修改</button><script type="text/javascript">var vm = new Vue({el: '#app-15',data: {stu: [{stuNum: "10010",stuImg: "img/1.jpg",stuName: "Tom",stuGender: "M",stuAge: 20}]},methods: {doUpdate: function (event) {// 如果 v-on 綁定的 js 函數沒有參數,調用的時候可以省略 (), 同時可以給 js 函數一個 event 參數(事件對象)// 1. event 表示觸發當前函數的事件// 2. event.srcElement 表示發生事件的元素 --- 修改按鈕// 3. event.srcElement.dataset 表示按鈕上綁定的數據集 (data-開頭的屬性)alert("---update:");let stu = event.srcElement.dataset;}}})
</script>
8.3 混合使用
有時也需要在內聯語句處理器中訪問原始的 DOM 事件。可以用特殊變量 $event
把它傳入方法
<button class="btn btn-danger" v-on:click="doDelete(s.stuNum,s.stuName, $event)" :data-simg="s.stuImg">刪除</button><script type="text/javascript">var vm = new Vue({el: '#app-15',data: {stu: [{stuNum: "10010",stuImg: "img/1.jpg",stuName: "Tom",stuGender: "M",stuAge: 20}]},methods: {doDelete: function (sNum, sName, event) {alert("---delete:" + sNum + " " + sName)console.log(event.srcElement.dataset)}}})
</script>
8.4 事件修飾符
修飾符是由點開頭的指令后綴來表示的。
當使用 v-on 進行事件綁定的時候,可以添加特定后綴,設置事件觸發的特性
8.4.1 事件修飾符使用示例
<button type="submit" class="btn btn-success" @click.prevent="test">修改</button>
8.4.2 事件修飾符
常用的事件修飾符:
.stop
.prevent
.capture
.self
.once
.passive
.prevent 用來阻止標簽的默認行為
<div id="app-16"><form action="https://www.baidu.com"><!-- 此處不加 .prevent ,網頁會跳轉到 https://www.baidu.com --><button type="submit" class="btn btn-success" @click.prevent="test">修改</button></form>
</div><script type="text/javascript">var vm = new Vue({el: '#app-16',data: {},methods: {test: function (event) {alert("--test");}}})
</script>
.stop 阻止事件冒泡
.self 設置只能自己觸發事件(子標簽不能觸發)
<div id="app-16"><!-- .prevent 示例 --><form action="https://www.baidu.com"><!-- 此處不加 .prevent ,網頁會跳轉到 https://www.baidu.com --><button type="submit" class="btn btn-success" @click層="test">修改</button></form><!-- .stop 示例 .self 示例:只能點擊自己觸發 --><div style="width: 200px; height: 200px; background: red;" @click.self="outside"><div style="width: 100px; height: 100px; background: yellow;" @click="inside"><!-- 此處加了 .stop , 網頁的外層 div 父標簽不會觸發 --><button @click.stop="itself">test stop 修飾符</button></div></div></div><script type="text/javascript">var vm = new Vue({el: '#app-16',data: {},methods: {test: function (event) {alert("--test");},inside: function () {alert("--inside");},outside: function () {alert("--outside");},itself: function () {alert("--itself");}}})
</script>
.once 限定事件只能觸發一次
<!-- .once 示例:test()方法只執行一次, -->
<form action="https://www.baidu.com"><!-- 加了 .prevent,第一次點擊執行 test(),默認跳轉被阻止, 第二次點擊按鈕,直接跳轉, test()不執行 --><button type="submit" class="btn btn-success" @click.prevent.once="test">修改</button>
</form>
8.5 按鍵修飾符
按鍵修飾符:針對鍵盤事件的修飾符,限定哪個按鍵會觸發事件
常用的按鍵修飾符:
.enter
.tab
.delete
(捕獲“刪除”和“退格”鍵).esc
.space
.up
.down
.left
.right
.enter 只有在 key
是 Enter
時調用(觸發 enter
按鍵之后觸發事件)
<div id="app-17"><input type="text" @keyup.enter="test">
</div><script type="text/javascript">var vm = new Vue({el: '#app-17',data: {},methods: {test: function () {alert("enter松開觸發")}}})
</script>
還可以通過全局 config.keyCodes
對象自定義按鍵修飾符別名:
// 輸入 按鍵 j 觸發事件 test
<input type="text" @keyup.aaa="test">
// 按鍵 j 的別名
Vue.config.keyCodes.aaa = 74
8.6 系統修飾符
組合鍵
示例:CTRL + J 觸發事件
<div id="app-17"><input type="text" @keyup.ctrl.j="test">
</div><script type="text/javascript">Vue.config.keyCodes.j = 74var vm = new Vue({el: '#app-17',data: {},methods: {test: function () {alert("enter松開觸發")}}})
</script>
常用的修飾符:
.ctrl
.alt
.shift
.meta
windows 鍵
九、表單輸入綁定
表單輸入綁定,即雙向綁定:就是能夠將 vue 實例的 data 數據渲染到表單輸入視圖 (input\textarea\select),
也能夠將輸入視圖的數據同步到 vue 實例的 data中。
<div id="app-18"><!-- 文本輸入框 密碼輸入框 --><input type="text" v-model="name" /><br /><input type="password" v-model="password" /><hr /><!-- 單選按鈕 --><input type="radio" v-model="radioTest" value="A" /> A<input type="radio" v-model="radioTest" value="B" /> B<input type="radio" v-model="radioTest" value="C" /> C<input type="radio" v-model="radioTest" value="D" /> D<hr /><!-- 復選框,綁定的是一個數組 --><input type="checkbox" v-model="checkBox" value="籃球" /> 籃球 <br /><input type="checkbox" v-model="checkBox" value="足球" /> 足球 <br /><input type="checkbox" v-model="checkBox" value="羽毛球" /> 羽毛球 <br /><input type="checkbox" v-model="checkBox" value="乒乓球" /> 乒乓球 <br /><!-- 下拉菜單 select:綁定一個字符串 --><select v-model="city"><option value="BJ">北京</option><option value="SH">上海</option><option value="SZ">深圳</option><option value="GZ">廣州</option></select><hr /><!-- 下拉菜單 select:加上了 multiple ,表示可多選,需要綁定一個數組 --><select v-model="cities" multiple><option value="BJ">北京</option><option value="SH">上海</option><option value="SZ">深圳</option><option value="GZ">廣州</option></select><button type="button" @click="test">測試</button>
</div><script type="text/javascript">var vm = new Vue({el: '#app-18',data: {name: "admin",password: "123456",radioTest: "C",checkBox: [],city: "",cities: []},methods: {test: function () {alert(vm.cities)}}})
</script>
十、組件
10.1 組件介紹及示例
組件,就是講通用的 HTML 模塊進行封裝 —— 可復用的 Vue 實例
? 通常一個應用會以一棵嵌套的組件樹的形式來組織:
10.1.1 組件注冊
將通用的 HTML 模塊封裝注冊到 vue 中
自定義組件 my-components.js:
Vue.component('header-button', {template: `<div style="width: 100%; height: 80px; background: salmon"><table width="100%"><tr><td width="200" align="right" valign="middle"><img src="img/1.jpg" height="80" /></td><td><label style="color: deepskyblue; font-size: 32px; font-family: 'Adobe 楷體 Std R'; margin-left: 30px">登錄</label></td></tr></table></div>`
});
10.1.2 組件引用
- 定義組件需要依賴 vue.js,在引用自定義組件 js 文件要先引用 vue.js
- 組件的引用必須在 vue 實例 el 指定的容器中 ,即要在Vue實例范圍內
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title><script src="https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js"></script><!-- 最新版本的 Bootstrap 核心 CSS 文件 --><link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css" integrity="sha384-HSMxcRTRxnN+Bdg0JdbxYKrThecOKuH5zCYotlSAcp1+c8xmyTe9GYg1l9a69psu" crossorigin="anonymous"><!-- 最新的 Bootstrap 核心 JavaScript 文件 --><script src="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js" integrity="sha384-aJ21OjlMXNL5UyIl/XNwTMqvzeRMZH2w8c5cRVpzpU8Y5bApTppSuUkhZXN0VxHd" crossorigin="anonymous"></script><script src="js/vue.js"></script>
</head>
<body><div id="app-19"><header-button></header-button><hr /><header-button></header-button></div><script src="js/my-components.js"></script><script type="text/javascript">var vm = new Vue({el: '#app-19'})</script>
</body>
</html>
10.2 組件注冊
10.2.1 自定義組件的結構
Vue.component()
注冊組件data
定義組件的模板渲染的數據template
組件的 HTML 模塊(HTML 標簽 \ CSS 樣式)methods
定義組件中的標簽事件中綁定的 JS 函數
my-components.js:
Vue.component('header-button', {data: function () {// 組件中 data 是通過函數返回的對象return {name: "貂蟬"};},template: `<div style="width: 100%; height: 80px; background: salmon"><table width="100%"><tr><td width="200" align="right" valign="middle"><img src="img/1.jpg" height="80" /></td><td><label style="color: deepskyblue; font-size: 32px; font-family: 'Adobe 楷體 Std R'; margin-left: 30px">登錄人: {{name}}</label></td><td><button @click="test">組件按鈕</button></td></tr></table></div>`,methods: {test: function () {alert("組件中 header-button 定義的函數事件")}}
});
10.2.2 組件的封裝
- 將模板中的 css 樣式提取出來,單獨封裝到 css 文件存儲在 css 目錄
- 將模板中的圖片存儲在 img 目錄
- 將定義組件的 js 文件和 vue 文件存放到 js 目錄
Vue 組件封裝的結構 |
---|
![]() |
注:在編碼過程中學到,Vue 中同一個 DOM 元素綁定多個點擊事件:可以使用逗號分隔。
10.2.3 組件的復用
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title><link rel="stylesheet" href="css/my-components.css" /><script src="https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js"></script><!-- 最新版本的 Bootstrap 核心 CSS 文件 --><link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css" integrity="sha384-HSMxcRTRxnN+Bdg0JdbxYKrThecOKuH5zCYotlSAcp1+c8xmyTe9GYg1l9a69psu" crossorigin="anonymous"><!-- 最新的 Bootstrap 核心 JavaScript 文件 --><script src="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js" integrity="sha384-aJ21OjlMXNL5UyIl/XNwTMqvzeRMZH2w8c5cRVpzpU8Y5bApTppSuUkhZXN0VxHd" crossorigin="anonymous"></script><script src="js/vue.js"></script>
</head>
<body><div id="app-19"><header-button></header-button><hr /><header-button></header-button></div><script src="js/my-components.js"></script><script type="text/javascript">var vm = new Vue({el: '#app-19'})</script>
</body>
</html>
10.3 組件通信
vue 實例本身就是一個組件(模板就是 el 指定容器,data 就是組件數據,methods 就是組件的事件函數)
在 vue 實例指定的 el 容器中引用的組件稱為子組件,當前 vue 實例就是父組件
注:子組件按鈕模板不能觸發父組件的方法,子組件的按鈕可以觸發子組件的方法。
10.3.1 父傳子
vue 實例引用組件的時候,傳遞數據到引用的組件中
通過組件的屬性實現父組件傳遞數據到子組件
示意圖 |
---|
![]() |
10.3.2 子傳父 – 使用 props
屬性動態傳遞參數
通過子組件的按鈕“調用”父組件的函數,通過函數傳值
流程示意圖 |
---|
![]() |
父組件:
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title><link rel="stylesheet" href="css/my-components.css" /><script src="js/vue.js"></script>
</head>
<body><div id="app-21"><!-- 組件的引用必須在 vue 實例指定的容器中 --><header-bar :name="message" @my-event="parentMethod"></header-bar>子組件傳到父組件的標題名稱: {{title}}<hr /><header-bar name="關羽"></header-bar></div><script src="js/my-components-bar2.js"></script><script type="text/javascript">var vm = new Vue({el: '#app-21',data: {message: "貂蟬",title: ""},methods: {parentMethod: function (res) {vm.title = res;}}})</script>
</body>
</html>
子組件:
Vue.component('header-bar', {data: function() {return {title: "三國 -- √"}},template: `<div class="divStyle"><table class="tableStyle"><tr><td width="200" align="right" valign="middle"><img src="img/1.jpg" class="logoImg" /></td><td><label class="nameStyle">登錄人: {{name}}</label></td><td><button @click="childMethod">組件按鈕點擊次數</button></td></tr></table></div>`,props: ["name"],methods: {childMethod: function () {this.$emit("my-event", this.title);}}
});
10.3.3 總結
父組件通信子組件
-
props
: 子組件通過props獲取定義父組件傳遞的自定義屬性 -
this.$refs
: 引用子組件 -
this.$children
: 父組件childrens屬性,存儲著所有的子組件
子組件通信父組件(或根組件)
-
this.$emit
: 子組件通過$emit
訪問父組件傳遞的自定義事件 -
this.$parent
: 訪問父組件 -
this.$root
: 訪問根組件。根組件root就是new Vue({el: "#app"});
中的el元素
10.4 組件插槽
當我們自定義 vue 組件時,允許組件中的部分內容在調用組件時進行定義 —— 插槽
10.4.1 插槽的使用
- 在自定義組件時通過
slot
標簽在組件的模板中定義插槽
my-components-bar-slot.js:
Vue.component('header-bar', {data: function() {return {title: "三國 -- √"}},template: `<div class="divStyle"><table class="tableStyle"><tr><td width="200" align="right" valign="middle"><img src="img/1.jpg" class="logoImg" /></td><td><label class="nameStyle">登錄人: {{name}}</label></td><td><slot></slot></td><td><button @click="childMethod">組件按鈕點擊次數</button></td></tr></table></div>`,props: ["name"],methods: {childMethod: function () {this.$emit("my-event", this.title);}}
});
- 在父組件中調用此組件時,指定插槽填充的模板
示例1:插槽填充 搜索框
<header-bar :name="message"><input /> <button>搜索</button>
</header-bar>
示例2:插槽填充 按鈕
<header-bar :name="message" @my-event="parentMethod"><div><a href="#">首頁</a><a href="#">后臺</a><a href="#">管理</a><a href="#">關于</a></div>
</header-bar>
10.4.2 具名插槽
當組件中的插槽數量 > 1 時,需要給組件中的
slot
標簽添加name
屬性指定插槽的名字
- 定義組件
Vue.component('page-frame', {template: `<div><div id="header" style="width: 100%; height: 100px; background: pink">{{title}}<br />slot1 : <br /><slot name="slot1"></slot></div><div style="width: 100%; height: 580px">slot2 : <br /><slot name="slot2"></slot></div><div id="footer" style="width: 100%; height: 40px; background: lightblue">{{cr}}</div></div>`,props: ["title", "cr"]
});
- 引用組件
<div id="app-22"><!-- 組件的引用必須在 vue 實例指定的容器中 --><page-frame title="標題" cr="地址"><template slot="slot1"><input /> <button>搜索</button></template><template slot="slot2"><div><a href="#">首頁</a><a href="#">后臺</a><a href="#">管理</a><a href="#">關于</a></div></template></page-frame>
</div>
10.4.3 插槽作用域
- 定義組件時,將組件中的數據綁定到
slot
標簽
my-components-bar-slot.js:
Vue.component('page-frame-scope', {template: `<div><div id="header" style="width: 100%; height: 100px; background: pink">{{title}}<br />slot1 : <br /><slot name="slot1"></slot></div><div style="width: 100%; height: 580px">slot2 : <br /><slot name="slot2" v-bind:sites="sites"></slot></div><div id="footer" style="width: 100%; height: 40px; background: lightblue">{{cr}}</div></div>`,props: ["title", "cr"],data: function () {return {sites: [{"name": "菜鳥教程","url": "www.runoob.com"},{"name": "google","url": "www.google.com"},{"name": "微博","url": "www.weibo.com"}]}}
});
- 引用組件時,在填充插槽的模板上使用
slot-scopt
屬性獲取插槽綁定的值
<page-frame-scope title="標題" cr="地址"><template slot="slot1"><input /> <button>搜索</button></template><template slot="slot2" slot-scope="res"><table class="table table-bordered"><tr><th>名稱</th><th>網站</th></tr><tr v-for="site in res.sites"><td>{{site.name}}</td><td>{{site.url}}</td></tr></table></template>
</page-frame-scope>
十一、axios 異步通信
11.1 axios 介紹
vue 可以實現數據的渲染,但是如何獲取數據呢?
vue 本身不具備通信能力,通常結合 axios —— 一個專注于異步通信的 js 框架來使用(Vue.js 2.0 版本推薦使用 axios 來完成 ajax 請求。)
- axios 數據通信
- vue 數據渲染
- 什么是 axios ?
? Axios 是一個基于 promise 的 HTTP 庫,可以用在瀏覽器和 node.js 中。
- 菜鳥教程
axios
說明文檔:https://www.runoob.com/vue2/vuejs-ajax-axios.html - 中文文檔:http://www.axios-js.com/
11.2 axios 入門使用
- axios —— 實現步驟復雜
- JQuery 笨重
- axios 簡潔、高效,對 RESTful 支持良好
11.3 axios 異步請求方法
axios 提供了多種異步請求方法,實現對 RESTful 風格的支持
11.3.1 GET 格式的請求
-
axios.get(url).then(function);
-
使用 response.data 讀取 JSON 數據:
axios.get('json/json_demo.json').then(response => (this.info = response.data.sites)).catch(function (error) {console.log(error) })
-
-
axios.get(url,{}).then(function);
-
GET 方法傳遞參數格式 (使用 axios 的 get 請求傳遞參數,需要將參數設置在 params 下)
// 直接在 URL 上添加參數 ID=12345 axios.get('/user?ID=12345').then(function (response) {console.log(response);}).catch(function (error) {console.log(error);});// 也可以通過 params 設置參數: axios.get('/user', {params: {ID: 12345}}).then(function (response) {console.log(response);}).catch(function (error) {console.log(error);});
-
11.3.2 POST 格式的請求
-
axios.post(url, {}).then(function);
-
axios.post("https://localhost:9098/blog/upload", {name: "張三",age: "20"}).then(response => (this.info2 = response)).catch(function (error) {console.log(error) })
-
11.3.3 自定義請求
自定義請求:自定義請求方式、請求參數、請求頭、請求體(post)
axios({url: "https://localhost:9098/blog/upload",method: "post",params: {// 設置請求行傳值name: "張三",limit: 15},headers: {// 設置請求頭},data: {// 設置請求體 (post / put)}
}).then(function (res) {console.log(res)
});
11.3.4 請求方法別名
- axios.request(config)
- axios.get(url[, config])
- axios.delete(url[, config])
- axios.head(url[, config])
- axios.post(url[, data[, config]])
- axios.put(url[, data[, config]])
- axios.patch(url[, data[, config]])
當使用別名方法時,不需要在config中指定url,method和data屬性。
11.4 并發請求
axios.all()、axios.spread() 兩個輔助函數用于處理同時發送多個請求,可以實現在多個請求都完成后再執行一些邏輯。
處理并發請求的助手函數:
- axios.all(iterable)
- axios.spread(callback)
<div id="app-25"><button type="button" @click="test">測試</button>
</div><script type="text/javascript">var vm = new Vue({el: "#app-25",data: {},methods: {test: function () {// 發送異步請求axios.all([f1(), f2()]).then(axios.spread(function (res1, res2) {// 兩個請求都要執行完畢console.log("所有請求都完成")console.log(res1);console.log(res2);}));}}});function f1() {console.log('調用第一個接口')return axios.get("json/json_demo.json");}function f2() {console.log('調用第二個接口')return axios.get("json/json_demo2.json");}
</script>
注:兩個請求執行完成后,才執行 axios.spread() 中的函數,且 axios.spread() 回調函數的的返回值中的請求結果的順序和請求的順序一致
F12 查看控制臺輸出情況
11.5 箭頭函數
11.5.1 axios 回調函數的參數 res
res 并不是接口返回的數據,而是表示一個響應數據:res.data 才表示接口響應的數據
11.5.2 箭頭函數
<script type="text/javascript">var vm = new Vue({el: "#app-24",data: {songs: ""},methods: {test4: function () {// 發送異步請求axios.get("json/json_demo2.json").then((res) => {// res 并不是接口返回的數據,而是表示一個響應數據:res.data 才表示接口響應的數據this.songs = res.data;console.log(res.data)})}}})
</script>
十二、 路由 router
router 是由 vue 官方提供的用于實現組件跳轉的插件。
Vue Router 是 Vue.js (opens new window)官方的路由管理器。它和 Vue.js 的核心深度集成,讓構建單頁面應用變得易如反掌。
12.1 路由插件的引用
12.1.1 離線
12.1.2 在線 CDN
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
當你要把 Vue Router 添加進來,我們需要做的是,將組件 (components) 映射到路由 (routes),然后告訴 Vue Router 在哪里渲染它們。
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title><style type="text/css">body {padding: 0px;margin: 0px;}ul {list-style: none;}ul li {display: inline;float: left;margin-left: 15px;}</style><script src="https://unpkg.com/vue/dist/vue.js"></script><script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
</head>
<body><div id="app-26"><div style="width: 100%; height: 70px; background: #00BFFF;"><table><tr><td><img src="img/1.jpg" height="70" style="margin-left: 100px;" /></td><td><ul><li><router-link to="/index">首頁</router-link></li><li><router-link to="/java">Java</router-link></li><li><router-link to="/python">Python</router-link></li><li><router-link to="/vue">Vue</router-link></li></ul></td></tr></table></div><div style="width: 100%; height: 680px; background: salmon;"><router-view></router-view></div></div><script type="text/javascript"><!-- vue 的路由旨在為單頁面應用開發提供便攜 -->// 定義鏈接跳轉的模板(組件)const t1 = {template: `<p align="center">index</p>`};const t2 = {template: `<p align="center" >Java</p>`};const t3 = {template: `<p align="center">Python</p>`};const t4 = {template: `<p align="center">Vue</p>`};const my_router = new VueRouter({routes: [{path: '/index',component: t1},{path: '/java',component: t2},{path: '/python',component: t3},{path: '/vue',component: t4}]});var vm = new Vue({el: '#app-26',router: my_router});</script></body>
</html>
點擊鏈接,根據路由,跳轉并顯示對應的組件模板
12.2 動態路由匹配
12.2.1 通配符
*
可以匹配任意路徑
例如:
/user-*
匹配所有以user-
開頭的任意路徑/*
匹配所有路徑
const my_router = new VueRouter({routes: [{path: '/user-*',component: t4},{path: '/*',component: t5}]
});
注意:如果使用通配符定義路徑,需要注意路由聲明的順序
12.2.2 路由參數
/index/:id
可以匹配/index/
開頭的路徑
<div id="app-27"><router-link to="/index/101">首頁</router-link><router-view></router-view>
</div><script type="text/javascript"><!-- vue 的路由旨在為單頁面應用開發提供便攜 -->// 1. 定義鏈接跳轉的模板(組件)const t1 = {template: `<p align="center">index {{$route.params.id}}</p>`};// 2. 定義路由const my_router = new VueRouter({routes: [{path: '/index/:id',component: t1}]});// 3. 引用路由var vm = new Vue({el: '#app-27',router: my_router});
</script>
12.2.3 優先級
如果一個路徑匹配了多個路由,則按照路由的配置順序:路由定義的越早優先級就越高。
12.3 嵌套路由
在一級路由的組件中顯示二級路由
<div id="app-28"><div style="width: 100%; height: 20px; background: #00BFFF;"><router-link to="/index">首頁</router-link><router-link to="/index/t2">首頁-t2</router-link><router-link to="/index/t3">首頁-t3</router-link><router-view></router-view></div>
</div><script type="text/javascript"><!-- vue 的路由旨在為單頁面應用開發提供便攜 -->// 1. 定義鏈接跳轉的模板(組件)const t1 = {template: `<div style="width: 400px; height: 200px; border: blue 1px solid" >index<hr /><router-view></router-view></div>`};const t2 = {template: `<div>t2</div>`};const t3 = {template: `<div>t3</div>`};// 2. 定義路由const my_router = new VueRouter({routes: [{path: '/index',component: t1,children: [{path: "t2",component: t2},{path: "t3",component: t3}]},]});// 3. 引用路由var vm = new Vue({el: '#app-28',router: my_router});
</script>
12.4 編程式導航
12.4.1 push()
<div id="app-29"><div style="width: 100%; height: 20px; background: #00BFFF;"><!-- <router-link to="/index">首頁</router-link> --><button type="button" @click="test">首頁按鈕</button><router-view></router-view></div>
</div><script type="text/javascript"><!-- vue 的路由旨在為單頁面應用開發提供便攜 -->// 1. 定義鏈接跳轉的模板(組件)const t1 = {template: `<div style="width: 400px; height: 200px; border: blue 1px solid" >index</div>`};// 2. 定義路由const my_router = new VueRouter({routes: [{path: '/index',component: t1}]});// 3. 引用路由var vm = new Vue({el: '#app-29',router: my_router,methods: {test: function () {// js 代碼實現路由跳轉,編程式導航my_router.push("/index");}}});
</script>
12.4.2 push() 參數
// 1. 字符串
my_router.push("/index");// 2. 對象
my_router.push({path: "/index"});// 3. 命名的路由 name 參數指的是定義路由時指定的名字
my_router.push({name: "r1", params: {id: 101}});// 4. URL 傳值,相當于 /index?id=101
my_router.push({path: "/index", query: {id: 101}});
12.4.3 replace()
功能與 push() 一致,區別在于 replace() 不會向 history 添加新的瀏覽記錄
12.4.4 go()
參數為一個整數,表示在瀏覽器歷史記錄中前進或后退多少步 相當于
windows.history.go(-1)
的作用
12.5 命名路由
命名路由:在定義路由的時候可以給路由指定 name,我們在進行路由導航時可以通過路由的名字導航
<div id="app-30"><div style="width: 100%; height: 20px; background: #00BFFF;"><input type="text" v-model="rName" /><router-link :to="{name: rName}">t1</router-link><button type="button" @click="test">首頁按鈕2</button><router-view></router-view></div>
</div><script type="text/javascript"><!-- vue 的路由旨在為單頁面應用開發提供便攜 -->// 1. 定義鏈接跳轉的模板(組件)const t1 = {template: `<div style="width: 400px; height: 200px; border: blue 1px solid" >t1</div>`};const t2 = {template: `<div style="width: 400px; height: 200px; border: blue 1px solid" >t2</div>`};// 2. 定義路由const my_router = new VueRouter({routes: [{path: '/index',name: "r1",component: t1},{path: '/index2',name: "r2",component: t2}]});// 3. 引用路由var vm = new Vue({el: '#app-30',data: {rName: "r1"},router: my_router,methods: {test: function () {// js 代碼實現路由跳轉,編程式導航my_router.push({name: vm.rName});}}});
</script>
12.6 命名視圖
<div id="app-31"><div style="width: 100%; height: 20px; background: #00BFFF;"><router-link to="/index">t1</router-link><router-link to="/index2">t2</router-link><!-- 路由視圖 --><!-- 如果在 HTML 中有一個以上的路由視圖 router-view,需要給 router-view 指定 name,
在路由中需要使用 components 映射多個組件根據 name 設置組件與 router-view 的綁定關系 --><router-view name="v1"></router-view><router-view name="v2"></router-view></div>
</div><script type="text/javascript"><!-- vue 的路由旨在為單頁面應用開發提供便攜 -->// 1. 定義鏈接跳轉的模板(組件)const t11 = {template: `<div style="width: 400px; height: 200px; border: blue 1px solid" >t11</div>`};const t12 = {template: `<div style="width: 400px; height: 200px; border: red 1px solid" >t12</div>`};const t21 = {template: `<div style="width: 400px; height: 200px; border: yellow 1px solid" >t21</div>`};const t22 = {template: `<div style="width: 400px; height: 200px; border: wheat 1px solid" >t22</div>`};// 2. 定義路由const my_router = new VueRouter({routes: [{path: '/index',components: {v1: t11,v2: t12}},{path: '/index2',components: {v1: t21,v2: t22}}]});// 3. 引用路由var vm = new Vue({el: '#app-31',data: {rName: "r1"},router: my_router,methods: {test: function () {// js 代碼實現路由跳轉,編程式導航my_router.push({name: vm.rName});}}});
</script>
12.7 重定向
12.7.1 重定向
訪問 /index
, 重定向到 /login
<div id="app-32"><router-link to="/login">登錄</router-link><router-link to="/index">首頁</router-link><router-view></router-view>
</div><script type="text/javascript"><!-- vue 的路由旨在為單頁面應用開發提供便攜 -->// 1. 定義鏈接跳轉的模板(組件)const t1 = {template: `<div style="width: 400px; height: 200px; border: blue 1px solid" >登錄</div>`};// 2. 定義路由const my_router = new VueRouter({routes: [{path: '/login',component: t1},{path: '/index',redirect: "/login"}]});// 3. 引用路由var vm = new Vue({el: '#app-32',router: my_router});
</script>
- 根據路由命名重定向
// 2. 定義路由
const my_router = new VueRouter({routes: [{path: '/login',name: "r1",component: t1},{path: '/index',// 根據路由路徑重定向// redirect: "/login"// 根據路由命名重定向redirect: {name: "r1"}}]
});
12.7.2 路由別名
<div id="app-32"><router-link to="/login">登錄</router-link><br /><router-link to="/alias-login">(別名)-登錄</router-link> <br /><router-view></router-view>
</div><script type="text/javascript">const t1 = {template: `<div style="width: 400px; height: 200px; border: blue 1px solid" >登錄</div>`};// 2. 定義路由const my_router = new VueRouter({routes: [{path: '/login',alias: "/alias-login",component: t1}]});// 3. 引用路由var vm = new Vue({el: '#app-32',router: my_router});
</script>
12.8 路由組件傳參
可以通過 /url/:attr
方式實現通過路由傳值給組件
<div id="app-33"><router-link to="/login/101">登錄</router-link><br /><router-view></router-view>
</div><script type="text/javascript">const t1 = {template: `<div style="width: 400px; height: 200px; border: blue 1px solid" >登錄:{{$route.params.id}}</div>`};// 2. 定義路由const my_router = new VueRouter({routes: [{path: '/login/:id',component: t1}]});// 3. 引用路由var vm = new Vue({el: '#app-33',router: my_router});
</script>
通過 props
傳參
<div id="app-33"><router-link to="/index/102">首頁t2</router-link><br /><router-view></router-view>
</div><script type="text/javascript">const t2 = {props:["id"],template: `<div style="width: 400px; height: 200px; border: blue 1px solid" >首頁t2:{{id}}</div>`};const my_router = new VueRouter({routes: [{path: '/index/:id',component: t2,props: true}]});// 3. 引用路由var vm = new Vue({el: '#app-33',router: my_router});
</script>