Vue入門
1.什么是MVVM?
MVVM(Model-View-ViewModel)是一種軟件架構設計模式,是一種簡化用戶界面的事件驅動編程方式。它源自與經典的MVC模式,MVVM的核心是ViewModel層,負責轉換Model中的數據對象來讓數據變得更容易管理和使用
為什么要使用MVVM?
MVVM模式和MVC模式一樣,主要目的是分離視圖(View)和模型(Model)
低耦合:視圖(View)可以獨立於Model變化和修改,一個ViewModel可以綁定到不同的View上,當View變化的時候Model可以不變,當Model變化的時候,View也可以不變。
可復用:你可以把一些視圖邏輯放在一個ViewModel里面,讓很多View重用這段視圖邏輯。
獨立開發:開發人員可以專注於業務邏輯和數據的開發(ViewModel),設計人員可以專注於頁面設計。
可測試:界面向來是比較難於測試的,而現在測試可以針對ViewModel來寫
2.第一個Vue項目
第一個Vue程序
1.導入Vue.js
CDN導入
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
2.new 一個vue對象
3.綁定一個元素
4.放數據
5.從模板里取出來
<!--View層 模板-->
<div id="app">
{{message}}
</div>
<!--導入vue.js-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
<script>
var vm = new Vue({
el:"#app",
//Model:數據
data:{
message:"hello,vue!"
}
});
</script>
3.Vue基本語法
v-bind
使用v-bind來綁定元素特性!
v-開頭的被稱為指令
v-bind這個指令的意思是“將這個元素節點的title特性和Vue實例的message屬性保持一致
<!--View層 模板-->
<div id="app">
<span v-bind:title="message">鼠標懸停在此處,可以查看動態綁定的信息</span>
</div>
<!--導入vue.js-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
<script>
var vm = new Vue({
el:"#app",
//Model:數據
data:{
message:"hello,vue!"
}
});
</script>
v-if、v-else
<!--View層 模板-->
<div id="app">
<h1 v-if ok==="lyl">我是true</h1>
<h1 v-else>我是flase</h1>
</div>
<!--導入vue.js-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
<script>
var vm = new Vue({
el:"#app",
//Model:數據
data:{
ok: "lyl"
}
});
</script>
v-for
<!--View層 模板-->
<div id="app">
<li v-for="item in items">
{{item.message}}
</li>
</div>
<!--導入vue.js-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
<script>
var vm = new Vue({
el:"#app",
//Model:數據
data:{
items:[
{message: "我是itme1"},
{message: "我是itme2"}
]
}
});
</script>
methods
<div id="app">
<button v-on:click="say">click me</button>
</div>
<!--導入vue.js-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
<script>
var vm = new Vue({
el:"#app",
//Model:數據
data:{
message: "我是Vue"
},
methods:{//方法必須定義在Vue的method對象中
say:function (event){
alert(this.message);
}
}
});
</script>
4.Vue的雙向綁定
什么是雙向數據綁定?
Vue.js是一個MVVM框架,即數據雙向綁定,即當數據發生變化的時候,視圖也就發生變化,當視圖發生變化的時候,數據也會跟着同步變化,這也是Vue的精髓之處。
注意,我們所說的數據雙向綁定,一定是對於Ui控件來說的,非UI控件不會涉及到數據的雙向綁定,單項數據綁定是使用狀態管理工具的前提,如果我們使用vuex,那么數據流也是單項的,這時就會和雙向數據綁定有沖突。
為什么要實現數據的雙向綁定?
在vue.js 中,如果使用vuex,實際上數據還是單向的,之所以說是數據雙向綁定,這是用的UI控件來說,對於我們處理表單,Vue.js
的雙向數據綁定用起來就特別舒服了。即兩者並不互斥,在全局性數據流使用單項,方便跟蹤;局部性數據流使用雙向,簡單易操作。
在表單中使用雙向數據綁定?
你可以用v-model 指令在表單
<input>
,
<textarea>
及<select>
元素上創建雙向數據綁定。它會根據控件類型自動選取正確的方法來更新元素。盡管有些神奇,但v-model本質上不過是語法糖。它負責監聽用戶的輸入事件以更新數據,並對一些極端場景進行一些特殊處理。
注意: v-model 會忽略所有表單元素的.value、checked、selected
特性的初始值而總是將Vue實例的數據作為數據來源。你應該通過JavaScript在組件的data選項中聲明初始值!
通過v-model實現數據綁定
<div id="app">
請輸入文本:<input type="text" v-model="message">{{message}}
<!--也可以使用selected實現默認選值-->
<select name="" id="" v-model="selected">
<option disabled value="">--請選擇--</option>
<option value="A">A</option>
<option value="B">B</option>
<option value="C">C</option>
</select>
{{selected}}
</div>
<!--導入vue.js-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
<script>
var vm = new Vue({
el:"#app",
//Model:數據
data:{
message: "我是Vue"
selected: "C" //默認下拉菜單選中為C
},
methods:{//方法必須定義在Vue的method對象中
}
});
</script>
v-bind和v-model區分
(1)v-bind是單項數據綁定,映射關系是Model->View,我們通過Model操作就可以實現視圖的聯動更新。
格式:v-bind:(props)="(message)"
props就是組件component的元素
message就是vm中Data對象的數據
綁定一個屬性
<img v-bind:src="imagesrc"/>
(2)v-model是雙向數據綁定,映射關系是 View接受的數據,傳給model,model的數據再傳給view ,用於表單控件
5.Vue組件
通過component定義一個組件,component有兩個元素:props(參數)、template(模板)
組件lyl
中的v-bind
綁定了props
屬性中的參數
<div id="app">
<lyl v-for="item in items" v-bind:zujian="item"></lyl>
</div>
<!--導入vue.js-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
<script>
//定義一個Vue組件component
Vue.component("lyl",{
props: ['zujian'],
template:'<li>{{zujian}}</li>'
})
var vm = new Vue({
el:"#app",
//Model:數據
data:{
items: ["西瓜","蘋果","橘子"]
}
});
</script>
6.Axios異步通信
什么是Axios?
Axios是一個開源的可以用在瀏覽器端和
node.js
的異步通信框架,它的主要作用就是實現 AJAX異步通信,其功能特點如下:
-
從瀏覽器中創建XMLHttpRequests
-
從node.js 創建http請求
-
支持Promise API[ JS中鏈式編程 ]攔截請求和響應
-
轉換請求數據和響應數據取消請求
-
自動轉換JSON數據
-
客戶端支持防御XSRF(跨站請求偽造)
為什么要使用Axios?
由於Vue.js
是一個視圖層框架並且作者(尤雨溪)嚴格准守SoC (關注度分離原則),所以Vue.js並不包含AJAX的通信功能,為了解決通信問題,作者單獨開發了一個名為 vue-resource
的插件,不過在進入2.0版本以后停止了對該插件的維護並推薦了Axios框架。少用jQuery,因為它操作Dom太頻繁!
Axios的CDN引入:
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
Vue實例有一個完整的生命周期,也就是從開始創建、初始化數據、編譯模板、掛載DOM、渲染→更新→渲染、卸載等一系列過程,我們稱這是Vue的生命周期。通俗說就是Vue
實例從創建到銷毀的過程,就是生命周期。
實例測試:
<div id="app">
<div>{{info.address.country}}</div>
<div>{{info.name}}</div>
<a v-bind:href="info.url">跳轉</a>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script type="text/javascript">
var vm = new Vue({
el:"#app",
//data:是vm的屬性,此處用的是data()
data(){
return{
//請求返回的參數格式,必須和json字符串一樣
info: {
name: null,
address: {
street: null,
city: null,
country: null
},
url:null
}
}
},
mounted(){//鈎子函數,鏈式編程,Es6新特性
axios.get('../data.json').then(response=>(this.info=response.data))
},
});
</script>
7.計算屬性
計算出來的結果,保存在屬性中(簡單來說,就是能夠將計算結果緩存起來的屬性)
內存中運行:虛擬DOM
<div id="app">
<div>time:{{time()}}</div>
<div>time1:{{time1}}</div>
</div>
<!--導入vue.js-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
<script>
var vm = new Vue({
el:"#app",
//Model:數據
data:{
message:"你好"
},
methods:{
time:function (){
return Date.now(); //返回一個時間戳
}
},
computed:{//計算屬性
time1:function (){
this.message;
return Date.now();
}
}
});
</script>
- methods:定義方法,調用方法使用time(),需要帶括號
- computed:定義計算屬性,調用屬性使用time1,不需要帶括號; this.message 是為了能夠讓time1觀察到數據變化而變化
- 如何在方法中的值發生了變化,則緩存就會刷新! 可以在控制台使用vm.message="lyl" ,改變下數據的值,再次測試觀察效果!
8.插槽slot
在vue.js中我們使用<slot>
元素作為承載分發內容的出口,作者稱其為插槽,可以應用在組合組件的場景中;
通過插槽<slot>
的name屬性進行值的綁定
<div id="app">
<todo>
<todo-title slot="todo-title" v-bind:title="title"></todo-title>
<todo-item slot="todo-item" v-for="item in items" v-bind:item="item"></todo-item>
</todo>
</div>
<!--導入vue.js-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
<script>
//slot插槽
Vue.component("todo",{
//通過slot中的name屬性綁定標簽中的slot
template: `<div>`+
`<slot name="todo-title"></slot>`+
`<ul>\
<slot name="todo-item"></slot>
</ul>`+
`</div>`
});
//一個title組件,props中的參數要加引號
Vue.component("todo-title",{
props: ['title'],
template: '<div>{{title}}</div>'
});
//一個item組件
Vue.component("todo-item",{
props: ['item'],
template: '<li>{{item}}</li>'
})
var vm = new Vue({
el:"#app",
data:{
title: "title:lyl測試",
items:['java','python','C']
},
});
</script>
9.自定義事件內容分發
補充:
(1)v-for可以遍歷出數組的下標
v-for="(item,index) in items"
(2)組件中也可以有methods:
對象
(3)通過this.$emit()
自定義事件內容分發
(4)v-on
等價於@click
<div id="app">
<todo>
<todo-title slot="todo-title" v-bind:title="title"></todo-title>
<todo-item slot="todo-item"
v-for="(item,index) in items"
v-bind:item="item"
v-bind:index="index"
v-on:remove_self="removeitems(index)">
</todo-item>
</todo>
</div>
<!--導入vue.js-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
<script>
//slot插槽
Vue.component("todo",{
//通過slot中的name屬性綁定標簽中的slot
template: `<div>`+
`<slot name="todo-title"></slot>`+
`<ul>\
<slot name="todo-item"></slot>
</ul>`+
`</div>`
});
//一個title組件,props中的參數要加引號
Vue.component("todo-title",{
props: ['title'],
template: '<div>{{title}}</div>'
});
//一個item組件
Vue.component("todo-item",{
props: ['item','index'],
//組件只可以綁定組件內部自己的methods的方法,不能綁定vue對象的方法
template: '<li>索引:{{index}}---》{{item}} <button v-on:click="remove">刪除</button></li>',
methods: {
remove:function (index){
//通過this.$emit 自定義事件分發,調用vue對象中的removeitems
this.$emit('remove_self',index)
}
}
})
var vm = new Vue({
el:"#app",
data:{
title: "title:lyl測試",
items:['java','python','C']
},
methods: {
removeitems:function (index){
console.log("刪除了"+this.items[index]+"成功")
this.items.splice(index,1) //通過js的splice方法,從index開始,一次刪除一個元素
}
}
});
</script>
自定義事件分發小結:
(前端作為轉接媒介)
(1)在實現插槽的組件中可以調用自身的methods方法,但是無法調用Vue對象的methods方法
(2)通過在組件的方法中,this.$emit('remove_self',index)
實現事件轉發
(3)在組件的標簽中,通過事件轉發的方法 v-on:remove_self="removeitems(index)"
綁定到Vue對象中的methods方法
第一個Vue-cli項目
1.什么是vue-cli?
vue-cli官方提供的一個腳手架,用於快速生成一個vue的項目模板;
預先定義好的目錄結構及基礎代碼,就好比咱們在創建Maven項目時可以選擇創建一個骨架項目,這個骨架項目就是腳手架,我們的開發更加的快速;
主要的功能:
- 統一的目錄結構
- 本地調試
- 熱部署
- 單元測試
- 集成打包上線
2.環境配置
- Node.js
下載地址: http://nodejs.cn/download/ 安裝的時候一直下一步直到結束
確認是否安裝成功:
- 在cmd中運行node -v命令,查看是否能夠輸出版本號
- 在cmd中運行npm -v命令,查看是否能夠輸出版本號
- 安裝node.js淘寶鏡像加速器(cnpm)
# -g 就是全局安裝
npm install cnpm -g
# 或使用如下語句解決npm速度慢的問題,但是每次install都需要(媽發)
npm install --registry=https://registry.npm.taobao.org
- 安裝vue-cli
cnpm instal1 vue-cli-g
#測試是否安裝成功#查看可以基於哪些模板創建vue應用程序,通常我們選擇webpack
vue list
2.2 第一個vue-cli應用程序
- 找到一個項目路徑(空文件夾)
- 創建一個基於webpack模板的vue應用程序
#1、首先需要進入到對應的目錄 cd E:\study\Java\workspace\workspace_vue
#2、這里的myvue是頂日名稱,可以根據自己的需求起名
vue init webpack myvue
-
創建過程需要的操作
一路選no
Project name:項目名稱,默認回車即可
Project description:項目描述,默認回車即可
Author:項目作者,默認回車即可
Install vue-router:是否安裝vue-router,選擇n不安裝(后期需要再手動添加)
Use ESLint to lint your code:是否使用ESLint做代碼檢查,選擇n不安裝(后期需要再手動添加)
Set up unit tests:單元測試相關,選擇n不安裝(后期需要再手動添加)
Setupe2etests with Nightwatch:單元測試相關,選擇n不安裝(后期需要再手動添加)
Should we run npm install for you after the,project has been created:創建完成后直接初始化,選擇n,我們手動執行;運行結果
當出現問題時,它會給出提示我們按照提示來就行
- 初始化並運行
cd myvue
npm install
npm run dev
訪問localhost:8080即可
Webpack
什么是webpack?
本質上,webpack是一個現代JavaScript應用程序的靜態模塊打包器(module
bundler)。當webpack處理應用程序時,它會遞歸地構建一個依賴關系圖(dependency
graph),其中包含應用程序需要的每個模塊,然后將所有這些模塊打包成一個或多個bundle.
Webpack是當下最熱門的前端資源模塊化管理和打包工具,它可以將許多松散耦合的模塊按照依賴和規則打包成符合生產環境部署的前端資源。還可以將按需加載的模塊進行代碼分離,等到實際需要時再異步加載。通過loader轉換,任何形式的資源都可以當做模塊,比如CommonsJS.AMD、ES6、css、JSON、CoffeeScript、LESS等;
安裝Webpack
WebPack是一款模塊加載器兼打包工具, 它能把各種資源, 如JS、JSX、ES 6、SASS、LESS、圖片等都作為模塊來處理和使用
安裝:
npm install webpack -g
npm install webpack-cli -g
測試安裝成功:
webpack -v
webpack-cli -v
配置:
創建webpack .config.js配置文件
entry: 入口文件,指定WebPack 用哪個文件作為項目的入口
output:輸出,指定WebPack把處理完成的文件放置到指定路徑
module:模塊,用於處理各種類型的文件
plugins:插件,如:熱更新、代碼重用等r
resolve:設置路徑指向
watch:監聽,用於設置文件改動后直接打包
- 創建項目
在自己的目錄中,新建文件夾webpack-study,然后用IDEA打開
- 創建一個名為modules的目錄,用於放置JS模塊等資源文件
- 在modules下創建模塊文件hello.js
//暴露一個方法:sayHi
exports.sayHi = function(){
document.write("<div>Hello Webpack</div>");
}
- 在modules下創建一個名為main.js的入口文件main.js,用於打包時設置entry屬性
//require 導入一個模塊,就可以調用這個模塊中的方法了
var hello = require("./hello");
hello.sayHi();
- 在項目目錄下創建webpack.config.js配置文件,
module.exports = {
entry:"./modules/main.js",
output:{
filename:"./js/bundle.js"
}
}
- 使用webpack命令打包(命令行狀態下),打包成功后會生成一個dist文件夾
打包:
說明:打包如果失敗,就用管理員權限運行webpack
- 在項目目錄下創建HTML頁面,index.html,通過script導入webpack打包后的JS文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<script src="./dist/js/bundel.js"></script>
</body>
</html>
補充:
webpack -watch
參數--watch 用於監聽變化,如果要打包的東西有變化,就重新打包
Vue-router路由
Vue Router是Vue.js官方的路由管理器。它和Vue.js的核心深度集成,讓構建單頁面應用變得易如反掌。包含的功能有:
-
嵌套的路由/視圖表
-
模塊化的、基於組件的路由配置路由參數、查詢、通配符
-
基於Vue.js 過渡系統的視圖過渡效果
-
細粒度的導航控制
-
帶有自動激活的Css classt的鏈接
-
HTML5歷史模式或hash模式,在IE9中自動降級
-
自定義的滾動條行為
安裝
- 基於第一個
vue-cli
進行測試學習; 先查看node modules中是否存在vue-router, vue-router是一個插件包, 所以我們還是需要用npm/cnpm來進行安裝的
npm install vue-router --save-dev
- 如果在一個模塊化工程中使用它,必須要通過Vue.use()明確地安裝路由功能
import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter);
問題解決:
npm run dev時候提示好多警告,Router is not found in vue-router
,並且無法加載出頁面
原因:vue-router的版本太高
解決方案:更換低版本的vue-router
cnpm install vue-router@3.1.3 --save-dev
測試路由
- 在src目錄下新建
cpmponents
文件夾用於存放我們自己編寫的組件 - 定義自己的組件Content.vue、Main.vue
Content.vue
<template>
<h1>內容頁</h1>
</template>
<script>
export default {
name: "Content"
}
</script>
<style scoped>
</style>
Main.vue
<template>
<h1>首頁</h1>
</template>
<script>
export default {
name: "Main"
}
</script>
<style scoped>
</style>
- 新建router文件夾,用於存放路由,在文件夾下編寫index.js,用於配置路由
index.js
import Vue from 'vue'
//導入路由插件
import Router from "vue-router";
//導入自定義的組件
import Content from "../components/Content";
import Main from "../components/Main";
//安裝路由
Vue.use(Router);
//配置導出路由
export default new Router({
routes:[
{
//路由路徑
path:'/content',
name:'content',
//跳轉的組件
component:Content
},
{
path:'/main',
name:'main',
component: Main
}
]
});
- 在main.js中配置路由(import路由的時候路徑寫到文件夾即可,因為寫的是index.js會被默認掃描)
main.js
import Vue from 'vue'
import App from './App'
import router from './router' //自動掃描里面的路由配置
Vue.config.productionTip = false;
//顯示聲明引用VueRouter
new Vue({
el: '#app',
//配置路由
router,
components: { App },
template: '<App/>'
})
- 在
app.vue
中使用路由
<template>
<div id="app">
<!--
router-link:默認會被渲染成一個<a>標簽,to屬性為指定鏈接
router-view:用於渲染路由匹配到的組件
-->
<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>
- 通過命令
npm run dev
運行,通過瀏覽器進行訪問
Vue+Element小例子
1.創建工程
- 創建一個名為hello-vue的工程
vue init webpack hello-vue
- 安裝依賴,我們需要安裝vue-router、element-ui、sass-loader、node-sass四個插件
#進入工程目錄
cd hello-vue
#安裝vue-routern
npm install vue-router --save-dev
#安裝element-ui
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為該命令的縮寫
問題解決:
在最后npm run dev
的時候,出現sass版本問題
解決方案:將package.json
文件中的"sass-loader": "^7.3.1"
版本改成7.3.1
重新執行以下命令:
npm uninstall node-sass
npm i -D sass
-
用IDEA打開新建的項目,在src下新建routers、views文件夾
-
說明:
- assets:用於存放資源文件
- components:用於存放Vue功能組件
- views:用於存放Vue視圖組件
- router:用於存放vue-router配置
-
在views文件夾下新建Login.vue和Main.vue組件
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>
Main.vue
<template>
<h1>主頁</h1>
</template>
<script>
export default {
name: "Main"
}
</script>
<style scoped>
</style>
- 在routers文件夾下新建index.js文件
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',
name : 'main',
component: Main
},
{
path: '/login',
name: 'login',
component:Login
}
]
});
- 在main.js中配置路由
import Vue from 'vue'
import App from './App'
import router from './routers'
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) //ElementUI
})
2.路由嵌套
- 新建views下的子組件,user/List.vue、和/user/Profile.vue
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>
通過在路由配置組件中配置子元素children屬性,實現嵌套
index.js
import Vue from 'vue'
import Router from 'vue-router'
import Login from "../views/Login";
import Main from "../views/Main";
import Profile from "../views/user/Profile";
import List from "../views/user/List";
Vue.use(Router);
export default new Router({
routes: [
{
path : '/main',
name : 'main',
component: Main,
children:[ //子元素嵌套
{
path : '/user/list',
name : 'list',
component: List
},
{
path : '/user/profile',
name : 'profile',
component: Profile
}
]
},
{
path: '/login',
name: 'login',
component:Login
}
]
});
更新Main.vue中的內容為側邊欄樣式內容
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: #B3C0D1;
color: #333;
line-height: 60px;
}
.el-aside {
color: #333;
}
</style>
3.參數傳遞及重定向
參數傳遞方法1:
前端通過params傳遞,中間通過router接收,通過$router.params.id
展示
(1)前端通過to屬性傳遞參數(注意:要對to屬性進行雙向綁定)
name傳組件名,params傳遞參數,需要對象:v-bind
<router-link v-bind:to="{name: 'profile',params:{id:1}}">個人信息</router-link>
(2)通過路由(index.js)接收
routes: [
{
path : '/main',
name : 'main',
component: Main,
children:[
{
path : '/user/list',
name : 'list',
component: List
},
{
path : '/user/profile:id', //通過id接收(如果使用name傳參
//此處的:id可以不寫,但是在地址欄中沒辦法改變id 的值)
name : 'profile',
component: Profile
}
]
},
{
path: '/login',
name: 'login',
component:Login
}
]
(3)在Profile.vue中顯示傳遞的參數
注意:所有的元素不能直接在根節點下,必須至少有一個div標簽包裹,否則出錯
<template>
<div>
<h1>個人信息</h1>
{{$route.params.id}}
</div>
</template>
參數傳遞方法2:
使用props減少耦合
(1)前端通過to屬性傳遞參數(注意:要對to屬性進行v-bind綁定)
name傳組件名,params傳遞參數,需要對象:v-bind
<router-link :to="{name: 'profile',params:{id:1,name:'望穿先生',age:'22'}}">個人信息</router-link>
(2)通過路由(index.js)接收
在需要接收參數的路由后,新增屬性props:true
indes.js
routes: [
{
path : '/main',
name : 'main',
component: Main,
children:[
{
path : '/user/list',
name : 'list',
component: List
},
{
path : '/user/profile',
name : 'profile',
component: Profile,
props: true
}
]
},
{
path: '/login',
name: 'login',
component:Login
}
]
(3)在Profile.vue中顯示傳遞的參數
需要的Profile.vue接收參數並且在export中增加props屬性
注意:所有的元素不能直接在根節點下,必須至少有一個div標簽包裹,否則出錯
Profile.vue
<template>
<div>
<h1>個人信息</h1>
<ul>
<li>id:{{id}}</li>
<li>姓名:{{name}}</li>
<li>年齡:{{age}}</li>
</ul>
</div>
</template>
<script>
export default {
props:['id','name','age'],
name: "Profile"
}
</script>
重定向
Vue 中的重定向是作用在路徑不同但組件相同的情況
- 在router/index.js配置重定向路徑
index.js
routes: [
{
path : '/main',
name : 'main',
component: Main,
children:[
{
path : '/user/list',
name : 'list',
component: List
},
{
path : '/user/profile:id',
name : 'profile',
component: Profile,
props : true
}
]
},
{
path: '/login',
name: 'login',
component:Login
},
{
path: '/gohome',
redirect : '/main'
}
]
在前台加入鏈接
<router-link to="/gohome">返回首頁</router-link>
路由模式與404
路由模式有兩種
- hash:路徑帶 # 符號,如 http://localhost/#/login
- history:路徑不帶 # 符號,如 http://localhost/login
修改路由配置
index.js
export default new Router({
mode:'history',
routes: []
)}
在路由的配置中修改
路由鈎子
除了之前的鈎子函數還存在兩個鈎子函數
beforeRouteEnter:在進入路由前執行
beforeRouteLeave:在離開路由前執行
- 在 Profile.vue 使用
<script>
export default {
name: "UserProfile",
beforeRouteEnter: (to, from, next) => {
console.log("准備進入個人信息頁");
next();
},
beforeRouteLeave: (to, from, next) => {
console.log("准備離開個人信息頁");
next();
}
}
</script>
參數說明:
to:路由將要跳轉的路徑信息
from:路徑跳轉前的路徑信息
next:路由的控制參數
next() 跳入下一個頁面
next(’/path’) 改變路由的跳轉方向,使其跳到另一個路由
next(false) 返回原來的頁面
next((vm)=>{}) 僅在 beforeRouteEnter 中可用,vm 是組件實例
在鈎子函數中進行異步請求
- 安裝Axios
cnpm install --save vue-axios
- main.js引用 Axios
import axios from 'axios'
import VueAxios from 'vue-axios'
Vue.use(VueAxios, axios)
- 准備數據
data.json
{
"name": "望穿先生",
"url": "http://baidu.com",
"page": "1",
"isNonProfit": "true",
"address": {
"street": "含光門",
"city": "陝西西安",
"country": "中國"
},
"links": [
{
"name": "B站",
"url": "https://www.bilibili.com/"
},
{
"name": "4399",
"url": "https://www.4399.com/"
},
{
"name": "百度",
"url": "https://www.baidu.com/"
}
]
}
說明: 只有我們的 static 目錄下的文件是可以被訪問到的,所以我們就把靜態文件放入該目錄下
- 在 beforeRouteEnter 中進行異步請求
<script>
export default {
name: "UserProfile",
beforeRouteEnter: (to, from, next) => {
console.log("准備進入個人信息頁");
next(vm => {
//進入路由之前執行getData方法
vm.getData()
});
},
beforeRouteLeave: (to, from, next) => {
console.log("准備離開個人信息頁");
next();
},
//axios
methods: {
getData: function () {
this.axios({
method: 'get',
url: 'http://localhost:8080/static/mock/data.json'
}).then(function (response) {
console.log(response)
})
}
}
}
</script>
- 測試