千鋒 Vue 詳細筆記整理

視頻筆記是根據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 中提取數據

在這里插入圖片描述

Model-View-ViewModel —— 概念圖

二、 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}}

  1. 創建一個 HTML 文件

  2. 引入 vue.js 文件

    <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
    
  3. 示例:

<!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 只有在 keyEnter 時調用(觸發 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>

在這里插入圖片描述

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/208491.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/208491.shtml
英文地址,請注明出處:http://en.pswp.cn/news/208491.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

WPF(Windows Presentation Foundation)的 StatusBar控件

WPF&#xff08;Windows Presentation Foundation&#xff09;的 StatusBar 是一種用于顯示狀態欄的控件。狀態欄是用于向用戶提供應用程序的狀態信息或其他相關信息的區域。它通常位于應用程序窗口的底部&#xff0c;并提供一些常見的功能&#xff0c;如顯示進度、狀態文本、通…

[C#] 基于 yield 語句的迭代器邏輯懶執行

眾所周知, C# 可以通過 yield 語句來快速向 IEnumerator 或者 IEnumerable 類型的方法返回值返回一個元素. 但它還有另外一個特性, 就是其內部邏輯的懶執行. 每兩個 yield 語句之間的邏輯都是一個狀態, 只有在調用迭代器的 MoveNext 方法后, 才會執行下一個狀態的邏輯. 在文章中…

澤攸科技二維材料轉移臺的應用場景及優勢

隨著二維材料的廣泛研究和各種潛在應用的開發&#xff0c;對于二維材料樣品的精密操控與轉移的需求日益增加。特別是一些新型二維材料的制備和器件集成制備中&#xff0c;需要在顯微鏡下對樣品進行觀察與定位&#xff0c;并能夠在微米甚至納米量級上精確移動和轉移樣品。 傳統…

集簡云 x 零售企業丨快速集成有贊商城和微盛企微管家,實現私域運營自動化

客戶介紹 某公司是一家知名的飲料廠商&#xff0c;自1998年成立以來&#xff0c;一直致力于研發和生產各種熱門飲品&#xff0c;如果汁、碳酸飲料、礦泉水等。因其獨特的口感和健康的品質深受消費者的喜愛。企業擁有多個知名品牌&#xff0c;享有極高的品牌知名度和市場份額。該…

BGP綜合

1、使用PreVal策略&#xff0c;確保R4通過R2到達192.168.10.0/24。 2、使用AS_Path策略&#xff0c;確保R4迪過R3到達192.168.11.0/24。 3、配置MED策略&#xff0c;確保R4通過R3到達192.168.12.0/24。 4、使用Local Preference策略&#xff0c;確保R1通過R2到達192.168.1.0…

Mac電腦系統管理:iStat Menus中文 for Mac

iStat Menus是一款強大而靈活的系統監控工具&#xff0c;可以幫助Mac用戶實時監控和管理自己的電腦。它提供了豐富的系統狀態和性能指標&#xff0c;可自定義的菜單欄圖標以及歷史數據記錄功能&#xff0c;讓用戶能夠全面了解和掌握電腦的運行情況。 實時系統監控&#xff1a;i…

Django的Auth模塊

Auth模塊 我們在創建好一個Django項目后執行數據庫遷移命令會自動生成很多表 其中有auth_user等表 Django在啟動之后就可以直接訪問admin路由&#xff0c;需要輸入用戶名和密碼&#xff0c;數據參考的就是auth_user表&#xff0c;并且必須是管理員才能進入 依賴于a…

flink1.12.4消費kafka 報錯 The coordinator is not available

報錯 You should retry committing the latest consumed offsets. Caused by: org.apache.kafka.common.errors.CoordinatorNotAvailableException: The coordinator is not available. 但是任務還在正常跑. 開源bug [FLINK-28060] Kafka Commit on checkpointing fails rep…

12.8 作業 C++

使用手動連接&#xff0c;將登錄框中的取消按鈕使用qt4版本的連接到自定義的槽函數中&#xff0c;在自定義的槽函數中調用關閉函數 將登錄按鈕使用qt5版本的連接到自定義的槽函數中&#xff0c;在槽函數中判斷ui界面上輸入的賬號是否為"admin"&#xff0c;密碼是否為…

一篇文章熟練掌握 Axios

Axios是什么 Axios是一個基于Promise的網絡請求庫&#xff0c;作用于node.js和瀏覽器中。在服務端使用原生node.js http模塊&#xff0c;在客戶端使用XMLHttpRequest。是基于Promise對Ajax的封裝。 Axios的特性 從瀏覽器創建XMLHttpRequests從node.js創建http請求支持Promis…

基于OpenCV的人臉識別系統案例

基于OpenCV的人臉識別系統案例 人臉識別簡介代碼實現案例應用情況 下面將介紹如何使用Python和OpenCV庫構建一個簡單但強大的人臉識別系統。人臉識別是計算機視覺領域的一個重要應用&#xff0c;具有廣泛的實際用途&#xff0c;從安全門禁到娛樂應用。 人臉識別簡介 人臉識別是…

MySQL - 表達式With as 語句的使用及練習

目錄 8.1 WITH AS 的含義 8.2 WITH AS語法的基本結構如下&#xff1a; 8.3 練習題1 8.4 牛客練習題 8.1 WITH AS 的含義 WITH AS 語法是MySQL中的一種臨時結果集&#xff0c;它可以在SELECT、INSERT、UPDATE或DELETE語句中使用。通過使用WITH AS語句&#xff0c;可以將一個查…

量子芯片技術:未來的計算革命

量子芯片技術&#xff1a;未來的計算革命 一、引言 隨著科技的不斷發展&#xff0c;人類正在進入一個全新的技術時代&#xff0c;即量子時代。量子芯片技術作為這個時代的重要代表&#xff0c;正逐漸改變我們對計算和信息處理的理解。本文將深入探討量子芯片技術的基本原理、…

Navicat 技術指引 | 適用于 GaussDB 分布式的服務器對象的創建/設計

Navicat Premium&#xff08;16.3.3 Windows版或以上&#xff09;正式支持 GaussDB 分布式數據庫。GaussDB分布式模式更適合對系統可用性和數據處理能力要求較高的場景。Navicat 工具不僅提供可視化數據查看和編輯功能&#xff0c;還提供強大的高階功能&#xff08;如模型、結構…

Java入門 EditPlus的安裝與配置講解

寫Java程序不建議使用EditPlus&#xff0c;首選idea社區版&#xff0c;其次是vscode&#xff0c; 然后是eclipse 。editplus說實話排不上號。 但既然小伙伴想了解一下怎么配置&#xff0c;這里就簡單說一下。 下載 首先是jdk&#xff0c;jdk是Java開發和運行的基礎&#xff…

EVT_WDF_DEVICE_PREPARE_HARDWARE API

NTSTATUS EVT_WDF_DEVICE_PREPARE_HARDWARE(__inWDFDEVICE Device,__inWDFCMRESLIST ResourcesRaw,__inWDFCMRESLIST ResourcesTranslated); 上面API中ResourcesRaw和ResourcesTranslated類型相同&#xff0c;那他們的區別是啥&#xff1f; 答&#xff1a; EVT_WDF_DEVICE_P…

【前端設計模式】之訪問者模式

引言 在前端開發中&#xff0c;我們經常需要處理復雜的對象結構和數據集合。這時候&#xff0c;訪問者模式就能派上用場了。訪問者模式允許我們將操作和數據結構分離開來&#xff0c;從而實現對復雜對象結構的優雅處理。 訪問者模式的特性 訪問者模式具有以下特性&#xff1…

iview Table實現跨頁勾選記憶功能以及利用ES6的Map數據結構實現根據id進行對象數組的去重

因為iview Table組件的勾選是選中當前頁的所有數據,當我們切到別的頁面時,會發送請求給后端,這個時候就會刷新我們之前頁碼已經選中的數據。現在有個需求就是,在我們選擇不同頁碼的數據勾選中之后,實現跨頁勾選記憶功能,就是說已經打鉤了的數據,不管切到哪一頁它都是打鉤…

AI聊天專題報告:ChatGPT全景圖聊聊技術產品和未來

今天分享的AI系列深度研究報告&#xff1a;《AI聊天專題報告&#xff1a;ChatGPT全景圖聊聊技術產品和未來》。 &#xff08;報告出品方&#xff1a;LanguageX&#xff09; 報告共計&#xff1a;22頁 爭論&#xff1a;ChatGPT算不算技術革命 回應吳軍老師“ChatGPT不算新技術…

Navicat 技術指引 | 適用于 GaussDB 分布式的模型功能

Navicat Premium&#xff08;16.3.3 Windows 版或以上&#xff09;正式支持 GaussDB 分布式數據庫。GaussDB 分布式模式更適合對系統可用性和數據處理能力要求較高的場景。Navicat 工具不僅提供可視化數據查看和編輯功能&#xff0c;還提供強大的高階功能&#xff08;如模型、結…