Vue
簡介
Vue:是一套用於構建使用者介面的漸進式JavaScript框架。與其它大型框架不同的是,Vue 被設計為可以自底向上逐層應用。Vue 的核心庫只關注檢視層,方便與第三方庫或既有專案整合。
CSS前處理器:提供CSS缺失的樣式層複用機制,減少冗餘程式碼,提高樣式程式碼的可維護性,大大提高前端在樣式上的開發效率。
CSS前處理器:是一種專門的程式語言,進行web頁面樣式設計,通過編譯器轉化為正常的CSS檔案,以供專案使用。
常用CSS前處理器:
SASS,基於Ruby,通過服務端處理,功能強大,解析效率高,需要學習Ruby語言。
LESS,基於NodeJS,通過客戶端處理,使用簡單。
TypeScript:
- TypeScript是一種由微軟開發的開源、跨平臺的程式語言。它是JavaScript的超集,最終會被編譯為JavaScript程式碼。
- TypeScript擴充套件了JavaScript的語法,所以任何現有的JavaScript程式可以執行在TypeScript環境中。TypeScript是為大型應用的開發而設計,並且可以編譯為JavaScript。
JavaScript框架:
- JQuery:優點是簡化了DOM操作,缺點是DOM操作太頻繁,影響前端效能。
- Angular:Google收購的前端框架,由一群Java程式設計師開發,其特點是將將後臺的MVC模式搬到了前端,並增加了模組化開發的理念,與微軟合作,採用TypeScript語法開發,對後端程式設計師友好,對前端程式設計師不太友好。
- React:FaceBook出品,一款高效能JS前端框架,其特點是提出了新概念【虛擬DOM】用於減少真實DOM操作,在記憶體中模擬DOM操作,有效的提升了前端的渲染效率;缺點是複雜,需要額外學習一門JSX語言。
- Vue:一款漸進式JavaScript框架,所謂漸進式就是逐步實現新特性的意思,如實現模組化開發,路由,狀態管理等新特性,其特點是包含了Angular(模組化)和React(虛擬DOM)的優點。
- Axios:前端通訊框架,因為Vue的邊界很明確,就是為了處理DOM,不具備通訊能力;為此就需要一個通訊框架與伺服器互動,當然也可以使用JQuery提供的Ajax通訊功能。
UI框架
- Ant-Design:阿里巴巴出品。基於React的UI框架。
- ElementUI,iview,ice:餓了麼出品 ,基於Vue的UI框架。
- BootStrap:Twitter推出的用於前端開發的開源工具包。
- AmazeUI:一款HTML5跨屏前端框架。
JavaScript構建工具:
- Babel:JS 編譯工具,主要用於瀏覽器不支援的ES新特性,比如用於編譯TypeScript。
- WebPack:模組打包器,主要作用是打包,壓縮,合併及按序載入。
MVVM模式的實現者:
- Model:模型層,這裡表示JavaScript物件。
- View:檢視層,這裡表示DOM(HTML操作的元素)。
- ViewModel:連線檢視和資料的中介軟體,Vue.js就是MVVC中ViewModel層的實現者。
在MVVC架構中,是不允許資料和檢視直接通訊的,只能通過ViewModel來通訊,而ViewModel就是定義了一個Observer觀察者。
- ViewModel能夠觀察到資料的變化,並對檢視對應的內容進行更新。
- ViewModel能夠監聽到檢視的變化,並能通知資料發生改變。
因此,Vue.js就是一個MVVM的實現者,它的核心就是實現了DOM監聽與資料繫結。
為什麼使用MVVM:分離檢視和模型
- 低耦合:檢視可獨立於Model變化和修改,一個ViewModel可繫結到不同的View上,當View變化的時候Model可以不變,當Model變化的時候View也可以不變。
- 可複用:可以把一些邏輯檢視放在一個ViewModel中,讓很多View重用這段邏輯檢視。
- 獨立開發:開發人員可以專注業務邏輯和資料的開發(ViewModel),設計人員專注於頁面設計。
- 可測試:測試可以針對ViewModel來寫。
第一個Vue程式
IDEA安裝Vue.js外掛
demo.html
<body>
<div id="app">
<h1>{{message}}</h1>
<span v-bind:title="message">
滑鼠懸停幾秒檢視動態繫結的資訊
</span>
</div>
<!-- 匯入Vue.js-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
<script>
var vm = new Vue({
el:"#app",
data:{
message:"hello,vue!"
}
});
</script>
</body>
Vue基本語法
- if
<body>
<!--View層-->
<div id="app">
<h1 v-if="ok">Yes</h1>
<h1 v-else>No</h1>
</div>
<div id="app2">
<h1 v-if="type==='A'">A</h1>
<h1 v-else-if="type==='B'">B</h1>
<h1 v-else>C</h1>
</div>
<!-- 匯入Vue.js-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
<script>
var vm = new Vue({
el:"#app",
data:{
ok: true
}
});
var vm = new Vue({
el:"#app2",
data:{
type: 'A'
}
});
</script>
</body>
- for
<body>
<div id="app">
<h1 v-for="item in items">{{item.message}}</h1>
</div>
<!-- 匯入Vue.js-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
<script>
var vm = new Vue({
el:"#app",
data:{
items:[
{message: 'zzrr'},
{message: 'Vue'}
]
}
});
</script>
</body>
- 監聽事件
<body>
<!--View層-->
<div id="app">
<button v-on:click="sayHi">click me</button>
</div>
<!-- 匯入Vue.js-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
<script>
var vm = new Vue({
el: "#app",
data: {
message: 'zzr'
},
methods: {
// 方法必須定義在Vue的methods物件中
sayHi: function () {
alert(this.message);
}
}
});
</script>
</body>
雙向繫結
文字框繫結
<body>
<!--View層-->
<div id="app">
<!-- 輸入的文字:<input type="text" v-model="message">{{message}}-->
<textarea v-model="message"></textarea>
輸入文字框內容為:{{message}}
</div>
<!-- 匯入Vue.js-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
<script>
var vm = new Vue({
el: "#app",
data: {
message: ""
}
});
</script>
</body>
單選框繫結
<body>
<!--View層-->
<div id="app">
性別:
<input type="radio" name="sex" value="男" v-model="zr">男
<input type="radio" name="sex" value="女" v-model="zr">女
<p>
你選中了:{{zr}}
</p>
</div>
<!-- 匯入Vue.js-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
<script>
var vm = new Vue({
el: "#app",
data: {
zr: ""
}
});
</script>
</body>
下拉框
<body>
<!--View層-->
<div id="app">
<p>
下拉框:<select v-model="message">
<option value="" disabled>--請選擇--</option>
<option>A</option>
<option>B</option>
<option>C</option>
</select>
value: {{message}}
</p>
</div>
<!-- 匯入Vue.js-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
<script>
var vm = new Vue({
el: "#app",
data: {
message: ""
}
});
</script>
</body>
元件
<body>
<!--View層-->
<div id="app">
<zzr v-for="item in items" v-bind:zr="item"></zzr>
</div>
<!-- 匯入Vue.js-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
<script>
// 定義一個Vue元件component
Vue.component("zzr",{
props: ['zr'],
template: '<li>{{zr}}</li>'
});
var vm = new Vue({
el: "#app",
data: {
items: ["java","linux","vue"]
}
});
</script>
</body>
Axios非同步通訊
Axios是一個開源的可以用在瀏覽器端和 Node.JS 的非同步通訊框架, 它的主要作用是和Ajax一樣實現非同步通訊。
Axios:
- 從瀏覽器中建立XMLHttpRequests
- 從Node.js建立http請求
- 支援Peomise API [JS中鏈式程式設計]
- 攔截請求和響應
- 轉換請求資料和響應資料
- 取消請求
- 自動轉換 JSON 資料
- 客戶端支援防禦XSRF [跨站請求偽造]
測試
<head>
<meta charset="UTF-8">
<title>Title</title>
<!-- 解決閃爍問題-->
<style>
[v-clock]{
display: none;
}
</style>
</head>
<body>
<!--View層-->
<div id="vue" v-clock>
<div>{{info.name}}</div>
<div>{{info.address}}</div>
<div>{{info.links}}</div>
<div>{{info.address.city}}</div>
<a v-bind:href="info.url">部落格園</a>
</div>
<!-- 匯入Vue.js和axios-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script>
var vm = new Vue({
el: "#vue",
data(){//data方法
return{
//請求的返回引數格式,必須和json字串一樣
info: {
name: null,
url: null,
address:{
city: null,
country: null
},
links:[{
name: null,
url: null
}]
}
}
},
mounted(){//鉤子函式
axios.get('../data.json').then(response=>(this.info=response.data))
}
});
</script>
</body>
data.json
{
"name": "zr",
"url": "https://www.cnblogs.com/zhou-zr",
"page": "11",
"address": {
"city": "武漢",
"country": "中國"
},
"links": [
{
"name": "bokeyuan",
"url": "cnblogs.com/zhou-zr"
},
{
"name": "zrkuang",
"url": "www.baidu.com"
}
]
}
計算屬性
計算屬性:是一個能夠將計算結果快取起來的屬性(將行為轉化成了靜態的屬性),可理解為快取。
demo8.html
<body>
<!--View層-->
<div id="app">
<p>currentTime():{{currentTime()}}</p>
<p>currentTime2:{{currentTime2}}</p>
</div>
<!-- 匯入Vue.js-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
<script>
var vm = new Vue({
el: "#app",
data: {
message:"hello,zzzrrr!"
},
methods: {
currentTime: function () {//在瀏覽器控制檯輸出vm.currentTime()時間戳值會改變
return Date.now();//返回時間戳
}
},
computed: {//計算屬性 methods,computed方法名不能重,重名會呼叫methods中的方法
currentTime2: function () {//在瀏覽器控制檯輸出vm.currentTime2時間戳值不會改變
this.message; //增加這一行後控制檯vm.message="zzrr"再輸出時間戳值會改變
return Date.now();//返回時間戳
}
}
});
</script>
</body>
呼叫方法時,每次需要計算,既然計算就必然產生系統的開銷,如果這個結果不經常變化就可以考慮將這個結果快取起來。計算結果的主要目的就是將不經常變化的計算結果進行快取,以節省系統的開銷。
Slot
在Vue.js中我們使用
v-bind:簡寫 :
demo9.html
<body>
<!--View層-->
<div id="app">
<tudo>
<!--v-bind:簡寫 :-->
<tudo-title slot="tudo-title" :title="title"></tudo-title>
<tudo-items slot="tudo-items" v-for="item in tudoItems" :items="item"></tudo-items>
</tudo>
</div>
<!-- 匯入Vue.js-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
<script>
Vue.component("tudo",{
template:
'<div>\
<slot></slot>\
<ul>\
<slot></slot>\
</ul>\
</div>'
});
Vue.component("tudo-title",{
props: ['title'],
template: '<div>{{title}}</div>'
});
Vue.component("tudo-items",{
props: ['items'],
template: '<li>{{items}}</li>'
});
var vm = new Vue({
el: "#app",
data: {
title: "週週",
tudoItems: ["Java","ZZRR","Kuang"],
}
});
</script>
</body>
自定義事件
v-on:簡寫 @
this.$emit 自定義事件分發
demo10.html
<body>
<!--View層-->
<div id="app">
<tudo>
<tudo-title slot="tudo-title" :title="title"></tudo-title>
<tudo-items slot="tudo-items" v-for="(item,index) in tudoItems" :items="item" v-bind:index="index" v-on:remove="removeItems(index)"></tudo-items>
</tudo>
</div>
<!-- 匯入Vue.js-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
<script>
Vue.component("tudo",{
template:
'<div>'+
'<slot name="tudo-title"></slot>'+
'<ul>'+
'<slot name="tudo-items"></slot>'+
'</ul>'+
'</div>'
});
Vue.component("tudo-title",{
props: ['title'],
template: '<div>{{title}}</div>'
});
Vue.component("tudo-items",{
props: ['items','index'],
//v-on:簡寫 @
template: '<li>{{index}}----{{items}} <button @click="remove">刪除</button></li>',
methods: {
remove: function (index) {
//this.$emit 自定義事件分發
this.$emit('remove',index);
}
}
});
var vm = new Vue({
el: "#app",
data: {
title: "週週",
tudoItems: ["Java","ZZRR","Kuang"],
},
methods: {
removeItems: function (index) {
console.log("刪除了"+this.tudoItems[index]);
this.tudoItems.splice(index,1); //一次刪除一個元素
}
}
});
</script>
</body>
第一個Vue-cli程式
-
安裝node.js(官網下載64位的安裝包,直接安裝到自己指定目錄)
-
cmd以管理員開啟,node-v;npm-v分別輸入檢視版本
-
安裝淘寶映象加速器,npm install cnpm -g
-
安裝vue-cli,輸入cnpm install vue-cli -g
-
輸入vue list,檢視可以基於哪些模板建立 vue 應用程式,通常選擇webpack
- 新建一個專案資料夾,cmd進入該資料夾,輸入vue init webpack myvue(一路no即可)
-
進入vue專案中 cd myvue,再執行npm install
-
npm run dev啟動專案
- 可輸入以上地址訪問,ctrl+c 終止
webpack學習使用
webpack是一個現代JavaScript應用程式的靜態模組打包器(model bundler),當webpack處理應用程式時,它會遞迴的構建一個依賴關係圖,其中包含應用程式需要的每個模組,然後將這些模組打包成一個或者多個包(bundle) 。
cmd以管理員啟動:
-
npm install webpack -g
-
npm install webpack-cli -g
測試安裝成功:
- webpack -v
- webpack-cli -v
專案包(webpack-study)下modules資料夾下
hello.js
//暴露一個方法
exports.sayHi = function () {
document.write("<h1>zzzrrr</h1>")
};
(webpack-study)/modules/main.js
var hello = require("./hello");
hello.sayHi();
專案包(webpack-study)下webpack.config.js
module.exports = {
entry: "./modules/main.js",
output:{
filename: "./js/bundle.js",
}
};
打包
管理員cmd進入到(webpack-study)下,webpack打包,webpack --watch熱部署(選一個即可)。
專案包下index.html
<body>
<script src="dist/js/bundle.js"></script>
</body>
Vue-Router路由
Vue-Router是Vue.js官方的路由管理器,它和Vue.js的核心深度整合,讓構建單頁面應用變得易如反掌,包含的功能有:
- 巢狀的路由/檢視類
- 模組化的,基於元件的路由配置
- 路由引數,查詢,萬用字元
- 基於Vue.js過渡系統的檢視過渡效果
- 細粒度的導航控制
- 帶有自動啟用的CSS class的連線
- HTML5歷史模式或hash模式,在IE9中自動降級
- 自定義的滾動條行為
專案目錄下:npm install vue-router --save-dev
src/components/Content.vue
<template>
<h1>內容頁</h1>
</template>
<script>
export default {
name: "Content"
}
</script>
<style scoped>
</style>
src/components/Main.vue
<template>
<h1>首頁</h1>
</template>
<script>
export default {
name: "Main"
}
</script>
<style scoped>
</style>
src/components/Zzr.vue
<template>
<h1>ZZRR</h1>
</template>
<script>
export default {
name: "Zzr"
}
</script>
<style scoped>
</style>
src/router/index.js
import Vue from 'vue';
import VueRouter from 'vue-router';
import Content from "../components/Content";
import Main from "../components/Main";
import Zzr from "../components/Zzr";
//安裝路由
Vue.use(VueRouter);
//配置匯出路由
export default new VueRouter({
routes: [
{
//路徑
path: '/content',
name: 'content',
//跳轉的元件
component: Content
},
{
//路徑
path: '/main',
name: 'content',
//跳轉的元件
component: Main
},
{
//路徑
path: '/zzr',
name: 'content',
//跳轉的元件
component: Zzr
},
]
});
src/App.vue
<template>
<div id="app">
<h1>Vue-Router</h1>
<router-link to="/main">首頁</router-link>
<router-link to="/content">內容頁</router-link>
<router-link to="/zzr">Zzr</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>
src/main.js
import Vue from 'vue'
import App from './App'
import router from './router' //自動掃描裡面的路由配置
Vue.config.productionTip = false;
new Vue({
el: '#app',
//配置路由
router,
components: { App },
template: '<App/>'
})
專案下執行 npm run dev,然後訪問。
vue+elementUI
建立工程步驟
- 建立工程
- vue init webpack hello-vue
- 進入工程目錄
- cd hello-vue
- 安裝
- npm install vue-router --sava-dev
- 安裝
- npm i element-ui -S
- 安裝依賴
- npm install
- 安裝SASS載入器
- cnpm install sass-loader node-sass --save-dev
- 啟動測試
- npm run dev
解釋說明:
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為該命令的縮寫。
搭建專案,結構目錄如下:
Login.vue
<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>
App.vue
<template>
<div id="app">
<h1>App</h1>
<router-view></router-view>
</div>
</template>
<script>
export default {
name: 'App',
}
</script>
index.js
import Vue from 'vue'
import Router from 'vue-router'
import Login from "../views/Login"
import Main from "../views/Main"
Vue.use(Router);
export default new Router({
routes: [
{
path: '/main',
component: Main
},
{
path: '/login',
component: Login
}
]
});
App.vue
<template>
<div id="app">
<h1>App</h1>
<router-view></router-view>
</div>
</template>
<script>
export default {
name: 'App',
}
</script>
main.js
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.use(router);
Vue.use(ElementUI);
new Vue({
el: '#app',
router,
render: h => h(App), //Element
})
執行npm run dev後,訪問http://localhost:8080/#/login
注意如果打包釋出失敗:在pakage.json中降低sass版本為"sass-loader": "^7.3.1",
如果出現:
執行 npm uninstall node-sass 解除安裝
再安裝 cnpm install node-sass@4.14.1
最後:npm run dev
巢狀路由
巢狀路由又稱子路由,在實際應用中,通常由多層巢狀的元件而成,同樣的,URL中各段動態路徑也按某種結構對應巢狀各層元件。
在上一個專案基礎下增加user資料夾
List.vue
<template>
<h1>使用者列表頁</h1>
</template>
<script>
export default {
name: "List"
}
</script>
<style scoped>
</style>
Profile.vue
<template>
<h1>個人資訊</h1>
</template>
<script>
export default {
name: "Profile"
}
</script>
<style scoped>
</style>
index.js
import Vue from 'vue'
import Router from 'vue-router'
import Login from "../views/Login"
import Main from "../views/Main"
import UserList from "../views/user/List";
import UserProfile from "../views/user/Profile";
Vue.use(Router);
export default new Router({
routes: [
{
path: '/main',
component: Main,
//巢狀路由
children: [
{path: '/user/profile',component: UserProfile},
{path: '/user/list',component: UserList}
]
},
{
path: '/login',
component: Login,
}
]
});
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 lang="scss">
.el-header {
background-color: #2acaff;
color: #333;
line-height: 60px;
}
.el-aside {
color: #333;
}
</style>
引數傳遞及重定向
方法一
修改Main.vue
<el-menu-item index="1-1">
<!--插入的地方 name;地址,params:引數 傳參:v-bind -->
<router-link :to="{name: 'UserProfile',params: {id:1}}">個人資訊</router-link>
</el-menu-item>
修改index.js
//巢狀路由
children: [
{path: '/user/profile/:id',name: 'UserProfile',component: UserProfile},
{path: '/user/list',component: UserList}
]
修改Profile.vue,接收
<template>
<!-- 所有的元素不能直接在根節點下-->
<div>
<h1>個人資訊</h1>
{{$route.params.id}}
</div>
</template>
方法二
Main.vue和方法一相同
index.js
//巢狀路由
children: [
{path: '/user/profile/:id',name: 'UserProfile',component: UserProfile,props:true},
{path: '/user/list',component: UserList}
]
修改Profile.vue,接收
<template>
<!-- 所有的元素不能直接在根節點下-->
<div>
<h1>個人資訊</h1>
{{id}}
</div>
</template>
<script>
export default {
props: ['id'],
name: "Profile"
}
</script>
<style scoped>
</style>
重定向
index.js中增加
{
path: '/goHome',
redirect: '/main',
}
Main.vue中增加
<el-menu-item index="1-3">
<!--插入的地方-->
<router-link to="/goHome">回到首頁</router-link>
</el-menu-item>
登入顯示使用者名稱:
Login.vue中修改為:
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;
}
});
}
}
index.js中Main元件上增加 props: true,
path: '/main/:name',
props: true,
component: Main,
Main.vue增加 props:['name'], 接收引數, {{name}} 顯示
<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>
</el-container>
</div>
</template>
<script>
export default {
props:['name'],
name: "Main"
}
</script>
測試 http://localhost:8080/#/login 登入後右上方顯示使用者名稱
404和路由鉤子
路由模式有兩種:
- hash:路徑帶#符號,如 http://localhost:8080/#/login
- history:路徑不帶#符號,如 http://localhost:8080/login
index.js中增加 mode: 'history',
export default new Router({
mode: 'history',
routes: [
{
});
配置404頁面
NotFound.vue
<template>
<div><h1>404,你的頁面走丟了</h1></div>
</template>
<script>
export default {
name: "NotFound"
}
</script>
<style scoped>
</style>
index.js
import NotFound from "../views/NotFound";
....
//路由中增加
{
path: '*',
component: NotFound,
}
路由鉤子與非同步請求
beforeRouteEnter:在進入路由前執行
beforeRouteLeave:在離開路由前執行
Profile.vue
export default {
props: ['id'],
name: "Profile",
beforeRouteEnter:(to, from, next)=>{
console.log("進入路由之前!");
next();
},beforeRouteLeave:(to, from, next)=>{
console.log("進入路由之後!");
next();
},
methods: {
getData: function () {
this.axi
}
}
}
引數說明:
- to:路由將要跳轉的路徑資訊
- from:路徑跳轉前的路徑資訊
- next:路由的控制引數
- next() 跳入下一個頁面
- next('/path') 改變路由的跳轉方向,使其跳到另一個路由
- next(false) 返回原來的介面
- next((vm)=>{}) 僅在beforeRouteEnter中可用,vm是元件例項
在鉤子函式中使用非同步請求:
-
安裝axios:cnpm install axios -s (打包失敗使用npm install --save vue-axios或官網npm install --save axios vue-axios)
-
main.js中引用axios
Profile.vue
<script>
export default {
props: ['id'],
name: "Profile",
beforeRouteEnter:(to, from, next)=>{
console.log("進入路由之前!");
next(vm => {
vm.getData();//進入路由之前執行該方法
});
},beforeRouteLeave:(to, from, next)=>{
console.log("進入路由之後!");
next();
},
methods: {
getData: function () {
this.axios({
method: 'get',
url: 'http://localhost:8080/static/mock/data.josn',
}).then(function (response) {
console.log(response);
})
}
}
}
</script>