介紹
- Vue.js 中文文檔地址:https://cn.vuejs.org/guide/introduction.html#what-is-vue
Vue.js 是什么
- Vue (讀音 /vju?/,類似于 view) 是一套用于構建用戶界面的漸進式框架。與其它大型框架不同的是,Vue 被設計為可以自底向上逐層應用。Vue 的核心庫只關注視圖層,不僅易于上手,還便于與第三方庫或既有項目整合。另一方面,當與現代化的工具鏈以及各種支持類庫結合使用時,Vue 也完全能夠為復雜的單頁應用提供驅動。
Vue.js 優點
前端三要素
- HTML + CSS + JavaScript
CSS 預處理器
JavaScript 框架
UI 框架
JavaScript 構建工具
常用的 Vue UI 組件庫
vue-element-admin
- 簡述:vue-element-admin 是一個后臺前端解決方案,它基于 vue 和 element-ui實現。它使用了最新的前端技術棧,內置了 i18 國際化解決方案,動態路由,權限驗證,提煉了典型的業務模型,提供了豐富的功能組件,它可以幫助你快速搭建企業級中后臺產品原型。相信不管你的需求是什么,本項目都能幫助到你。
- 地址:https://panjiachen.github.io/vue-element-admin-site/zh/
MVVM 模式
為什么使用 MVVM 模式
第一個 Vue 程序
IDEA 安裝插件
使用 IDEA 工具開發,可安裝 Vue.js 插件!
在 IDEA 中安裝插件后,可快速構建 vue 文件:
PS:若安裝插件后也沒有出現快速構建 vue 文件的選項,可先手動創建 .vue 結尾的空文件,再次新建時,則可成功顯示!
CDN 簡述
-
智能 dns 讓用戶可以訪問同線路最近的服務器
-
cdn 的緩存機制可以加快訪問速度,也可以緩解源站服務器壓力(因為根本不會去訪問源站)
-
cdn 讓大規模的用戶請求架構變得簡單
-
cdn 性價比高,同帶寬需求下 cdn 服務比增加帶寬劃算
作用:盡可能避開互聯網上有可能影響數據傳輸速度和穩定性的瓶頸和環節,使內容傳輸得更快、更穩定。
安裝
可使用多種方式進行安裝,如直接下載對應類庫、使用 CDN 引入、使用 NPM 安裝等...
此處使用 CDN:
- 壓縮版:
<script src="https://cdn.bootcss.com/vue/2.5.16/vue.min.js"></script>
- 完整版:
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
示例代碼
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>first vue</title>
</head>
<body>
<!--view層:模板-->
<div id="app">
<h2>{{message}}</h2>
</div>
<!--使用CDN方式導入Vue.js-->
<script src="https://cdn.bootcss.com/vue/2.5.16/vue.min.js"></script>
<script>
var vm = new Vue({
el: "#app",
//Model: 數據
data: {
message: "hello,vue!"
}
});
</script>
</body>
</html>
相關指令
v-bind
-
作用:與指定屬性進行綁定
-
v-bind:
可簡寫為:
-
示例:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>test</title> </head> <body> <!--view層:模板--> <div id="app"> <h2>{{message}}</h2> <span v-bind:title="message"> 鼠標懸浮幾秒查看動態綁定的提示信息! </span> <!-- v-bind可簡寫 --> <input type='text' :value="str" /> </div> <!--使用CDN方式導入Vue.js--> <script src="https://cdn.bootcss.com/vue/2.5.16/vue.min.js"></script> <script> var vm = new Vue({ el: "#app", //Model: 數據 data: { message: "hello,vue!", str: "test str" } }); </script> </body> </html>
v-if、v-else-if、v-else
-
作用:判斷
-
示例:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>test3</title> </head> <body> <div id="app"> <h1 v-if="ok">yes</h1> <h1 v-else>no</h1> <span v-if="type==='A'">A</span> <span v-else-if="type==='B'">B</span> <span v-else>D</span> </div> <!-- 導入vue.js --> <script src="https://cdn.bootcss.com/vue/2.5.16/vue.min.js"></script> <script> var vm = new Vue({ el: "#app", data: { ok: true, type: 'A' } }); </script> </body> </html>
v-show
- 作用:判斷
- 說明:從功能上講,
v-show
和v-if
作用是相同的,主要是他們的渲染過程有區別。
除了
v-if
,還有一個可以按條件顯示一個元素的指令是v-show
。其用法基本一樣:<h1 v-show="ok">Hello!</h1>
不同之處在于
v-show
會在 DOM 渲染中保留該元素;v-show
僅切換了該元素上名為display
的 CSS 屬性。
v-show
不支持在<template>
元素上使用,也不能和v-else
搭配使用。
v-if
vs.v-show
v-if
是“真實的”按條件渲染,因為它確保了在切換時,條件區塊內的事件監聽器和子組件都會被銷毀與重建。
v-if
也是惰性的:如果在初次渲染時條件值為 false,則不會做任何事。條件區塊只有當條件首次變為 true 時才被渲染。相比之下,
v-show
簡單許多,元素無論初始條件如何,始終會被渲染,只有 CSSdisplay
屬性會被切換。總的來說,
v-if
有更高的切換開銷,而v-show
有更高的初始渲染開銷。因此,如果需要頻繁切換,則使用v-show
較好;如果在運行時綁定條件很少改變,則v-if
會更合適。
v-for
-
作用:循環
-
示例:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>test4</title> </head> <body> <div id="app"> <ul>編程語言 <li v-for="item in items"> {{item.message}} </li> </ul> <ol>編程語言(顯示下標) <li v-for="(item, index) in items"> {{item.message}} --> {{index}} </li> </ol> </div> <!-- 導入vue.js --> <script src="https://cdn.bootcss.com/vue/2.5.16/vue.min.js"></script> <script> var vm = new Vue({ el: "#app", data: { items: [ {message: "java"}, {message: "python"}, {message: "go"} ] } }); </script> </body> </html>
v-on
-
作用:事件監聽
-
v-on:click
可簡寫為@click
-
示例:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>test5</title> </head> <body> <div id="app"> <p>{{message}}</p> <button v-on:click="reverseMessage">反轉消息</button> </div> <!-- 導入vue.js --> <script src="https://cdn.bootcss.com/vue/2.5.16/vue.min.js"></script> <script> var vm = new Vue({ el: "#app", data: { message: "Hello Vue.js!"}, methods: { reverseMessage: function () { this.message = this.message.split('').reverse().join(''); } } }); </script> </body> </html>
v-model
-
作用:實現數據的雙向綁定
-
說明:使用該指令可在
<input>、<textarea>、<select>
等元素上創建雙向數據綁定,會根據控件類型自動選取正確方法來更新元素。它負責監聽用戶的輸入事件以更新數據,并對一些極端場景進行一些特殊處理。 -
注意:
v-model
會忽略所有表單元素的 value、checked、selected 特性的初始值而總是將 Vue 實例的數據作為數據來源,所以開發者應該通過 JavaScript 在組件的 data 選項中聲明初始值! -
v-model 又稱表單標簽,主要作用就是實現表單標簽的的雙向綁定;
它只能使用在表單輸入標簽,因為需要通過表單輸入標簽輸入的內容,來改變其他地方的數據;
v-model:value
可以簡寫為v-model
,需要明確它默認就是綁定的 value 屬性。 -
示例:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>test6</title> </head> <body> <div id="app"> 單行文本: <input type="text" v-model="message"> {{message}} <br><br> 文本域: <textarea v-model="texts"></textarea> {{texts}} <br><br> 單選按鈕:<br> 性別: <input type="radio" name="sex" value="男" v-model="gender">男 <input type="radio" name="sex" value="女" v-model="gender">女 <br> <span>選中了【{{gender}}】</span> <br><br> 下拉框: <select v-model="selected"> <option value="" disabled>--請選擇--</option> <option>A</option> <option>B</option> <option>C</option> </select> <span>value:{{selected}}</span> </div> <!-- 導入vue.js --> <script src="https://cdn.bootcss.com/vue/2.5.16/vue.min.js"></script> <script> var vm = new Vue({ el: "#app", data: { selected: '', message: "123", texts: '', gender: '' } }); </script> </body> </html>
vue 實例
每個使用 vue 進行數據渲染的網頁文檔都需要創建一個 Vue 實例——ViewModel
Vue 實例的生命周期
vue 實例的生命周期:vue 實例從創建到銷毀的過程
- 創建 vue 實例:初始化 data,加載 el
- 數據掛載:將 vue 實例 data 中數據渲染到網頁 HTML 標簽
- 重新渲染:當 vue 的 data 數據發生變化,會重新渲染到 HTML 標簽
- 銷毀實例
鉤子函數
為便于開發者在 vue 實例生命周期不同階段進行特定的操作,vue 在生命周期四個階段的前后分別提供了一個函數,這個函數無須開發者調用,當 vue 實例到達生命周期的指定階段,會自動進行相關函數的調用,這些函數稱為鉤子函數。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<script src="https://cdn.bootcss.com/vue/2.5.16/vue.min.js"></script>
</head>
<body>
<div id="container">
<label v-once>{{str}}</label><br />
<label>{{str}}</label><br />
<input type="text" v-model="str" />
</div>
<script type="text/javascript">
var vm = new Vue({
el: "#container",
data: {
str: "初始數據"
},
beforeCreate: function() {
//1.data初始化之前執,不能操作data
console.log("beforeCreate------->1");
},
created: function() {
//2.data初始化之后執行,模板加載之前,可以修改/獲取data中的值
console.log(this.str);
console.log("created------->2");
//this.str = "data初始化之后執行";
},
beforeMount: function() {
//3.模板加載之后,數據初始渲染(掛載)之前,可以修改/獲取data中的值
//this.str = "數據初始渲染(掛載)之前執行";
console.log("beforeMount------->3");
},
mounted: function() {
//4.數據初始渲染(掛載)之后,可以對data中的變量進行修改,但是不會影響v-once的渲染
//this.str = "數據初始渲染(掛載)之后執行";
console.log("mounted------->4");
},
beforeUpdate: function() {
//5.數據渲染之后,當data中的數據變化觸發重新渲染,渲染之前執行此函數
// data數據被修改之后,重新渲染到html之前
console.log("-----" + this.str);
this.str = "數據被修改,重新被渲染到html之前";
console.log("beforeUpdate------->5");
},
updated: function() {
//6.data數據被修改之后,重新渲染到html之后
//this.str = "數據被修改,重新渲染都html后";
console.log("updated------->6");
},
beforeDestroy: function() {
//7.實例銷毀之前
console.log("beforeDestroy------->7");
},
destroyed: function() {
//8.實例銷毀之后
console.log("destroyed------->8");
}
});
</script>
</body>
</html>
計算屬性
計算屬性的重點突出在屬性兩個字上(屬性是名詞),首先它是個屬性,其次,這個屬性有計算的能力(計算是動詞),這里的計算就是個函數;簡單點說,他就是一個能夠將計算結果緩存起來的屬性(將行為轉化成了靜態的屬性),僅此而已;也可以將其想象成緩存!
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>test9</title>
<!--引入Vue.js-->
<script src="https://cdn.bootcss.com/vue/2.5.16/vue.min.js"></script>
</head>
<body>
<div id="vue">
<!--注意:一個是方法,一個是屬性!-->
<p>調用當前時間的方法:{{currentTime1()}}</p> <!--方法調用需要帶括號-->
<p>當前時間的計算屬性:{{currentTime2}}</p> <!--屬性調用不能帶括號-->
</div>
<script type="text/javascript">
var vm = new Vue({
el: '#vue',
data: {message: 'Hello Vue.js!'},
// 注意:methods 和 computed 里的東西不能重名!
methods: { //在此可定義方法,調用方法需要帶()
//currentTime1:這是一個方法!
currentTime1: function () {
return Date.now();
}
},
computed: { //在此可定義計算屬性,調用屬性不需要帶()
//currentTime2:這是一個屬性,不是方法!
currentTime2: function () {
this.message; //作用:通過改變該值,觀察currentTime2屬性值的變化
return Date.now();
}
}
});
</script>
</body>
</html>
測試結果:(F12 --》控制臺)
vm.currentTime1()
1656988519767
vm.currentTime1()
1656988521888
vm.currentTime1()
1656988524916
結論:調用方法,每次都需要重新計算
vm.currentTime2()
Uncaught TypeError: vm.currentTime2 is not a function
<anonymous> debugger eval code:1
debugger eval code:1:4
結論:計算屬性是屬性,調用時不能帶括號
vm.currentTime2
1656988393581
vm.currentTime2
1656988393581
vm.currentTime2
1656988393581
結論:計算屬性將不經常變化的計算結果緩存了起來,只有發生變化的時候才會重新計算
vm.message = 'new data';
"new data"
vm.currentTime2
1656988775105
vm.currentTime2
1656988775105
結論:計算屬性中的值被改變時,計算結果重新計算,并重新進行緩存
說明:如果計算屬性中的值發生變化時,則緩存就會刷新,可在控制臺使用vm.message = 'new data';
,改變下數據的值,再次測試并觀察效果!
結論:調用方法時,每次都需要重新計算,既然有計算過程,則必定會產生系統開銷,如果這個結果是不經常變化的,則可以考慮將這個結果緩存起來,采用計算屬性就可以很方便的做到這一點!計算屬性的主要特性就是為了將不經常變化的計算結果進行緩存,以節約系統開銷。
偵聽器
偵聽器,就是 data 中屬性的監聽器,當 data 中的屬性值發?變化就會觸發偵聽器函數的執?。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<script src="https://cdn.bootcss.com/vue/2.5.16/vue.min.js"></script>
</head>
<body>
<div id="container">
<input type="text" v-model="str1" /><br />
<input type="text" v-model="str2" /><br />
{{str3}}
</div>
<script type="text/javascript">
var vm = new Vue({
el: "#container",
data: {
str1: "江蘇",
str2: "蘇州",
str3: "江蘇蘇州"
},
watch: {
str1: function() {
this.str3 = this.str1 + this.str2;
},
str2: function() {
this.str3 = this.str1 + this.str2;
}
}
});
</script>
</body>
</html>
類與樣式綁定
我們可以使? mustache 語法將 vue 中 data 的數據綁定到 HTML 標簽及標簽的屬性,如何將 data 中的值綁定到標簽的 class 及 style 屬性呢?下面就是需要介紹的類與樣式綁定—— class 與 style 綁定。
class 綁定
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<script src="https://cdn.bootcss.com/vue/2.5.16/vue.min.js"></script>
<style type="text/css">
.mystyle1 {
width: 200px;
height: 100px;
background: orange;
}
.mystyle3 {
width: 200px;
height: 100px;
background: black;
}
.my-style2 {
border-radius: 10px;
}
</style>
</head>
<body>
<div id="container">
<!--如果b1為true就加載 mystyle1;如果b2為true,則加載my-style2-->
<!-- 注意:如果樣式名中有特殊字符如橫杠,需要添加單引號 -->
<div :class="{mystyle1:b1,'my-style2':b2}"></div>
<!--為class屬性加載多個樣式名 -->
<div :class="[chooseStyle1,chooseStyle2]"></div>
<!--如果b3為true,則class='mystyle3'; 否則class='mystyle1'
如果在三目運算中使用樣式名則需加單引號,不加單引號則表示從data變量中獲取樣式名-->
<div :class="[b3 ? 'mystyle3' : 'mystyle1']"></div>
<div :class="[b3 ? chooseStyle3 : chooseStyle1]"></div>
</div>
<script type="text/javascript">
var vm = new Vue({
el: "#container",
data: {
b1: true,
b2: true,
b3: false,
chooseStyle1: "mystyle1",
chooseStyle2: "my-style2",
chooseStyle3: "mystyle3"
}
});
</script>
</body>
</html>
style 綁定
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<script src="https://cdn.bootcss.com/vue/2.5.16/vue.min.js"></script>
</head>
<body>
<div id="container">
<!--當使用v-bind綁定內聯樣式時:
1. 使用{}定義style樣式,才能獲取data中的值,{}要遵循JSON格式
2. {}中不再使用style樣式屬性名“font-size”,要使用對應的js屬性名
border-style-width ---》 borderStyleWidth(橫杠連接變駝峰形式)
-->
<div v-bind:style="{color: colorname,fontSize: fontsize+'px'}">vue之style綁定</div>
<!--我們可以直接為style屬性綁定一個data中定義好的內聯樣式的字符串-->
<div v-bind:style="mystyle1">vue之style綁定</div>
<!--我們可以直接為style屬性綁定一個data中定義好的內聯樣式的對象-->
<div v-bind:style="mystyle2">vue之style綁定</div>
<!--可以在同一個style上通過數組引用多個內聯樣式的對象-->
<div v-bind:style="[mystyle2,mystyle3]">vue之style綁定</div>
</div>
<script type="text/javascript">
var vm = new Vue({
el: "#container",
data: {
colorname: "green",
fontsize: 30,
mystyle1: "color:orange;font-size:45px",
mystyle2: {
color: "blue",
fontSize: "40px"
},
mystyle3: {
textShadow: "orange 3px 3px 5px"
}
}
});
</script>
</body>
</html>
事件處理
事件綁定傳值的三種方式
在使? vue 進?數據渲染時,如果使?原? js 事件綁定(例如 onclick ),則需要獲取 vue 實例中的數據,并傳參,而且需要通過拼接來完成。
vue 提供了 v-on 指令?于綁定各種事件(
v-on:click
),簡化了從 vue 取值的過程,但是觸發的?法需要定義在 vue 實例的 methods 中,如下:<button type="button" v-on:click="doDelete(s.stuNum,s.stuName)">刪除</button> <script type="text/javascript"> var vm = new Vue({ el:"#container", data:{}, methods:{ doDelete:function(snum,sname){ console.log("----delete:"+snum+" "+sname) } } }); </script>
PS:
v-on:click
可以縮寫為@click
1. 使用 JS 函數傳值(不建議)
<button type="button" v-on:click="doDelete(s.stuNum,s.stuName)">刪除</button>
<script>
var vm = new Vue({
el:"#container",
data:{};
methods:{
doDelete:function(snum,sname){
console.log("----delete:"+snum+" "+sname)
}
}
});
</script>
2. 使? dataset 對象傳值(推薦)
說明:
推薦直接調用方法;
需要傳遞的參數使用
:data-xxx="數據"
格式進行傳遞;參數獲取通過方法定義時添加的 event 參數中獲??;
<button type="button" @click="doUpdate" :data-snum="s.stuNum" :data-sname="s.stuName" :data-simg="s.stuImg">修改</button>
<script>
var vm = new Vue({
el:"#container",
data:{};
methods:{
doUpdate:function(event){
//如果v-on綁定的js函數沒有參數,調?的時候可以省略(),同時可以給
//js函數?個event參數(事件對象)
// 1. event 表示觸發當前函數的事件
// 2. event.srcElement 表示發?事件的元素---修改按鈕
// 3. event.srcElement.dataset 表示按鈕上綁定的數據集(data-開頭的屬性)
console.log("-----update")
var stu = event.srcElement.dataset;
}
}
});
</script>
3. 混合使?傳值
混合傳值,方法參數中事件參數 event 需要注意,必須使用
$event
。
<button type="button" v-on:click="doDelete(s.stuNum,s.stuName,$event)":data-simg="s.stuImg">刪除</button>
<script>
var vm = new Vue({
el:"#container",
data:{};
methods:{
doDelete:function(snum,sname,event){
console.log("----delete:"+snum+" "+sname)
console.log(event.srcElement.dataset);
}
}
});
</script>
事件修飾符
當使? v-on 進?事件綁定的時候,可以添加特定后綴,設置事件觸發的特性。
下面介紹常用的幾個事件修飾符,更多參考官網:點擊查看
-
.prevent
:消除元素的默認事件 -
.stop
:阻?事件冒泡(阻??標簽向上冒泡) -
.self
:設置只能??觸發事件(?標簽不能觸發) -
.once
:限定事件只觸發?次
使用語法示例:
<button type="submit" @click.prevent="事件函數">測試</button>
.prevent
作用:消除元素的默認事件
示例:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<script src="https://cdn.bootcss.com/vue/2.5.16/vue.min.js"></script>
</head>
<body>
<div id="container">
<form action="https://www.baidu.com">
<button type="submit" class="btn btn-success btn-xs" @click.prevent="test">測試</button>
</form>
</div>
<script type="text/javascript">
var vm = new Vue({
el: "#container",
data: {},
methods: {
test: function() {
console.log("---test");
}
}
});
</script>
</body>
</html>
.stop
和 .self
作用:
-
.stop
:阻?事件冒泡(阻??標簽向上冒泡) -
.self
:設置只能??觸發事件(?標簽不能觸發)
示例:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<script src="https://cdn.bootcss.com/vue/2.5.16/vue.min.js"></script>
</head>
<body>
<div id="container">
<div style="width: 200px; height: 200px; background: red;" @click.self="method1">
<div style="width: 150px; height: 150px; background: green;" @click="method2">
<button type="button" @click.stop="method3">測試</button>
</div>
</div>
</div>
<script type="text/javascript">
var vm = new Vue({
el: "#container",
data: {},
methods: {
method1: function() {
alert("1");
},
method2: function() {
alert("2");
},
method3: function() {
alert("3");
},
}
});
</script>
</body>
</html>
.once
作用:限定事件只觸發?次
示例:略
按鍵修飾符
按鍵修飾符就是針對鍵盤事件的修飾符,限定哪個按鍵會觸發事件。
示例說明:對于下列文本框,輸入文字后,按下回車鍵并彈起時,會觸發事件,調用 method4 方法。
<input type="text" @keyup.enter="method4"/>
針對鍵盤操作的動作,除了 @keyup
還有:@keydown
和 @keypress
Vue 為一些常用的按鍵提供了別名:
.enter
.tab
-
.delete
(捕獲“Delete”和“Backspace”兩個按鍵) .esc
.space
.up
.down
.left
.right
除了以上 vue 提供按鈕的別名之外,我們還可以為按鍵?定義別名。
示例:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<script src="https://cdn.bootcss.com/vue/2.5.16/vue.min.js"></script>
</head>
<body>
<div id="container">
<!--2.使用定義的按鍵別名aaa作為修飾符-->
<input type="text" @keyup.aaa="method4" />
</div>
<script type="text/javascript">
//1.為按鍵J定于別名為 aaa
Vue.config.keyCodes.aaa = 74;
var vm = new Vue({
el: "#container",
data: {},
methods: {
method4: function() {
alert("4");
}
}
});
</script>
</body>
</html>
系統修飾符
組合鍵
可使用以下系統按鍵修飾符來觸發鼠標或鍵盤事件監聽器,只有當按鍵被按下時才會觸發:
.ctrl
.alt
.shift
-
.meta
:windows 鍵
示例:Ctrl + J 觸發事件
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<script src="https://cdn.bootcss.com/vue/2.5.16/vue.min.js"></script>
</head>
<body>
<div id="container">
<input type="text" @keyup.ctrl.j="method4" />
</div>
<script type="text/javascript">
Vue.config.keyCodes.j = 74;
var vm = new Vue({
el: "#container",
data: {},
methods: {
method4: function() {
alert("4");
}
}
});
</script>
</body>
</html>
表單輸入綁定
表單輸?綁定,即雙向綁定,就是能夠將 vue 實例的 data 數據渲染到表單輸?視圖(input\textarea\select 等),也能夠將輸?視圖的數據同步更新到 vue 實例的 data 中。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<script src="https://cdn.bootcss.com/vue/2.5.16/vue.min.js"></script>
</head>
<body>
<div id="container">
<!--文本輸入框、密碼輸入框-->
<input type="text" v-model="text" /><br />
<input type="password" v-model="pwd" /><br />
<!--單選按鈕-->
<input type="radio" v-model="opt1" value="A" />A 3
<input type="radio" v-model="opt1" value="B" />B 4
<input type="radio" v-model="opt1" value="C" />C 5
<input type="radio" v-model="opt1" value="D" />D 6 <br />
<!--復選框,綁定的是一個數組-->
<input type="checkbox" v-model="opt2" value="籃球" />籃球 <br />
<input type="checkbox" v-model="opt2" value="足球" />足球 <br />
<input type="checkbox" v-model="opt2" value="羽毛球" />羽毛球 <br />
<input type="checkbox" v-model="opt2" value="乒乓球" />乒乓球 <br />
<!--下拉菜單select:綁定一個字符串-->
<select v-model="city">
<option value="BJ">北京</option>
<option value="SH">上海</option>
<option value="GZ">廣州</option>
<option value="SZ">深圳</option>
</select>
<br />
<!--下拉菜單select:如果有multiple表示可多選,需要綁定一個數組-->
<select v-model="cities" multiple>
<option value="BJ">北京</option>
<option value="SH">上海</option>
<option value="GZ">廣州</option>
<option value="SZ">深圳</option>
</select>
<br />
<button type="button" @click="test">測試</button>
</div>
<script type="text/javascript">
var vm = new Vue({
el: "#container",
data: {
text: "aaa",
pwd: "111111",
opt1: "C",
opt2: ["籃球", "羽毛球"],
city: "SZ",
cities: ["BJ", "SZ"]
},
methods: {
test: function() {
alert(vm.cities);
}
}
});
</script>
</body>
</html>
組件化應用構建
組件系統是 Vue 的另一個重要概念,因為它是一種抽象,允許我們使用小型、獨立和通??蓮陀玫慕M件構建大型應用。仔細想想,幾乎任意類型的應用界面都可以抽象為一個組件樹:
示例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>test6</title>
</head>
<body>
<div id="app">
<ol>
<!--構建一個組件模板:創建一個 todo-item 組件的實例,使用自定義的Vue組件,遍歷數據,將數據傳遞給綁定的指定屬性-->
<todo-item v-for="item in todoList" v-bind:todo="item"></todo-item>
</ol>
</div>
<!-- 導入vue.js -->
<script src="https://cdn.bootcss.com/vue/2.5.16/vue.min.js"></script>
<script>
//注冊組件:定義名為 todo-item 的新組件
Vue.component("todo-item", {
props: ['todo'],
template: '<li>{{todo.text}}</li>'
});
var vm = new Vue({
el: "#app",
data: {
todoList: [
{id: 0, text: "學英語"},
{id: 1, text: "學技術"},
{id: 2, text: "學做飯"}
]
}
});
</script>
</body>
</html>
組件
組件介紹及示例
組件,就是將通?的 HTML 模塊進?封裝——可復?
組件注冊
將通?的 HTML 模塊封裝注冊到 vue 中
Vue.component("header-bar",{
});
組件引用
- 定義組件需要依賴 vue.js,在引??定義組件的 js ?件之前要先引? vue.js
- 組件的引?必須在 vue 實例 el 指定的容器中
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<div id="container">
<header-bar></header-bar>
</div>
<script type="text/javascript" src="js/vue.js"></script>
<script type="text/javascript" src="js/my-components.js"></script>
<script type="text/javascript">
var vm = new Vue({
el: "#container",
});
</script>
</body>
</html>
組件注冊
自定義組件的結構
-
data
定義組件的模板渲染的數據 -
template
組件的 HTML 模塊(HTML標簽\css樣式) -
methods
定義組件中的標簽事件綁定的 JS 函數
Vue.component("header-bar", {
data: function() {
//組件中的data是通過函數返回的對象
return {
title: "Java電商平臺"
};
},
template: `<div style="width: 100%; height: 80px; background: lightyellow;">
<table width="100%">
<tr>
<td width="200" align="right" valign="middle">
<img src="img/logo.png" height="80">
</td>
<td>
<label style="color: deepskyblue;font-size:32px; font-family: 華文行楷; margin-left: 30px;">
{{title}}
</label>
</td>
<td>
<button @click="test">組件中的按鈕</button>
</td>
</tr>
</table>
</div>`,
methods: {
test: function() {
alert("組件中定義的函數");
}
}
});
組件的封裝
- 將模版中的 css 樣式提出取來,單獨定義到 css ?件存儲在 css ?錄
- 將模版中的圖?存在 img ?錄
- 將定義組件的 js ?件和 vue 的?件存放到 js ?錄
組件的復用
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<link rel="stylesheet" href="css/my-components.css" />
</head>
<body>
<div id="container">
<header-bar></header-bar>
</div>
<script type="text/javascript" src="js/vue.js"></script>
<script type="text/javascript" src="js/my-components.js"></script>
<script type="text/javascript">
var vm = new Vue({
el: "#container"
});
</script>
</body>
</html>
組件通信
vue 實例本身就是?個組件(模板就是 el 指定容器,data 就是組件數據,methods 就是組件的事件函數)
在 vue 實例指定的 el 容器中引?的組件稱為?組件 ,當前 vue 實例就是?組件
父傳子
vue 實例引?組件的時候,傳遞數據到引?的組件中
子傳父
通過?組件的按鈕“調?”?組件的函數,通過函數傳值
組件插槽
當我們?定義 vue 組件時,允許組件中的部分內容在調?組件時進?定義——插槽
插槽的使用
在?定義組件時通過 slot
標簽在組件的模版中定義插槽
Vue.component("header-bar", {
data: function() {
//組件中的data是通過函數返回的對象
return {
str2: "子組件中的數據"
};
},
template: '<div class="divStyle">
<table class="tableStyle">
<tr>
<td width="200" align="right" valign="middle">
<img src="img/logo.png" class="logoImg">
</td>
<td>
<label class="titleStyle">
{{title}}
</label>
</td>
<td>
<slot></slot>
</td>
<td>
<button @click="childMethod">子組件中的按鈕</button>
</td>
</tr>
</table>
</div>',
props: ["title"],
methods: {
childMethod: function() {
this.$emit("my-event", this.str2);
}
}
});
在?組件中調?此組件時,指定插槽填充的模版
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<link rel="stylesheet" href="css/bootstrap.css" />
<link rel="stylesheet" href="css/my-components.css" />
<script type="text/javascript" src="js/jquery-3.4.1.min.js"></script>
<script type="text/javascript" src="js/bootstrap.js"></script>
<script type="text/javascript" src="js/vue.js"></script>
</head>
<body>
<div id="container">
<header-bar :title="sss">
<!--組件標簽包含的HTML默認為填充到插槽的模版-->
<input /><button>搜索</button>
</header-bar>
</div>
<script type="text/javascript" src="js/my-components.js"></script>
<script type="text/javascript">
var vm = new Vue({
el: "#container",
data: {
sss: "自定義標題"
}
});
</script>
</body>
</html>
具名插槽
當組件中的插槽數量 > 1 時,需要給組件中的 slot 標簽添加 name 屬性指定插槽的名字
定義組件
Vue.component("page-frame", {
template: '<div>
<div id="header" style="width:100%;
height:100px;background:pink">
<slot name="s1"></slot>
</div>
<div style="width:100%; height:580px">
<slot name="s2"></slot>
</div>
<div id="footer" style="width:100%;
height:40px;background:lightgray">{{cr}}</div>
</div>',
props: ["title", "cr"]
});
引用組件
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<div id="container">
<page-frame title="標題" cr="vue學習">
<!--定義一個模版,填充到組件的name=s1的 插槽-->
<template slot="s1">
<input type="text" placeholder="歌曲名、歌手" />
<button type="button" @click="doSearch">搜索</button>
</template>
<!--定義一個模版,填充到組件的name=s2的 插槽-->
<template slot="s2">
<table class="table table-bordered table-condensed">
<tr>
<th>序號</th>
<th>歌曲ID</th>
<th>歌曲名</th>
<th>歌手</th>
<th>專輯</th>
<th>時長</th>
<th>操作</th>
</tr>
</table>
</template>
</page-frame>
</div>
</body>
</html>
插槽作用域
定義組件時,將組件中的數據綁定到 slot 標簽
Vue.component("page-frame", {
template: '<div>
<div id="header" style="width:100%;height:100px;background:pink">
<slot name="s1"></slot>
</div>
<div style="width:100%; height:580px">
<slot name="s2" v-bind:musics="songs"></slot>
</div>
<div id="footer" style="width:100%;height:40px;background:lightgray">{{cr}}</div>
</div>',
props: ["title", "cr"],
data: function() {
return {
songs: [{}, {}]
};
}
});
引?組件時,在填充插槽的模版上使? slot-scope
屬性獲取插槽綁定的值
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<div id="container">
<page-frame title="標題" cr="vue學習">
<template slot="s1">
<input type="text" placeholder="歌曲名、歌手" />
<button type="button" @click="doSearch">搜索</button>
</template>
<!--在使用模版填充組件插槽時,可以使用slot-scope屬性獲取組件插槽綁定的數據的集合 -->
<template slot="s2" slot-scope="res">
<table class="table table-bordered table-condensed">
<tr>
<th>序號</th>
<th>歌曲ID</th>
<th>歌曲名</th>
<th>歌手</th>
<th>專輯</th>
<th>時長</th>
<th>操作</th>
</tr>
<tr v-for="song,index in res.musics">
<!--遍歷省略-->
</tr>
</table>
</template>
</page-frame>
</div>
</body>
</html>
插槽 slot 補充
內容分發:在Vue.js
中我們使用<slot>
元素作為承載分發內容的出口,作者稱其為插槽,可應用在組合組件的場景中。
測試:如準備一個待辦事項組件(to-do),該組件由待辦標題(to-do-title)和待辦事項(to-do-items)組成,但這三個組件又相互獨立,該如何操作?
代碼示例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>插槽slot</title>
<!--引入Vue.js-->
<script src="https://cdn.bootcss.com/vue/2.5.16/vue.min.js"></script>
</head>
<body>
<div id="app10">
<to-do>
<to-do-title slot="to-do-title" v-bind:title="toDoTitle"></to-do-title>
<to-do-items slot="to-do-items" v-for="item in toDoList" v-bind:item="item"></to-do-items>
</to-do>
</div>
<script type="text/javascript">
Vue.component("to-do", {
// template: '<div>' +
// '<slot></slot>' +
// '<ul>' +
// '<slot></slot>' +
// '</ul>' +
// '</div>'
// 使用折行轉義字符,使多行html模板更簡潔
template: '<div>\
<slot name="to-do-title"></slot>\
<ul>\
<slot name="to-do-items"></slot>\
</ul>\
</div>'
});
Vue.component("to-do-title", {
props: ['title'],
template: '<p>{{title}}</p>'
});
Vue.component("to-do-items", {
props: ['item'],
template: '<li>{{item}}</li>'
});
var vm = new Vue({
el: "#app10",
data: {
toDoTitle: "待辦事項",
toDoList: ['起床', '洗漱', '工作']
}
});
</script>
</body>
</html>
Vue 中使用 Element-UI 組件
element-ui 官網鏈接:https://element.eleme.cn/#/zh-CN/component/table
vue2.x 鏈接:https://v2.cn.vuejs.org/v2/guide/installation.html
下面是在 Vue 中使用 Element-UI 表單組件示例:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>vue + element-ui 組件使用示例</title>
<!-- 第一步:引入樣式和組件庫 -->
<!-- 引入element-ui的樣式 -->
<link rel="stylesheet" >
<!-- 引入vue2.0的組件庫,element-ui的組件庫是基于vue的,需要提前引入 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2.7.10"></script>
<!-- 引入element-ui的組件庫 -->
<script src="https://unpkg.com/element-ui/lib/index.js"></script>
</head>
<body>
<div id="container">
<!-- 第二步:在vue容器中復制進指定element-ui組件的模板代碼 -->
<template>
<el-table :data="tableData" border style="width: 100%">
<el-table-column prop="date" label="日期" width="180">
</el-table-column>
<el-table-column prop="name" label="姓名" width="180">
</el-table-column>
<el-table-column prop="address" label="地址">
</el-table-column>
</el-table>
</template>
</div>
<script type="text/javascript">
var vm = new Vue({
el: "#container",
// 第三步:引入示例數據
data: {
tableData: [{
date: '2016-05-02',
name: '王小虎',
address: '上海市普陀區金沙江路 1518 弄'
}, {
date: '2016-05-04',
name: '王小虎',
address: '上海市普陀區金沙江路 1517 弄'
}, {
date: '2016-05-01',
name: '王小虎',
address: '上海市普陀區金沙江路 1519 弄'
}, {
date: '2016-05-03',
name: '王小虎',
address: '上海市普陀區金沙江路 1516 弄'
}]
}
});
</script>
</body>
</html>
自定義事件內容分發
- 通過組件無法直接操作 Vue 對象的數據,可以通過組件調前端,通過前端操作 Vue 對象的數據,實現組件操作 Vue 對象數據。
- 核心:自定義事件
this.$emit('myEvent')
- 例如:在組件中添加一個刪除按鈕,要求點擊刪除,將指定列表數據刪除
示例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>插槽slot之自定義事件分發</title>
<!--引入Vue.js-->
<script src="https://cdn.bootcss.com/vue/2.5.16/vue.min.js"></script>
</head>
<body>
<div id="app10">
<to-do>
<to-do-title slot="to-do-title" v-bind:title="toDoTitle"></to-do-title>
<to-do-items slot="to-do-items"
v-for="(luis, index) in toDoList"
v-bind:item="luis"
v-bind:index="index"
v-on:rm="removeItem(index)"></to-do-items><!--綁定自定義事件-->
</to-do>
</div>
<script type="text/javascript">
Vue.component("to-do", {
// template: '<div>' +
// '<slot></slot>' +
// '<ul>' +
// '<slot></slot>' +
// '</ul>' +
// '</div>'
// 使用折行轉義字符,使多行html模板更簡潔
template: '<div>\
<slot name="to-do-title"></slot>\
<ul>\
<slot name="to-do-items"></slot>\
</ul>\
</div>'
});
Vue.component("to-do-title", {
props: ['title'],
template: '<p>{{title}}</p>'
});
Vue.component("to-do-items", {
props: ['item', 'index'],
// template: '<li>{{item}} <button @click="remove">刪除</button></li>',
template: '<li>{{index}}---{{item}} <button v-on:click="remove">刪除</button></li>',
methods: {
remove: function (index) {
//自定義事件分發
//不能直接通過組件控制Vue對象中的方法;可通過組件調前端,再通過前端來控制Vue對象
this.$emit("rm", index);
}
}
});
var vm = new Vue({
el: "#app10",
data: {
toDoTitle: "待辦事項",
toDoList: ['起床', '洗漱', '工作']
},
methods: {
removeItem: function (index) {
//刪除指定數組下標處指定個數的元素
this.toDoList.splice(index, 1);
}
}
});
</script>
</body>
</html>
Vue 入門小結
核心:數據驅動,組件化
優點:借鑒了 AngularJS 的模塊化開發和 React 的虛擬 Dom;虛擬 Dom 就是把 Dom 的操作放到內存中執行。
常用屬性:
v-if
v-else-if
v-else
v-for
-
v-on
綁定事件,簡寫@
-
v-model
數據雙向綁定 -
v-bind
給組件綁定參數,簡寫:
組件化:
- 組合組件 slot 插槽
- 組件內部綁定事件需要使用到
this.$emit("事件名", 參數);
- 計算屬性的特色,緩存計算數據
遵循 SoC 關注度分離原則,Vue 是純粹的視圖框架,并不包含如 Ajax 之類的通信功能,為了解決通信問題,我們需要使用 Axios 框架做異步通信。
說明:
- 以上屬于 Vue 的基礎語法,包括示例都是為了演示語法的使用,實際開發不會采用此方式!
- Vue 的開發都是要基于 NodeJS,實際開發都是采用的 vue-cli 腳手架,vue-router 實現路由(跳轉),vuex 實現狀態管理(會話管理),Vue UI 界面,一般使用 ElementUI(餓了么出品),或使用 ICE(阿里巴巴出品)來快速搭建前端項目!
Axios 異步通信
vue 可以實現數據的渲染,但是如何獲取數據呢?
vue 本身不具備通信能力,通常結合 axios(一個專注于異步通信的 js 框架)來使用。
- Axios 中文文檔:http://www.axios-js.com/zh-cn/docs/
如果使用 IDEA 寫代碼需要保證設置中 JavaScript 規范為 ECS 6+,如下:
什么是 Axios
- Axios 是一個基于 promise 的 HTTP 庫,可以用在瀏覽器和 node.js 中,其主要作用就是實現 AJAX 異步通信。
為什么使用 Axios
- 由于
Vue.js
是一個視圖層框架,并且其開發者(尤雨溪)嚴格遵守 SOC(關注度分離原則),所以Vue.js
并不包含 AJAX 的通信功能,為了解決通信問題,作者單獨開發了一個名為vue-resource
的插件,不過在進入 2.0 版本以后,其停止了對該插件的維護并推薦了Axios
框架。建議少用 jQuery,因為它操作 DOM 太頻繁。 - 對于異步通信:
- 原生 ajax:實現步驟復雜
- jQuery:笨重
- Axios:簡潔高效,對 RESTful 支持良好
安裝
可使用 npm、bower、cdn 等,此處選擇使用 cdn:
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
使用案例
異步請求
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<!-- vue -->
<script src="https://cdn.jsdelivr.net/npm/vue@2.7.10"></script>
<!-- axios -->
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
</head>
<body>
<div id="container">
<button type="button" @click="test1">測試1</button>
</div>
<script type="text/javascript">
var vm = new Vue({
el: "#container",
methods: {
test1: function() {
//發送異步請求
// axios.get(url).then(fn);
// axios.get(url,{}).then(fn)
axios.get("http://localhost:9999/music/detail", {
params: {
id: "25640392"
}
})
.then(function(res) {
console.log(res);
});
}
}
});
</script>
</body>
</html>
Axios 提供了多種異步請求方法,實現對 RESTful 風格的支持。
get 請求
無參傳遞:
axios.get(url).then(fn);
有參傳遞:
axios.get(url,{}).then(fn)
//使?axios的get請求傳遞參數,需要將參數設置在params下 axios.get("http://localhost:9999/music/detail",{ params:{ id:"25640392" } }) .then(function(res){ console.log(res); });
post 請求
axios.post(url,{}).then(fn)
axios.post("http://localhost:9999/music/search",{s:"阿刁"}) .then(function(res){ console.log(res); });
自定義請求:自定義請求方式、請求參數、請求頭、請求體(post)
axios({ url:"http://localhost:9999/music/search", method:"post", params:{ //設置請求?傳值 s:"成都", limit:15 }, headers:{ //設置請求頭 }, data:{ //設置請求體(post/put) } }).then(function(res){ console.log(res) });
其他
- delete
- put
- option
并發請求
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<!-- vue -->
<script src="https://cdn.jsdelivr.net/npm/vue@2.7.10"></script>
<!-- axios -->
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
</head>
<body>
<div id="container">
<button type="button" @click="test1">測試1</button>
</div>
<script type="text/javascript">
var vm = new Vue({
el: "#container",
methods: {
test1: function() {
//發送異步請求
axios.all([listMusics(), getMusicDetail()]).then(axios.spread(function(r1, r2) {
// 兩個請求現在都執行完成
console.log(r1);
console.log(r2);
}));
}
}
});
function listMusics() {
return axios.get('http://localhost:9999/music/search?s=成都');
}
function getMusicDetail() {
return axios.get('http://localhost:9999/music/detail?id=25640392');
}
</script>
</body>
</html>
箭頭函數
箭頭函數是一種語法,需要明白其使用格式。
先要注意:axios 的回調函數的參數 res,并不是接口返回的數據,而是表示一個響應對象;res.data 才表示接口響應回來的數據。
此知識點學習目標:需要明白這種用法的意義,還有要看得懂!
案例需求
需求:將接口返回的數據設置到 vue 中
方式一
直接通過 vue 對象設置(簡單名了,但用的人少)
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<!-- vue -->
<script src="https://cdn.jsdelivr.net/npm/vue@2.7.10"></script>
<!-- axios -->
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
</head>
<body>
<div id="container">
<button type="button" @click="test1">測試1</button>
</div>
<script type="text/javascript">
var vm = new Vue({
el: "#container",
data: {
song: {}
},
methods: {
test1: function() {
//發送異步請求
axios.get("http://localhost:9999/music/detail", {
params: {
id = 25640392
}
})
.then(function(res) {
// res并不是接口返回的數據,而是表示一個響應對象;res.data才表示接口響應的數據
if (res.data.code == 200) {
// 直接通過vm實例設置
vm.song = res.data.songs[0];
}
});
}
}
});
</script>
</body>
</html>
方式二
通過定義屬性,在指定位置使用(用的多)
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<!-- vue -->
<script src="https://cdn.jsdelivr.net/npm/vue@2.7.10"></script>
<!-- axios -->
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
</head>
<body>
<div id="container">
<button type="button" @click="test1">測試1</button>
</div>
<script type="text/javascript">
var vm = new Vue({
el: "#container",
data: {
song: {}
},
methods: {
test1: function() {
// 定義一個變量,將當前vue實例賦值給它
var _this = this;
//發送異步請求
axios.get("http://localhost:9999/music/detail", {
params: {
id = 25640392
}
})
.then(function(res) {
// res并不是接口返回的數據,而是表示一個響應對象;res.data才表示接口響應的數據
if (res.data.code == 200) {
// 如果這里直接寫this,則代表的是回調函數的對象,不是vm對象!
// this.song = res.data.songs[0];
// 通過外面定義的變量設置數據
_this.song = res.data.songs[0];
}
});
}
}
});
</script>
</body>
</html>
方式三
使用箭頭函數(需要看得懂)
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<!-- vue -->
<script src="https://cdn.jsdelivr.net/npm/vue@2.7.10"></script>
<!-- axios -->
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
</head>
<body>
<div id="container">
<button type="button" @click="test1">測試1</button>
</div>
<script type="text/javascript">
var vm = new Vue({
el: "#container",
data: {
song: {}
},
methods: {
test1: function() {
//發送異步請求
axios.get("http://localhost:9999/music/detail", {
params: {
id = "25640392"
}
})
.then((res) => {
// res并不是接口返回的數據,而是表示一個響應對象;res.data才表示接口響應的數據
if (res.data.code == 200) {
this.song = res.data.songs[0];
}
});
}
}
});
</script>
</body>
</html>
router 路由(新)
router 是由 vue 官方提供的,用于組件跳轉的插件。
1. 路由插件的引用
離線模式示例:(復制并轉到 CDN 中地址,保存就是對應的 js 庫文件)
<script type="text/javascript" src="js/vue.js" ></script>
<script type="text/javascript" src="js/vue-router.js"></script>
在線 CDN:(vue-router 需要依賴 vue 才能使用)【注意:使用高版本可能會報錯】
<script src="https://cdn.staticfile.org/vue/2.4.2/vue.min.js"></script>
<!-- 低版本,也可以使用 -->
<!-- <script src="https://cdn.staticfile.org/vue-router/2.7.0/vue-router.min.js"></script> -->
<script src="https://cdn.jsdelivr.net/npm/vue-router@3.5.1/dist/vue-router.min.js"></script>
2. 路由使用案例
步驟簡述:
- 引入 vue 和 vue-router 的 js 文件
- 定義 vue 實例和對應的基礎 vue 容器標簽
- 在容器中使用路由專用鏈接和路由頁面展示標簽
- 在 js 中定義路由鏈接跳轉的模板
- 在 js 中定義路由跳轉的規則(在創建的 VueRouter 中定義跳轉規則)
- vue 實例中配置路由對象,即引用路由
代碼示例:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>01</title>
<style type="text/css">
body {
padding: 0px;
margin: 0px;
}
ul {
list-style: none;
}
ul li {
display: inline;
float: left;
margin-left: 15px;
margin- bottom: 15px;
}
ul li a {
text-decoration: none;
color: white;
font-size: 18px;
font-weight: bold;
}
ul li a:hover {
color: yellow;
}
</style>
<!-- 引入vue -->
<script src="https://cdn.staticfile.org/vue/2.4.2/vue.min.js"></script>
<!-- 引入vue-router -->
<!-- 低版本,也可以使用 -->
<!-- <script src="https://cdn.staticfile.org/vue-router/2.7.0/vue-router.min.js"></script> -->
<script src="https://cdn.jsdelivr.net/npm/vue-router@3.5.1/dist/vue-router.min.js"></script>
</head>
<body>
<div id="container">
<div style="width: 100%; height: 70px; background: #00BFFF;">
<table>
<tr>
<td>
<p>logo</p>
</td>
<td>
<ul>
<!-- 使用路由專用鏈接 -->
<li>
<router-link to="/a">首頁</router-link>
</li>
<li>
<router-link to="/b">Java</router-link>
</li>
<li>
<router-link to="/c">HTML5</router-link>
</li>
<li>
<router-link to="/d">Python</router-link>
</li>
</ul>
</td>
</tr>
</table>
</div>
<div style="width: 100%; height: 680px; background:lemonchiffon;">
<!-- 在此處展示路由跳轉的頁面 -->
<router-view></router-view>
</div>
</div>
<script type="text/javascript">
// vue的路由旨在為單頁面應用開發提供便捷
//1.定義鏈接跳轉的模板(組件)
//使用const聲明;var和const聲明的區別是const一旦賦值不可改變
const t1 = {
template: `<p>index</p>`
};
const t2 = {
template: `<p>Java</p>`
};
const t3 = {
template: `<p>HTML5</p>`
};
const t4 = {
template: `<p>PYTHON</p>`
};
//2.定義路由規則
const myrouter = new VueRouter({
routes: [{
path: "/a",
component: t1
},
{
path: "/b",
component: t2
},
{
path: "/c",
component: t3
},
{
path: "/d",
component: t4
}
]
});
// 3.vue實例中配置路由對象,即引用路由
var vm = new Vue({
el: "#container",
router: myrouter
});
</script>
</body>
</html>
3. 動態路由匹配
通配符
通過使用通配符
*
實現,*
可以匹配任意路徑。例如:
/user-*
匹配所有以user-
開頭的任意路徑/*
匹配所有路徑注意:如果使用通配符定義路徑,需要注意路由聲明的順序!
const myrouter = new VueRouter({
routes:[
{path:"/user-*",component:xxx},
{path:"/*",component:xxx}
]
});
路由參數
-
/a/:參數名
可以匹配/a/
開頭的路徑 -
{{$route.params.參數名}}
獲取數據
<div id="container">
<li><router-link to="/a/101">??</router-link></li>
<router-view></router-view>
</div>
<script type="text/javascript">
const t1 = {template:`<p>index:{{$route.params.id}}</p>`};
const myrouter = new VueRouter({
routes:[
{path:"/a/:id",component:t1}
]
});
var vm = new Vue({
el:"#container",
router:myrouter
});
</script>
優先級
如果一個路徑匹配了多個路由,則按照路由的配置順序:路由定義的越早,優先級別就越高。
4. 嵌套路由
在一級路由的組件中顯示二級路由
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>嵌套路由</title>
<!-- 引入vue -->
<script src="https://cdn.staticfile.org/vue/2.4.2/vue.min.js"></script>
<!-- 引入vue-router -->
<!-- 低版本,也可以使用 -->
<!-- <script src="https://cdn.staticfile.org/vue-router/2.7.0/vue-router.min.js"></script> -->
<script src="https://cdn.jsdelivr.net/npm/vue-router@3.5.1/dist/vue-router.min.js"></script>
</head>
<body>
<div id="container">
<router-link to="/a">首頁</router-link>
<router-link to="/a/c2">首頁-c2</router-link>
<router-link to="/a/c3">首頁-c3</router-link>
<router-view></router-view>
</div>
<script type="text/javascript">
const t1 = {
template: `<div style="width: 400px; height: 200px; border: skyblue 1px solid;">
index
<hr/>
<router-view></router-view>
</div>`
};
const t2 = {template: '<div>t2</div>'};
const t3 = {template: '<div>t3</div>'};
const myrouter = new VueRouter({
routes: [{
path: "/a",
component: t1,
children: [
{
path:"c2",
component: t2
},
{
path:"c3",
component: t3
}
]
}]
});
var vm = new Vue({
el: "#container",
router: myrouter
});
</script>
</body>
</html>
5. 編程式導航
學習目標:掌握不使用路由標簽鏈接,通過 js 代碼進行路由跳轉的方式。
push()
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>luis</title>
<!-- 引入vue -->
<script src="https://cdn.staticfile.org/vue/2.4.2/vue.min.js"></script>
<!-- 引入vue-router -->
<!-- 低版本,也可以使用 -->
<!-- <script src="https://cdn.staticfile.org/vue-router/2.7.0/vue-router.min.js"></script> -->
<script src="https://cdn.jsdelivr.net/npm/vue-router@3.5.1/dist/vue-router.min.js"></script>
</head>
<body>
<div id="container">
<!-- 舍棄下面通過超鏈接跳轉 -->
<!-- <router-link to="/index">首頁</router-link> -->
<!-- 改用通過按鈕進行跳轉 -->
<button type="button" @click="btnClick">首頁跳轉</button>
<router-view></router-view>
</div>
<script type="text/javascript">
const t1 = {
template: `<div style="width: 400px; height: 200px; border: skyblue 1px solid;">
index
</div>`
};
const myrouter = new VueRouter({
routes: [{
path: "/index",
component: t1
}]
});
var vm = new Vue({
el: "#container",
router: myrouter,
methods:{
btnClick:function() {
//js代碼實現路由跳轉,編程式導航
myrouter.push("/index");
}
}
});
</script>
</body>
</html>
push() 參數
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>luis</title>
<!-- 引入vue -->
<script src="https://cdn.staticfile.org/vue/2.4.2/vue.min.js"></script>
<!-- 引入vue-router -->
<!-- 低版本,也可以使用 -->
<!-- <script src="https://cdn.staticfile.org/vue-router/2.7.0/vue-router.min.js"></script> -->
<script src="https://cdn.jsdelivr.net/npm/vue-router@3.5.1/dist/vue-router.min.js"></script>
</head>
<body>
<div id="container">
<!-- 舍棄下面通過超鏈接跳轉 -->
<!-- <router-link to="/index">首頁</router-link> -->
<!-- 改用通過按鈕進行跳轉 -->
<button type="button" @click="btnClick">首頁跳轉</button>
<router-view></router-view>
</div>
<script type="text/javascript">
const t1 = {
template: `<div style="width: 400px; height: 200px; border: skyblue 1px solid;">
index:{{$route.params.id}}
</div>`
};
const myrouter = new VueRouter({
routes: [{
path: "/index",
name: "r1",
component: t1
}]
});
var vm = new Vue({
el: "#container",
router: myrouter,
methods:{
btnClick:function() {
//js代碼實現路由跳轉,編程式導航
//方式一:字符串
// myrouter.push("/index");
//方式二:對象
// myrouter.push({path:"/index"})
// myrouter.push({path:"/index", params:{id:121}});
//如果要使用組件傳值,可以在定義路由路徑時指定如:path:'index/:id',然后下方傳值
// myrouter.push({path:"/index/111"});
//方式三:命名的路由,需要定義路由名字name
// myrouter.push({name:"r1", params:{id:121}});
//方式四,url傳參,并非組件傳值,相當于/index?id=101
// myrouter.push({path:"/index", query:{id:101}});
}
}
});
</script>
</body>
</html>
replace()
replace() 和 push() 功能一致,只是 replace() 不會向 history 添加新的瀏覽記錄(即頁面沒有前進后退記錄)
go()
用法:
路由對象.go(-1);
參數為?個整數,表示在瀏覽器歷史記錄中前后/后退多少步,相當于
window.history.go(-1)
的作?;參數為負整數,則表示后退多少步;參數為正整數,則表示前進多少步。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>luis</title>
<!-- 引入vue -->
<script src="https://cdn.staticfile.org/vue/2.4.2/vue.min.js"></script>
<!-- 引入vue-router -->
<!-- 低版本,也可以使用 -->
<!-- <script src="https://cdn.staticfile.org/vue-router/2.7.0/vue-router.min.js"></script> -->
<script src="https://cdn.jsdelivr.net/npm/vue-router@3.5.1/dist/vue-router.min.js"></script>
</head>
<body>
<div id="container">
<!-- 舍棄下面通過超鏈接跳轉 -->
<!-- <router-link to="/index">首頁</router-link> -->
<!-- 改用通過按鈕進行跳轉 -->
<button type="button" @click="btnClick">首頁跳轉</button>
<button type="button" @click="back">后退</button>
<router-view></router-view>
</div>
<script type="text/javascript">
const t1 = {
template: `<div style="width: 400px; height: 200px; border: skyblue 1px solid;">
index:{{$route.params.id}}
</div>`
};
const myrouter = new VueRouter({
routes: [{
path: "/index",
name: "r1",
component: t1
}]
});
var vm = new Vue({
el: "#container",
router: myrouter,
methods:{
btnClick:function() {
//js代碼實現路由跳轉,編程式導航
myrouter.push("/index");
},
back:function() {
myrouter.go(-1);
}
}
});
</script>
</body>
</html>
6. 命名路由
命名路由:在定義路由的時候可以給路由指定 name,我們在進?路由導航時可以通過路由的名字導航
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>luis</title>
<!-- 引入vue -->
<script src="https://cdn.staticfile.org/vue/2.4.2/vue.min.js"></script>
<!-- 引入vue-router -->
<!-- 低版本,也可以使用 -->
<!-- <script src="https://cdn.staticfile.org/vue-router/2.7.0/vue-router.min.js"></script> -->
<script src="https://cdn.jsdelivr.net/npm/vue-router@3.5.1/dist/vue-router.min.js"></script>
</head>
<body>
<div id="container">
<!-- 使用路由的name進行鏈接跳轉,注意to屬性需要進行綁定,需要加冒號 -->
<router-link :to="{name:'r1'}">name鏈接跳轉</router-link>
<!-- js代碼進行路由跳轉 -->
<button type="button" @click="btnClick">按鈕跳轉</button>
<router-view></router-view>
</div>
<script type="text/javascript">
const t1 = {
template: `<div style="width: 400px; height: 200px; border: skyblue 1px solid;">
index:t1 skyblue
</div>`
};
const t2 = {
template: `<div style="width: 400px; height: 200px; border: red 1px solid;">
index:t2 red
</div>`
};
const myrouter = new VueRouter({
routes: [
{
path: "/a",
name: "r1",
component: t1
},
{
path: "/b",
name: "r2",
component: t2
}
]
});
var vm = new Vue({
el: "#container",
router: myrouter,
methods:{
btnClick:function() {
//js代碼實現路由跳轉,編程式導航
myrouter.push({name:"r2"});
}
}
});
</script>
</body>
</html>
7. 命名路由視圖
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>luis</title>
<!-- 引入vue -->
<script src="https://cdn.staticfile.org/vue/2.4.2/vue.min.js"></script>
<!-- 引入vue-router -->
<!-- 低版本,也可以使用 -->
<!-- <script src="https://cdn.staticfile.org/vue-router/2.7.0/vue-router.min.js"></script> -->
<script src="https://cdn.jsdelivr.net/npm/vue-router@3.5.1/dist/vue-router.min.js"></script>
</head>
<body>
<div id="container">
<!-- 多個模板放在多個視圖中展示 -->
<router-link to="/a">a鏈接跳轉</router-link>
<router-link to="/b">b鏈接跳轉</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>
<script type="text/javascript">
const t11 = {
template: `<div style="width: 400px; height: 200px; border: skyblue 1px solid;">
index:t11 skyblue
</div>`
};
const t12 = {
template: `<div style="width: 400px; height: 200px; border: yellow 1px solid;">
index:t12 yellow
</div>`
};
const t21 = {
template: `<div style="width: 400px; height: 200px; border: skyblue 1px solid;">
index:t21 skyblue
</div>`
};
const t22 = {
template: `<div style="width: 400px; height: 200px; border: yellow 1px solid;">
index:t22 yellow
</div>`
};
const myrouter = new VueRouter({
routes: [
{
path: "/a",
name: "r1",
components: {
v1: t11,
v2: t12
}
},
{
path: "/b",
name: "r2",
components: {
v1: t21,
v2: t22
}
}
]
});
var vm = new Vue({
el: "#container",
router: myrouter
});
</script>
</body>
</html>
8. 重定向和別名
重定向
訪問 /b
,重定向到 /a
- 根據路徑重定向
- 根據路由命名重定向
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>luis</title>
<!-- 引入vue -->
<script src="https://cdn.staticfile.org/vue/2.4.2/vue.min.js"></script>
<!-- 引入vue-router -->
<!-- 低版本,也可以使用 -->
<!-- <script src="https://cdn.staticfile.org/vue-router/2.7.0/vue-router.min.js"></script> -->
<script src="https://cdn.jsdelivr.net/npm/vue-router@3.5.1/dist/vue-router.min.js"></script>
</head>
<body>
<div id="container">
<router-link to="/a">路徑a</router-link>
<router-link to="/b">路徑b</router-link>
<router-view ></router-view>
</div>
<script type="text/javascript">
const t1 = {
template: `<div style="width: 400px; height: 200px; border: skyblue 1px solid;">
index:t11 skyblue
</div>`
};
const myrouter = new VueRouter({
routes: [
{
path: "/a",
name: "r1",
component: t1
},
{
path: "/b",
//根據路徑重定向
// redirect: "/a"
//根據路由命名重定向
redirect: {name: "r1"}
}
]
});
var vm = new Vue({
el: "#container",
router: myrouter
});
</script>
</body>
</html>
路由別名
給路由路徑起別名,可以通過別名訪問,隱藏真實路徑。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>luis</title>
<!-- 引入vue -->
<script src="https://cdn.staticfile.org/vue/2.4.2/vue.min.js"></script>
<!-- 引入vue-router -->
<!-- 低版本,也可以使用 -->
<!-- <script src="https://cdn.staticfile.org/vue-router/2.7.0/vue-router.min.js"></script> -->
<script src="https://cdn.jsdelivr.net/npm/vue-router@3.5.1/dist/vue-router.min.js"></script>
</head>
<body>
<div id="container">
<router-link to="/a">路徑a</router-link>
<router-link to="/haha">路徑a的別名haha</router-link>
<router-link to="/b">路徑b</router-link>
<router-view ></router-view>
</div>
<script type="text/javascript">
const t1 = {
template: `<div style="width: 400px; height: 200px; border: skyblue 1px solid;">
index:t11 skyblue
</div>`
};
const myrouter = new VueRouter({
routes: [
{
path: "/a",
alias: "/haha", //起別名
name: "r1",
component: t1
},
{
path: "/b",
//根據路徑重定向
// redirect: "/a"
//根據路由命名重定向
redirect: {name: "r1"}
}
]
});
var vm = new Vue({
el: "#container",
router: myrouter
});
</script>
</body>
</html>
9. 路由組件傳參
方式一:可以通過 /url/:attr
?式實現通過路由傳值給組件(耦合度較高)
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>luis</title>
<!-- 引入vue -->
<script src="https://cdn.staticfile.org/vue/2.4.2/vue.min.js"></script>
<!-- 引入vue-router -->
<!-- 低版本,也可以使用 -->
<!-- <script src="https://cdn.staticfile.org/vue-router/2.7.0/vue-router.min.js"></script> -->
<script src="https://cdn.jsdelivr.net/npm/vue-router@3.5.1/dist/vue-router.min.js"></script>
</head>
<body>
<div id="container">
<router-link to="/a/111">路徑a</router-link>
<router-view ></router-view>
</div>
<script type="text/javascript">
const t1 = {
template: `<div style="width: 400px; height: 200px; border: skyblue 1px solid;">
參數:{{$route.params.id}}
</div>`
};
const myrouter = new VueRouter({
routes: [
{
path: "/a/:id",
component: t1
}
]
});
var vm = new Vue({
el: "#container",
router: myrouter
});
</script>
</body>
</html>
方式二:通過 props
傳參(常用,解耦)
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>luis</title>
<!-- 引入vue -->
<script src="https://cdn.staticfile.org/vue/2.4.2/vue.min.js"></script>
<!-- 引入vue-router -->
<!-- 低版本,也可以使用 -->
<!-- <script src="https://cdn.staticfile.org/vue-router/2.7.0/vue-router.min.js"></script> -->
<script src="https://cdn.jsdelivr.net/npm/vue-router@3.5.1/dist/vue-router.min.js"></script>
</head>
<body>
<div id="container">
<router-link to="/a/333">路徑a</router-link>
<router-view ></router-view>
</div>
<script type="text/javascript">
const t1 = {
props: ["id"], //設置屬性
template: `<div style="width: 400px; height: 200px; border: skyblue 1px solid;">
參數:{{id}}
</div>`
};
const myrouter = new VueRouter({
routes: [
{
path: "/a/:id",
props: true, //開啟屬性
component: t1
}
]
});
var vm = new Vue({
el: "#container",
router: myrouter
});
</script>
</body>
</html>
PS:以上是路由一些基礎的使用,其他內容或詳細的使用參考官方文檔。
第一個 vue-cli 程序
什么是 vue-cli
- vue-cli 是官方提供的一個腳手架,用于快速生成一個 vue 的項目模板
- 預先定義好的目錄結構以及基礎代碼,就好比咱們在創建 Maven 項目時可以選擇創建一個骨架項目,這個骨架項目就是腳手架,使我們的開發更加的便捷。
主要的功能:
- 統一的目錄結構
- 本地調試
- 熱部署
- 單元測試
- 集成打包上線
需要的環境
1、安裝 Node.js
確認 Node.js 安裝成功:
-
cmd 下 輸入
node -v
,查看版本號打印信息 -
cmd 下 輸入
npm -v
,查看版本號打印信息npm:軟件包管理工具,類似 Linux 中 apt 軟件安裝。
2、安裝 cnpm
安裝 Node.js 淘寶鏡像加速器(cnpm),解決 npm 速度慢的問題:
# -g 就是全局安裝(推薦)
npm install cnpm -g
注意:建議優先使用 npm 下載,若 npm 下載緩慢,再考慮 使用 cnpm?。ㄍㄟ^淘寶下載的偶爾可能出現問題)
查看安裝情況:查看路徑C:\Users\linwe\AppData\Roaming\npm\node_modules
3、安裝 vue-cli
# 使用 cnpm 選擇全局安裝的方式安裝 vue-cli
cnpm install vue-cli -g
# 測試是否安裝成功
# 查看可以基于哪些模板創建 vue 程序,通常使用 webpack
vue list
查看安裝情況:查看路徑C:\Users\linwe\AppData\Roaming\npm\node_modules
第一個 vue-cli 程序創建
-
電腦上手動創建一個空目錄,如
D:\1a-Projects\vue-projects
-
在該目錄下,使用 cmd 命令,進入 DOS 窗口,初始化項目:
vue init webpack myvue
依據以下模板,進行項目的創建:(一路都選擇 no 即可)
D:\1a-Projects\vue-projects>vue init webpack myvue # 項目名,默認,回車,即可 ? Project name myvue # 項目描述,默認,回車,即可 ? Project description A Vue.js project # 項目作者,默認,回車,即可 ? Author luis # 選擇第一種 build 方式 ? Vue build standalone # 不安裝 vue-router,選擇 n,后續需要再手動添加 ? Install vue-router? No # 是否使用 ESLint 做代碼檢查,選擇 n,后續需要再手動添加 ? Use ESLint to lint your code? No # 單元測試相關,選擇 n,后續需要再手動添加 ? Set up unit tests No # 單元測試相關,選擇 n,后續需要再手動添加 ? Setup e2e tests with Nightwatch? No # 是否創建完成后直接初始化,選擇 n,我們手動執行,運行結果! ? Should we run `npm install` for you after the project has been created? (recommended) no vue-cli · Generated "myvue". # Project initialization finished! # ======================== To get started: cd myvue npm install (or if using yarn: yarn) npm run dev Documentation can be found at https://vuejs-templates.github.io/webpack
-
初始化并運行(可使用IDEA打開該項目,查看相關目錄結構)
cd myvue # 進入myvue目錄 npm install # 安裝依賴環境 npm run dev # 運行項目(運行成功后,可在瀏覽器輸入地址訪問)
PS:可使用 Ctrl + C 終止項目
webpack 學習使用
webpack 簡介
- webpack 主要作用是打包,其核心存在兩個部分,入口和出口,可以把 webpack 想象成香腸加工廠,就是活豬進去,香腸出來的那種,但是如果每次加工都需要員工親力親為,那多麻煩,所以我們考慮到了自動化配置。webpack 存在功能類似的配置文件,讓 webpack 通過配置,全自動的執行我們需要的編譯操作。
- webpack 分成四個部分,其中最核心的就是入口和出口,當然在入口和出口配置的同時我們還需要一些加載器和插件,這就是我們所謂的 webpack 配置文件,這個配置文件我們習慣把其命名為 webpack.config.js,還有 webpackfile.js。
- webpack 是一種模塊化的解決方案,其工作方式是:把你的項目當做一個整體,通過一個給定的主文件(如:index.js),webpack 將從這個文件開始找到你的項目的所有依賴文件,使用 loaders 處理它們,最后打包為一個(或多個)瀏覽器可識別的 JavaScript 文件。
- webpack 使用 ES6 模塊語法
總結一下,webpack 共分為四個部分:入口、出口、加載器、插件。
什么是 webpack
- webpack 可以看做是模塊打包機:分析你的項目結構,找到 JavaScript 模塊以及其它的一些瀏覽器不能直接運行的拓展語言(如 Scss,TypeScript 等),并將其轉換和打包為合適的格式供瀏覽器使用。
webpack 能干什么
- 根據入口文件的依賴,加載所有模塊 js,然后合并成一個 js
- 標準且純粹的模塊化打包工具
- 依賴一個文件入口,打包所有依賴為當前瀏覽器可用的代碼
安裝
npm install webpack -g # 安裝打包工具
npm install webpack-cli -g # 安裝客戶端
webpack -v # 查看安裝的版本(是否安裝成功)
相關配置參數(了解)
創建webpack.config.js
配置文件
- entry:入口文件,指定 webpack 用哪個文件作為項目的入口
- output:輸出,指定 webpack 把處理完成的文件放置到指定路徑
- module:模塊,用于處理各種類型的文件
- plugins:插件,如:熱更新、代碼復用等
- resolve:設置路徑指向
- watch:監聽,用于設置文件改動后直接打包
使用 webpack
目錄結構預覽:
-
在
D:\1a-Projects\vue-projects
下創建名為webpack-study
的空目錄(自定義),作為示例項目,使用 IDEA 打開 -
在項目目錄下,創建 modules 目錄,用于存放 JS 模塊等資源文件
-
在 modules 目錄下,創建模塊文件,如 hello.js,編寫 JS 模塊相關代碼,如:
hello.js
// 暴露一個方法 sayHi1 exports.sayHi1 = function () { document.write("<h1>luis1 learns ES6</h1>") }; // 暴露一個方法 sayHi2 exports.sayHi2 = function () { document.write("<h2>luis2 learns ES6</h2>") }; // 暴露一個方法 sayHi3 exports.sayHi3 = function () { document.write("<h3>luis3 learns ES6</h3>") };
-
在 modules 目錄下,創建一個名為 main.js 的入口文件,用于打包時設置 entry 屬性,如:
main.js
// require 導入一個模塊,就可以調用這個模塊中的方法了 var hello = require("./hello"); hello.sayHi1(); hello.sayHi2(); hello.sayHi3();
-
在項目目錄下,創建 webpack.config.js 配置文件,用于配置相關參數
webpack.config.js
module.exports = { entry: './modules/main.js', output: { filename: "./js.bundle.js" } }
-
在項目目錄下,地址欄輸入 cmd 進入 DOS 窗口,輸入
webpack
命令進行打包;打包完成后,在指定的輸出路徑下就可看到打包壓縮后的 js,后面如需使用,則直接引入該 js 即可,不用再使用打包前的那些 js。
D:\1a-Projects\vue-projects\webpack-study>webpack
-
引入打包壓縮后的 js:在項目目錄下,創建 index.html,在其中直接引入打包壓縮后的 js,瀏覽器打開即可
index.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <!--前端的模塊化開發--> <script src="dist/js.bundle.js"></script> </body> </html>
總結:
- vue.js 是一個前端 js 框架,是一套構建用戶界面的漸進式框架
- 前端的模塊化開發:將 js 寫好,使用 webpack 打包后,直接在前端引入即可
vue-router 路由(舊)
Tips:學習的時候,盡量打開官方文檔。
認識 vue-router
目前前端流行的三大框架,都有自己的路由實現:
- Angular 的 ngRouter
- React 的 ReactRouter
- Vue 的 vue-router
vue-router 是 Vue.js 官方的路由插件,它和 vue.js 是深度集成的,適合用于構建單頁面應用??稍L問其官方網站對其進行學習:https://router.vuejs.org/zh/
vue-router 是基于路由和組件的
- 路由用戶設定訪問路徑,將路徑和組件映射起來。
- 在 vue-router 的單頁面應用中,頁面路徑的改變就是組件的切換。
SPA(single page application):單一頁面應用程序,只有一個完整的頁面;它在加載頁面時,不會加載整個頁面,而是只更新某個指定的容器中內容。單頁面應用(SPA)的核心之一是:更新視圖而不重新請求頁面;vue-router 在實現單頁面前端路由時,提供了兩種方式:Hash 模式和 History 模式。
功能
vue-router 是 Vue.js 官方的路由管理器,它和 Vue.js 的核心深度集成,讓構建單頁面應用變得易如反掌,包含的功能有:
- 嵌套的路由/視圖表
- 模塊化的、基于組件的路由配置
- 路由參數、查詢、通配符
- 基于 Vue.js 過渡系統的視圖過渡效果
- 細粒度的導航控制
- 帶有自動激活的 CSS class 的鏈接
- HTML5 歷史模式或 hash 模式,在 IE9 中自動降級
- 自定義的滾動條行為
安裝
基于第一個 vue-cli 程序進行測試學習,先查看 node_modules 中是否存在 vue-router(之前創建第一個 vue-cli 程序時可選擇是否安裝 rue-router)
vue-router 是一個插件包,所以我們還是需要用 npm/cnpm 進行安裝!
在第一個 vue-cli 項目目錄地址欄輸入 cmd 命令,進入 DOS 窗口,輸入以下命令,進行安裝:
# 方式一:建議使用?。ㄊ褂?cnpm 方式,安裝低版本的 vue-router;經測試,高版本的使用有問題?。?cnpm install vue-router@3.1.3 --save-dev
# 方式二
npm install vue-router --save-dev
# 方式三:若以上方式安裝都有問題,就使用此種 cnpm 安裝
cnpm install vue-router --save-dev
安裝完成后,在 node_modules 目錄中就會出現 vue-router 的 js 庫,需要使用的地方,導入即可使用!
使用 vue-router
PS:刪除無用東西,如初始的 HelloWorld 組件相關
最終目錄結構預覽:(基于之前創建的第一個 vue-cli 程序)
-
components 目錄下新建兩個自定義的組件,用于路由組件跳轉測試;
Main.vue
<template> <h2>首頁</h2> </template> <script> export default { name: "Main" } </script> <style scoped> </style>
Content.vue
<template> <h1>內容頁</h1> </template> <script> export default { name: "Content" } </script> <style scoped> </style>
-
在 src 目錄下,新建 router 目錄,專門存放路由;在 router 目錄下,新建 index.js,用來導入、安裝并配置路由;
index.js
import Vue from "vue"; import VueRouter from "vue-router"; import Content from "../components/Content"; import Main from "../components/Main"; //安裝路由 Vue.use(VueRouter); //配置路由 export default new VueRouter({ routes: [ { //路由路徑 相當于@RequestMapping path: '/content', name: 'content', //跳轉的組件 component: Content }, { //路由路徑 path: '/main', name: 'main', //跳轉的組件 component: Main } ] });
-
在 main.js 中配置路由
main.js
import Vue from 'vue' import App from './App' //導入之前創建的路由配置目錄 import router from './router' Vue.config.productionTip = false /* eslint-disable no-new */ new Vue({ el: '#app', //配置路由 router, components: { App }, template: '<App/>' })
-
在 App.vue 中使用路由
App.vue
<template> <div id="app"> <h2>路由跳轉測試</h2> <h2>Vue-Router</h2> <router-link to="/main">首頁</router-link> <router-link to="/content">內容頁</router-link> <!--用來展示路由跳轉的頁面--> <router-view></router-view> </div> </template> <script> export default { name: 'App' } </script> <style> #app { font-family: 'Avenir', Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-align: center; color: #2c3e50; margin-top: 60px; } </style>
-
在項目目錄,在其地址欄輸入 cmd 命令,進入 dos 窗口(或直接在 IDEA 終端中)運行項目:
npm run dev
-
瀏覽器輸入相關地址,進行訪問測試
Tips:后續需要添加組件跳轉,只需要以下三步即可!
- 在 components 目錄下創建自定義組件
- 在 router 目錄的 index.js 中配置路由
- 在 App.vue 中使用路由
Vue+ ElementUI
說明:結合之前所學 + 使用 ElementUI 組件庫,進行實戰訓練
Element UI官網:https://element.eleme.cn/#/zh-CN/component/installation
準備
-
創建一個目錄如
vue-projects
,用來存放后續創建的 vue 工程,如D:\1a-Projects\vue-projects
-
以管理員權限打開命令行,并切換到該
vue-projects
目錄下操作:點擊搜索框,輸入 cmd,右擊以管理員方式運行命令提示符;先切換到 d 盤
d:
,再使用 cd 命令切換到指定目錄即可!
步驟
-
在
vue-projects
目錄下創建名為 hi-vue 的工程:D:\1a-Projects\vue-projects>vue init webpack hi-vue
安裝過程:項目名、描述、作者默認即可;編譯環境選第一個;后續一路 no;npm install 選第三個,手動安裝!
以上,項目初始化完成!
-
進入到 hi-vue 項目目錄下,安裝依賴和插件:
Tips:如果使用國外 npm 方式下載有問題,可嘗試換國內淘寶 cnpm 方式下載!
Tips:如果安裝過程中無 ERR(即錯誤),則可視為正常,繼續后續操作即可!
Tips:如果最后啟動失敗,找不出原因,可重新新建工程、初始化項目、重新安裝!
# 進入工程目錄 cd hi-vue # 安裝 vue-router # 優選方案(使用 cnpm 方式,安裝低版本的 vue-router;經測試,高版本的使用有問題?。?cnpm install vue-router@3.1.3 --save-dev # 備選方案 # cnpm install vue-router --save-dev # 安裝 element-ui(官網推薦使用npm方式安裝)(如果安裝有問題,就換 cnpm 方式安裝!) npm i element-ui -S # 安裝依賴 npm install # 安裝 SASS 加載器 cnpm install sass-loader node-sass --save-dev # 啟動測試 npm run dev
Npm 命令解釋
npm install moduleName
:安裝模塊到項目目錄下npm install -g moduleName
:-g
的意思是將模塊安裝到全局,具體安裝到磁盤哪個位置,要看 npm config prefix 的位置npm install --save moduleName
:--save
的意思是將模塊安裝到項目目錄下,并在 package 文件的 dependencies 節點寫入依賴,-S
為該命令的縮寫npm install --save-dev moduleName
:--save-dev
的意思是將模塊安裝到項目目錄下,并在 package 文件的 devDependencies 節點寫入依賴,-D
為該命令的縮寫
-
啟動成功并在瀏覽器成功訪問后;IDEA 打開項目,刪除 assets 中圖片,刪除 components 中 HelloWorld.vue 組件,刪除 App.vue 中無用的圖片引入和 HelloWorld 組件相關內容;至此,基礎工程有了!
-
在 src 目錄下,新建 router 目錄,存放路由相關;新建 views 目錄,存放視圖相關(組件);
目錄說明:components(放功能性相關組件)、router(放路由相關組件)、views(放視圖相關組件)
-
views 下新建
Main.vue
(首頁)和Login.vue
(登陸頁)作為視圖展示頁Main.vue
<template> <h1>首頁</h1> </template> <script> export default { name: "Main" } </script> <style scoped> </style>
Login.vue
(此登陸模板直接從 ElementUI 官網表單組件庫中復制即可)<template> <div> <el-form ref="loginForm" :model="form" :rules="rules" label-width="80px" class="login-box"> <h3 class="login-title">歡迎登錄</h3> <el-form-item label="賬號" prop="username"> <el-input type="text" placeholder="請輸入賬號" v-model="form.username"/> </el-form-item> <el-form-item label="密碼" prop="password"> <el-input type="password" placeholder="請輸入密碼" v-model="form.password"/> </el-form-item> <el-form-item> <el-button type="primary" v-on:click="onSubmit( 'loginForm' )">登錄</el-button> </el-form-item> </el-form> <el-dialog title="溫馨提示" :visible.sync="dialogVisible" width="30%" :before-close="handLeClose"> <span>請輸入賬號和密碼</span> <span slot="footer" class="dialog- footer"> <el-button type="primary" @click="dialogVisible = false">確定</el-button> </span> </el-dialog> </div> </template> <script> export default { name: "Login", data() { return { form: { username: '', password: '' }, //表單驗證,需要在el-form-item 元素中增加prop 屬性 rules: { username: [ {required: true, message: " 賬號不可為空", trigger: 'blur'} ], password: [ {required: true, message: " 密碼不可為空 ", trigger: 'blur'} ] }, //對話框顯示和隱藏 dialogVisible: false } }, methods: { onSubmit(formName) { //為表單綁定驗證功能 this.$refs[formName].validate((valid) => { if (valid) { //使用vue-router路由到指定頁面,該方式稱之為編程式導航 this.$router.push("/main"); } else { this.dialogVisible = true; return false; } }); } } } </script> <style lang="scss" scoped> .login-box { border: 1px solid #DCDFE6; width: 350px; margin: 180px auto; padding: 35px 35px 15px 35px; border-radius: 5px; -webkit-border-radius: 5px; -moz-border-radius: 5px; box-shadow: 0 0 25px #909399; } .login-title { text-align: center; margin: 0 auto 40px auto; color: #303133; } </style>
-
router 目錄下新建
index.js
,在其中配置路由index.js
import Vue from 'vue' import VueRouter from 'vue-router' import Main from "../views/Main"; import Login from "../views/Login"; //安裝路由 Vue.use(VueRouter); //配置路由 export default new VueRouter({ routes: [ { path: '/main', component: Main }, { path: '/login', component: Login } ] });
-
main.js 中引入 ElementUI 和 router
import Vue from 'vue' import App from './App' import router from './router' import ElementUI from 'element-ui'; import 'element-ui/lib/theme-chalk/index.css'; Vue.config.productionTip = false Vue.use(router); Vue.use(ElementUI); new Vue({ el: '#app', router, render: h => h(App) // components: { App }, // template: '<App/>' })
-
App.vue
中展示使用App.vue
<template> <div id="app"> <router-link to="/main">首頁</router-link> <router-link to="/login">登陸</router-link> <router-view></router-view> </div> </template> <script> export default { name: 'App' } </script>
-
終端輸入
npm run dev
運行,瀏覽器訪問測試http://localhost:8080
http://localhost:8080/#/main
http://localhost:8080/#/login
可能遇到的問題
-
安裝的
sass-loader
版本太高?解決:package.json 中將 sass-loader 版本改到指定低版本如 4.0.0;終端執行
npm install
,不行就cnpm install
,重新npm run dev
啟動即可。 -
vue-router 版本太高,導致路由聲明無效,找不到?
解決:安裝低版本的 vue-router,執行
cnpm install vue-router@3.1.3 --save-dev
,重新npm run dev
啟動即可。
小結
vue + element-ui 使用要點:
- main.js 中引入 Element
- views 或 components 中創建組件文件,在合適的位置復制進需使用的組件代碼
- 在如
App.vue
中使用
路由嵌套
- 路由嵌套又稱子路由,在實際應用中,通常由多層嵌套的組件組合而成。同樣地,URL 中各段動態路徑也按某種結構對應嵌套的各層組件,如
/user/foo/profile
和/user/foo/posts
。
基于前面 hi-vue 繼續舉例學習:
-
在 views 目錄下新建 user 目錄,在 user 目錄下創建
List.vue
和Profile.vue
作為用戶列表和個人信息展示List.vue
<template> <h2>用戶列表</h2> </template> <script> export default { name: "UserList" } </script> <style scoped> </style>
Profile.vue
<template> <h2>個人信息</h2> </template> <script> export default { name: "UserProfile" } </script> <style scoped> </style>
-
在 router 目錄的 index.js 中導入新組件,在 Main 中嵌套子路由
index.js
import Vue from 'vue' import VueRouter from 'vue-router' import Main from "../views/Main"; import Login from "../views/Login"; import UserProfile from "../views/user/Profile"; import UserList from "../views/user/List"; import CheckPwd from "../views/CheckPwd"; import Button from "../views/Button"; //安裝路由 Vue.use(VueRouter); //配置路由 export default new VueRouter({ routes: [ { path: '/main', component: Main, children: [ //路由嵌套(嵌套子路由) { path: '/user/profile', component: UserProfile }, { path: '/user/list', component: UserList } ] }, { path: '/login', component: Login } ] });
-
在 Main.vue 中添加側邊欄組件,實現路由嵌套(在 main 路由中嵌套子路由)的效果(側邊欄代碼來自 ElementUI)
Main.vue
<template> <div> <el-container> <!--側邊欄--> <el-aside width="200px"> <el-menu :default-openeds="['1']"> <el-submenu index="1"> <template slot="title"><i class="el-icon-caret-right"></i>用戶管理</template> <el-menu-item-group> <el-menu-item index="1-1"> <!--路由跳轉--> <router-link to="/user/profile">個人信息</router-link> </el-menu-item> <el-menu-item index="1-2"> <!--路由跳轉--> <router-link to="/user/list">用戶列表</router-link> </el-menu-item> </el-menu-item-group> </el-submenu> <el-submenu index="2"> <template slot="title"><i class="el-icon-caret-right"></i>內容管理</template> <el-menu-item-group> <el-menu-item index="2-1">分類管理</el-menu-item> <el-menu-item index="2-2">內容列表</el-menu-item> </el-menu-item-group> </el-submenu> </el-menu> </el-aside> <!--頂欄--> <el-container> <el-header style="text-align: right; font-size: 12px"> <el-dropdown> <i class="el-icon-setting" style="margin-right:15px"></i> <el-dropdown-menu slot="dropdown"> <el-dropdown-item>個人信息</el-dropdown-item> <el-dropdown-item>退出登錄</el-dropdown-item> </el-dropdown-menu> </el-dropdown> </el-header> <!--主顯示頁--> <el-main> <!--這里展示路由跳轉的組件樣式--> <router-view/> </el-main> </el-container> </el-container> </div> </template> <script> export default { name: "Main" } </script> <style scoped> .el-header { background-color: #048bd1; color: #333; line-height: 60px; } .el-aside { color: #333; } </style>
-
終端輸入
npm run dev
啟動項目,并在瀏覽器訪問http://localhost:8080/#/main
測試
參數傳遞以及重定向
參數傳遞
例子1:(整頁代碼示例)
-
在路由跳轉時,不僅僅需要路徑,還需要定義參數;
在 Main.vue 中,修改需傳參的路由跳轉方式:使用 v-bind,以對象形式進行傳參,顯示聲明 name 和 params 屬性
Main.vue
<template> <div> <el-container> <!--側邊欄--> <el-aside width="200px"> <el-menu :default-openeds="['1']"> <el-submenu index="1"> <template slot="title"><i class="el-icon-caret-right"></i>用戶管理</template> <el-menu-item-group> <el-menu-item index="1-1"> <!--路由跳轉--> <!--<router-link to="/user/profile">個人信息</router-link>--> <!--前端傳參,需要對象,使用v-bind,name和路由配置中name一致 (v-bind:xx 可簡寫為 :xx)--> <router-link v-bind:to="{name: 'UserProfile', params: {id: 1}}">個人信息</router-link> </el-menu-item> <el-menu-item index="1-2"> <!--路由跳轉--> <router-link to="/user/list">用戶列表</router-link> </el-menu-item> <el-menu-item index="1-3"> <!--路由跳轉(重定向)--> <router-link to="/goHome">回到首頁</router-link> </el-menu-item> </el-menu-item-group> </el-submenu> <el-submenu index="2"> <template slot="title"><i class="el-icon-caret-right"></i>內容管理</template> <el-menu-item-group> <el-menu-item index="2-1">分類管理</el-menu-item> <el-menu-item index="2-2">內容列表</el-menu-item> </el-menu-item-group> </el-submenu> </el-menu> </el-aside> <!--頂欄--> <el-container> <el-header style="text-align: right; font-size: 12px"> <el-dropdown> <i class="el-icon-setting" style="margin-right:15px"></i> <el-dropdown-menu slot="dropdown"> <el-dropdown-item>個人信息</el-dropdown-item> <el-dropdown-item>退出登錄</el-dropdown-item> </el-dropdown-menu> </el-dropdown> </el-header> <!--主顯示頁--> <el-main> <!--這里展示路由跳轉的組件樣式--> <router-view/> </el-main> </el-container> </el-container> </div> </template> <script> export default { name: "Main" } </script> <style scoped> .el-header { background-color: #048bd1; color: #333; line-height: 60px; } .el-aside { color: #333; } </style>
-
在 router 的 index.js 中,修改需接參路由的路徑格式 path,并定義 name 和 props 屬性
index.js
import Vue from 'vue' import VueRouter from 'vue-router' import Main from "../views/Main"; import Login from "../views/Login"; import UserProfile from "../views/user/Profile"; import UserList from "../views/user/List"; import CheckPwd from "../views/CheckPwd"; import Button from "../views/Button"; //安裝路由 Vue.use(VueRouter); //配置路由 export default new VueRouter({ routes: [ { path: '/main', component: Main, children: [ //路由嵌套(嵌套子路由) { // path: '/user/profile', path: '/user/profile/:id', //接參 name: 'UserProfile', //可定義name屬性 component: UserProfile, props: true //通過聲明props解耦,在任何地方都可使用該組件 }, { path: '/user/list', component: UserList } ] }, { path: '/login', component: Login }, { path: '/goHome', redirect: '/main' //實現重定向 } ] });
-
取參展示:在
Profile.vue
中獲取傳遞的參數,并進行展示下面列舉兩種方式:{{$route.params.id}} 方式獲??;{{id}} 方式是在
index.js
和Profile.vue
均聲明 props 后可用!Profile.vue
<template> <!-- 所有元素,不能直接暴露在根節點下?。?! --> <div> <h2>個人信息</h2> {{$route.params.id}} <br/><br/> {{id}} </div> </template> <script> export default { props: ['id'], //可通過組件取參,在上面就可以直接用了 name: "UserProfile" } </script> <style scoped> </style>
-
終端輸入
npm run dev
啟動項目,并在瀏覽器訪問http://localhost:8080/#/main
測試
例子2:(局部代碼示例)
-
前端頁面跳轉時傳遞用戶填寫的參數(如下的用戶填寫的姓名參數)
Login.vue
<script> export default { name: "Login", data() { return { form: { username: '', password: '' }, //表單驗證,需要在el-form-item 元素中增加prop 屬性 rules: { username: [ {required: true, message: " 賬號不可為空", trigger: 'blur'} ], password: [ {required: true, message: " 密碼不可為空 ", trigger: 'blur'} ] }, //對話框顯示和隱藏 dialogVisible: false } }, methods: { onSubmit(formName) { //為表單綁定驗證功能 this.$refs[formName].validate((valid) => { if (valid) { //使用vue-router路由到指定頁面,該方式稱之為編程式導航 //跳轉并且傳遞參數(將用戶填的姓名傳遞過去) this.$router.push("/main/" + this.form.username); } else { this.dialogVisible = true; return false; } }); } } } </script>
-
路由配置中,配置接參路徑,以及 props 屬性的聲明
index.js
//配置路由 export default new VueRouter({ routes: [ { path: '/main/:name', //接參 props: true, //聲明為true,方便前端頁面獲取參數 component: Main, children: [ //路由嵌套(嵌套子路由) { // path: '/user/profile', path: '/user/profile/:id', //接參 name: 'UserProfile', //可定義name屬性 component: UserProfile, props: true //通過聲明props解耦,在任何地方都可使用該組件 }, { path: '/user/list', component: UserList } ] }, { path: '/login', component: Login }, { path: '/goHome', redirect: '/main' //實現重定向 } ] });
-
頁面展示,聲明 props 屬性,并接參展示數據
Main.vue
<script> export default { props: ['name'], //接參 name: "Main" } </script> ------------------- <!--頂欄--> <el-container> <el-header style="text-align: right; font-size: 12px"> <el-dropdown> <i class="el-icon-setting" style="margin-right:15px"></i> <el-dropdown-menu slot="dropdown"> <el-dropdown-item>個人信息</el-dropdown-item> <el-dropdown-item>退出登錄</el-dropdown-item> </el-dropdown-menu> </el-dropdown> <!--顯示用戶名--> <span>{{name}}</span> </el-header> <!--主顯示頁--> <el-main> <!--這里展示路由跳轉的組件樣式--> <router-view/> </el-main> </el-container>
重定向
以下簡述實現方式:
-
在路由配置中使用
redirect
進行路由重定向,如:index.js
{ path: '/goHome', redirect: '/main' //實現重定向 },
-
使用指定路徑,以重定向方式進行跳轉,如:
Main.vue
<el-menu-item index="1-3"> <!--路由跳轉(重定向)--> <router-link to="/goHome">回到首頁</router-link> </el-menu-item>
注意
所有元素,不能直接暴露在根節點下?。?!
以Profile.vue
說明舉例:
錯誤用法:直接暴露在了<template>
中,程序報錯!
<template>
<!-- 所有元素,不能直接暴露在根節點下?。?! -->
<button></button>
<a></a>
<p></p>
<div>
<h2>個人信息</h2>
{{$route.params.id}}
<br/><br/>
{{id}}
</div>
</template>
<script>
export default {
props: ['id'], //可通過組件取參,在上面就可以直接用了
name: "UserProfile"
}
</script>
<style scoped>
</style>
正確用法:元素建議套在<div>
中使用!
<template>
<!-- 所有元素,不能直接暴露在根節點下?。?! -->
<div>
<button></button>
<a></a>
<p></p>
<h2>個人信息</h2>
{{$route.params.id}}
<br/><br/>
{{id}}
</div>
</template>
<script>
export default {
props: ['id'], //可通過組件取參,在上面就可以直接用了
name: "UserProfile"
}
</script>
<style scoped>
</style>
路由模式、404 和路由鉤子
路由模式
默認情況下,如,我們在地址欄中輸入地址http://localhost:8080
進行訪問,回車后,該地址欄中地址會自動帶上#
號,變為http://localhost:8080/#/
,這就是一種默認的路由模式!
路由模式有兩種:hash 和 history
- hash:路徑帶
#
符號,如http://localhost:8080/#/login
- history:路徑不帶
#
符號,如http://localhost:8080/login
路由模式設置:(不設置的話默認是 hash 模式,帶#
)
路由模式在路由配置中設置,一般通過在 router 目錄的 index.js
中設置 mode 屬性,如下:
import Vue from 'vue'
import VueRouter from 'vue-router'
import Main from "../views/Main";
import Login from "../views/Login";
import UserProfile from "../views/user/Profile";
import UserList from "../views/user/List";
import CheckPwd from "../views/CheckPwd";
import Button from "../views/Button";
//安裝路由
Vue.use(VueRouter);
//配置路由
export default new VueRouter({
//設置路由模式(默認hash,帶#號;history,則不帶#號)
mode: 'history',
routes: [
{
path: '/main/:name', //接參
props: true, //聲明為true,方便前端頁面獲取參數
component: Main,
children: [ //路由嵌套(嵌套子路由)
{
// path: '/user/profile',
path: '/user/profile/:id', //接參
name: 'UserProfile', //可定義name屬性
component: UserProfile,
props: true //通過聲明props解耦,在任何地方都可使用該組件
},
{
path: '/user/list',
component: UserList
}
]
},
{
path: '/login',
component: Login
},
{
path: '/goHome',
redirect: '/main' //實現重定向
},
{
path: '/checkPwd',
component: CheckPwd
},
{
path: '/button',
component: Button
}
]
});
404
一般情況下,地址欄輸入錯誤的訪問地址,應該給出一個 404 提示頁面,而不是什么都不顯示!
步驟:
-
views 下創建一個名為
NotFound.vue
的視圖組件,如下:NotFoung.vue
<template> <div> 404~ 你的頁面走丟了... </div> </template> <script> export default { name: "NotFound" } </script> <style scoped> </style>
-
路由配置(router 目錄下
index.js
)import Vue from 'vue' import VueRouter from 'vue-router' import Main from "../views/Main"; import Login from "../views/Login"; import UserProfile from "../views/user/Profile"; import UserList from "../views/user/List"; import CheckPwd from "../views/CheckPwd"; import Button from "../views/Button"; import NotFound from "../views/NotFound"; //安裝路由 Vue.use(VueRouter); //配置路由 export default new VueRouter({ //設置路由模式(默認hash,帶#號;history,則不帶#號) mode: 'history', routes: [ { path: '/main/:name', //接參 props: true, //聲明為true,方便前端頁面獲取參數 component: Main, children: [ //路由嵌套(嵌套子路由) { // path: '/user/profile', path: '/user/profile/:id', //接參 name: 'UserProfile', //可定義name屬性 component: UserProfile, props: true //通過聲明props解耦,在任何地方都可使用該組件 }, { path: '/user/list', component: UserList } ] }, { path: '/login', component: Login }, { path: '/goHome', redirect: '/main' //實現重定向 }, { path: '/checkPwd', component: CheckPwd }, { path: '/button', component: Button }, { path: '*', //匹配不到才走* component: NotFound } ] });
-
npm run dev
啟動,瀏覽器輸入規定內的不存在地址如http://localhost:8080/aa
,則會展示 404 視圖組件內容
路由鉤子與異步請求
鉤子函數
-
beforeRouteEnter
:在進入路由前執行 -
beforeRouteLeave
:在離開路由前執行
使用示例:
如在Profile.vue
中
<template>
<!-- 所有元素,不能直接暴露在根節點下?。?! -->
<div>
<h2>個人信息</h2>
{{$route.params.id}}
<br/><br/>
{{id}}
</div>
</template>
<script>
export default {
props: ['id'], //可通過組件取參,在上面就可以直接用了
name: "UserProfile",
//路由鉤子函數,類似于攔截器,在一些特殊時機自動執行!
beforeRouteEnter: (to, from, next)=>{
console.log("---》進入路由之前執行的!");
next();
},
beforeRouteLeave: (to, from, next)=>{
console.log("離開路由之前執行的!《===");
next();
}
}
</script>
<style scoped>
</style>
參數說明:
- to:路由將要跳轉的路徑信息
- from:路由跳轉前的路徑信息
- next:路由的控制參數
-
next()
:跳入下一個頁面 -
next('/path')
:改變路由的跳轉方向,使其跳到另一個路由 -
next(false)
:返回原來的頁面 -
next((vm)=>{})
:僅在beforeRouteEnter
中可用,vm
是組件實例
-
鉤子函數中使用異步請求
-
安裝 Axios:
cnpm install --save axios vue-axios
-
在
main.js
中引用 Axiosimport Vue from 'vue' import App from './App' import router from './router' import ElementUI from 'element-ui'; import 'element-ui/lib/theme-chalk/index.css'; import axios from 'axios' //導入axios import VueAxios from 'vue-axios' //導入axios Vue.config.productionTip = false Vue.use(router); Vue.use(ElementUI); Vue.use(VueAxios, axios) //使用axios new Vue({ el: '#app', router, render: h => h(App) // components: { App }, // template: '<App/>' })
-
在 static 目錄下新建 mock 目錄,在 mock 目錄下創建
data.json
作為測試數據(static 目錄下數據,地址欄可直接訪問獲?。?/p>data.json
{ "name": "luis", "url": "https://www.baidu.com", "page": 1, "isNonProfit": true, "address": { "street": "廣建路", "city": "江蘇蘇州", "country": "中國" } }
-
在
Profile.vue
中,演示鉤子函數與異步請求的使用Profile.vue
<template> <!-- 所有元素,不能直接暴露在根節點下?。?! --> <div> <h2>個人信息</h2> {{$route.params.id}} <br/><br/> {{id}} </div> </template> <script> export default { props: ['id'], //可通過組件取參,在上面就可以直接用了 name: "UserProfile", //路由鉤子函數,類似于攔截器,在一些特殊時機自動執行! beforeRouteEnter: (to, from, next)=>{ console.log("---》進入路由之前執行的!"); next((vm)=>{ vm.getData(); //利用組件實例調組件方法,獲取數據 }); }, beforeRouteLeave: (to, from, next)=>{ console.log("離開路由之前執行的!《==="); next(); }, methods: { getData: function () { this.axios({ //使用Axios異步通信 method: 'get', url: 'http://localhost:8080/static/mock/data.json' //請求的地址 }).then(function (response) { console.log(response.data); //返回的數據 }); } } } </script> <style scoped> </style>
-
npm run dev
啟動,瀏覽器 F12 打開調試,輸入localhost:8080/main/luis
進入首頁,點擊個人信息鏈接,觀察路由跳轉以及控制臺打印數據信息,查看是否可成功獲取數據。