狂神說 Vue 筆記
Vue 的核心庫只關注視圖層,方便與第三方庫或既有專案整合,
HTML + CSS + JS : 視圖 : 給用戶看,重繪后臺給的資料
網路通信 : axios
頁面跳轉 : vue-router
狀態管理:vuex
Vue-UI : ICE , Element UI
一、前端核心分析
1. VUE 概述
Vue (讀音/vju/, 類似于view)是一套用于構建用戶界面的漸進式框架,發布于2014年2月,與其它大型框架不同的是,Vue被設計為可以自底向上逐層應用,Vue的核心庫只關注視圖層,不僅易于上手,還便于與第三方庫(如: vue-router: 跳轉,vue-resource: 通信,vuex:管理)或既有專案整合
2. 前端三要素
-
HTML (結構) :超文本標記語言(Hyper Text Markup Language) ,決定網頁的結構和內容
-
CSS (表現) :層疊樣式表(Cascading Style sheets) ,設定網頁的表現樣式
-
JavaScript (行為) :是一種弱型別腳本語言,其源代碼不需經過編譯,而是由瀏覽器解釋運行,用于控制網頁的行為
-
3. JavaScript框架
-
jQuery: 大家熟知的JavaScript框架,優點是簡化了DOM操作,缺點是DOM操作太頻繁,影響前端性能;在前端眼里使用它僅僅是為了兼容IE6、7、8;
-
Angular: Google收購的前端框架,由一群Java程式員開發,其特點是將后臺的MVC模式搬到了前端并增加了模塊化開發的理念,與微軟合作,采用TypeScript語法開發;對后臺程式員友好,對前端程式員不太友好;最大的缺點是版本迭代不合理(如: 1代-> 2代,除了名字,基本就是兩個東西;截止發表博客時已推出了Angular6)
-
React: Facebook出品,一款高性能的JS前端框架;特點是提出了新概念[虛擬DOM]用于減少真實DOM操作,在記憶體中模擬DOM操作,有效的提升了前端渲染效率;缺點是使用復雜,因為需要額外學習一門[JSX] 語言;
-
Vue:一款漸進式JavaScript框架,所謂漸進式就是逐步實作新特性的意思,如實作模塊化開發、路由、狀態管理等新特性,其特點是綜合了Angular (模塊化)和React (虛擬DOM)的優點;
-
Axios :前端通信框架;因為Vue 的邊界很明確,就是為了處理DOM,所以并不具備通信能力,此時就需要額外使用一個通信框架與服務器互動;當然也可以直接選擇使用jQuery提供的AJAX通信功能;
前端三大框架:Angular、React、Vue
二、第一個Vue程式
1. 什么是MVVM
MVVM (Model-View-ViewModel) 是一種軟體架構設計模式,由微軟WPF (用于替代WinForm,以前就是用這個技術開發桌面應用程式的)和Silverlight (類似于Java Applet,簡單點說就是在瀏覽器上運行的WPF)的架構師Ken Cooper和Ted Peters 開發,是一種簡化用戶界面的事件驅動編程方式,由John Gossman (同樣也是WPF和Silverlight的架構師)于2005年在他的博客上發表,
MVVM 源自于經典的MVC (ModI-View-Controller) 模式,MVVM的核心是ViewModel層,負責轉換Model中的資料物件來讓資料變得更容易管理和使用,其作用如下:
-
該層向上與視圖層進行雙向資料系結
-
向下與Model層通過介面請求進行資料互動
![[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-dZfj6UVP-1595254922257)(D:\我\MyBlog\狂神說 VUE 筆記.assets\image-20200717215124290.png)]](https://img.uj5u.com/2022/03/16/304054160610171.png)
2. 為什么要使用MVVM
MVVM模式和MVC模式一樣,主要目的是分離視圖(View)和模型(Model),有幾大好處:
-
低耦合:視圖(View)可以獨立于Model變化和修改,一個ViewModel可以系結到不同的 View上,當View變化的時候Model可以不變,當Model變化的時候View也可以不變,
-
可復用:你可以把一些視圖邏輯放在一個ViewModel里面,讓很多View重用這段視圖邏輯,
-
獨立開發:開發人員可以專注于業務邏輯和資料的開發(ViewModel),設計人員可以專注于頁面設計,
-
可測驗:界面素來是比較難于測驗的,而現在測驗可以針對ViewModel來寫,
3. Vue 是 MVVM 模式的實作者
![[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-n9t7FtSN-1595254922262)(D:\我\MyBlog\狂神說 VUE 筆記.assets\image-20200717181433248.png)]](https://img-blog.csdnimg.cn/20200720222311692.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0RERERlbmdf,size_16,color_FFFFFF,t_70)
-
Model : 模型層,在這里表示JavaScript物件
-
View : 視圖層,在這里表示DOM (HTML操作的元素)
-
ViewModel : 連接視圖和資料的中間件,Vue.js就是MVVM中的ViewModel層的實作者在MVVM架構中,是不允許資料和視圖直接通信的,只能通過ViewModel來通信,而ViewModel就是定義了一個Observer觀察者
-
ViewModel 能夠觀察到資料的變化,并對視圖對應的內容進行更新
-
ViewModel 能夠監聽到視圖的變化,并能夠通知資料發生改變
至此,我們就明白了,Vue.js 就是一個MVVM的實作者,他的核心就是實作了DOM監聽與資料系結
Vue在線cdn:
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.min.js"></script>
1
三、Vue基本語法
1. v-bind
現在資料和DOM已經被建立了關聯,所有的東西都是回應式的,我們在控制臺操作物件的屬性,界面可以實時更新,
我們可以使用v-bind來系結元素屬性!
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<p>狂神說Java</p>
?
<!--view層 模板-->
<div id="app">
<span v-bind:title="message">滑鼠懸停幾秒鐘查看此處動態系結的提示資訊!</span>
</div>
</body>
?
<!--匯入js-->
<script src=https://www.cnblogs.com/wscsdn/p/"https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.min.js"></script>
<script>
var vm = new Vue({
el: "#app",
data: {
message: "hello,vue"
}
})
</script>
</html>
1234567891011121314151617181920212223242526
2. v-if v-else
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<p>狂神說Java</p>
?
<!--view層 模板-->
<div id="app">
<h1 v-if="type==='A'">A</h1>
<h1 v-else-if="type==='B'">B</h1>
<h1 v-else>C</h1>
</div>
</body>
?
<!--匯入js-->
<script src=https://www.cnblogs.com/wscsdn/p/"https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.min.js"></script>
<script>
var vm = new Vue({
el: "#app",
data: {
type: "A"
}
})
</script>
</html>
12345678910111213141516171819202122232425262728
3. v-for
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<p>狂神說Java</p>
?
<!--view層 模板-->
<div id="app">
<li v-for="item in items">
姓名:{{item.name}},年齡:{{item.age}}
</li>
</div>
</body>
?
<!--匯入js-->
<script src=https://www.cnblogs.com/wscsdn/p/"https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.min.js"></script>
<script>
var vm = new Vue({
el: "#app",
data: {
items: [
{name: "zhangsan", age: 12},
{name: "lisi", age: 10},
{name: "wangwu", age: 16}
]
}
})
</script>
</html>
1234567891011121314151617181920212223242526272829303132
4. v-on 事件系結
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<p>狂神說Java</p>
?
<!--view層 模板-->
<div id="app">
<button v-on:click="sayHi">Click Me</button>
</div>
</body>
?
<!--匯入js-->
<script src=https://www.cnblogs.com/wscsdn/p/"https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.min.js"></script>
<script>
var vm = new Vue({
el: "#app",
data: {
message: "你點我干嘛?"
},
methods: {
//方法必須系結在Vue的Methods物件中,v-on:事件
sayHi: (function (event) {
alert(this.message)
})
}
})
</script>
</html>
1234567891011121314151617181920212223242526272829303132
四、Vue雙向系結 v-model
1. 什么是雙向系結
Vue.js是一個MVVM框架,即資料雙向系結,即當資料發生變化的時候,視圖也就發生變化,當視圖發生變化的時候,資料也會跟著同步變化,這也算是Vue.js的精髓之處了,
值得注意的是,我們所說的資料雙向系結,一定是對于UI控制元件來說的,非UI控制元件不會涉及到資料雙向系結,單向資料系結是使用狀態管理工具的前提,如果我們使用vuex,那么資料流也是單項的,這時就會和雙向資料系結有沖突,
2. 為什么要實作資料的雙向系結
在Vue.js 中,如果使用vuex ,實際上資料還是單向的,之所以說是資料雙向系結,這是用的UI控制元件來說,對于我們處理表單,Vue.js的雙向資料系結用起來就特別舒服了,即兩者并不互斥,在全域性資料流使用單項,方便跟蹤;區域性資料流使用雙向,簡單易操作,
3. 在表單中使用雙向資料系結
你可以用v-model指令在表單 <input>、<textarea> 及<select> 元素上創建雙向資料系結,它會根據控制元件型別自動選取正確的方法來更新元素,盡管有些神奇,但v-model本質上不過是語法糖,它負責監聽戶的輸入事件以更新資料,并對一些極端場景進行一些特殊處理,
注意:v-model會忽略所有元素的value、checked、selected特性的初始值而總是將Vue實體的資料作為資料來源,你應該通過JavaScript在組件的data選項中宣告,
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
?
<!--view層 模板-->
<div id="app">
下拉框:
<select v-model="selected">
<option value=https://www.cnblogs.com/wscsdn/p/"" disabled>-請選擇-</option>
<option>A</option>
<option>B</option>
<option>C</option>
</select>
<p>value:{{selected}}</p>
</div>
</body>
?
<!--匯入js-->
<script src=https://www.cnblogs.com/wscsdn/p/"https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.min.js"></script>
<script>
var vm = new Vue({
el: "#app",
data: {
selected: ""
}
})
</script>
</html>
1234567891011121314151617181920212223242526272829303132
五、Vue組件
組件是可復用的Vue實體,說白了就是一組可以重復使用的模板,跟JSTL的自定義標簽、Thymeleaf的th:fragment 等框架有著異曲同工之妙,通常一個應用會以一棵嵌套的組件樹的形式來組織: ![[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-oSJ7c1GT-1595254922264)(D:\我\MyBlog\狂神說 VUE 筆記.assets\image-20200718095216872.png)]](https://img.uj5u.com/2022/03/16/304054160610172.png)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
?
<!--view層 模板-->
<div id="app">
<qinjiang v-for="item in items" v-bind:qin="item"></qinjiang>
</div>
</body>
?
<!--匯入js-->
<script src=https://www.cnblogs.com/wscsdn/p/"https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.min.js"></script>
<script>
Vue.component("qinjiang",{
props: ['qin'],
template: '<li>{{qin}}</li>'
})
?
var vm = new Vue({
el: "#app",
data: {
items: ['Java','Python','Php']
}
})
</script>
</html>
123456789101112131415161718192021222324252627282930
六、Axios通信
1. 什么是Axios
Axios是一個開源的可以用在瀏覽器端和NodeJS 的異步通信框架,她的主要作用就是實作AJAX異步通信,其功能特點如下:
-
從瀏覽器中創建
XMLHttpRequests -
從node.js創建http請求
-
支持Promise API [JS中鏈式編程]
-
攔截請求和回應
-
轉換請求資料和回應資料
-
取消請求
-
自動轉換JSON資料
-
客戶端支持防御XSRF (跨站請求偽造)
GitHub: https://github.com/ axios/axios 中文檔案: http://www.axios-js.com/
2. 為什么要使用Axios
由于Vue.js是一個視圖層框架且作者(尤雨溪) 嚴格準守SoC (關注度分離原則),所以Vue.js并不包含Ajax的通信功能,為了解決通信問題,作者單獨開發了一個名為vue-resource的插件,不過在進入2.0 版本以后停止了對該插件的維護并推薦了Axios 框架,少用jQuery,因為它操作Dom太頻繁 !
模擬Json資料:
{
"name": "weg",
"age": "18",
"sex": "男",
"url":"https://www.baidu.com",
"address": {
"street": "文苑路",
"city": "南京",
"country": "中國"
},
"links": [
{
"name": "bilibili",
"url": "https://www.bilibili.com"
},
{
"name": "baidu",
"url": "https://www.baidu.com"
},
{
"name": "cqh video",
"url": "https://www.4399.com"
}
]
}
12345678910111213141516171819202122232425
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<!--view層 模板-->
<div id="vue">
<div>{{info.name}}</div>
<a v-bind:href="info.url">點我進入</a>
</div>
</body>
?
<!--1.匯入vue.js-->
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.min.js"></script>
<!--匯入axios-->
<script src="https://cdn.bootcdn.net/ajax/libs/axios/0.19.2/axios.min.js"></script>
<script>
?
var vm = new Vue({
el: "#vue",
data: {
items: ['Java','Python','Php']
},
//data:vm的屬性
//data():vm方法
data(){
return{
//請求的回傳引數,必須和json字串一樣
info:{
name: null,
age: null,
sex: null,
url: null,
address: {
street: null,
city: null,
country: null
}
}
}
},
//鉤子函式,鏈式編程,ES6新特性
mounted(){
axios.get("../data.json").then(res => (this.info=res.data))
}
})
</script>
</html>
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950
3. Vue計算屬性
計算屬性的重點突出在屬性兩個字上(屬性是名詞),首先它是個屬性其次這個屬性有計算的能力(計算是動詞),這里的計算就是個函式;簡單點說,它就是一個能夠將計算結果快取起來的屬性(將行為轉化成了靜態的屬性),僅此而已;可以想象為快取!
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<!--view層 模板-->
<div id="app">
<div>currentTime1: {{currentTime1()}}</div>
<div>currentTime2: {{currentTime2}}</div>
</div>
</body>
<!--匯入js-->
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.min.js"></script>
<script>
var vm = new Vue({
el: "#app",
data: {
message: "hello,world!"
},
methods: {
currentTime1: function () {
return Date.now(); // 回傳一個時間戳
}
},
computed: {
//計算屬性:methods,computed 方法名不能重名,重名字后,只會呼叫methods的方法
currentTime2: function () {
this.message;
// 回傳一個時間戳
return Date.now();
}
}
})
</script>
</html>
123456789101112131415161718192021222324252627282930313233343536373839
結論: ?呼叫方法時,每次都需要進行計算,既然有計算程序則必定產生系統開銷,那如果這個結果是不經常變化的呢?此時就可以考慮將這個結果快取起來,采用計算屬性可以很方便的做到這一點,計算屬性的主要特性就是為了將不經常變化的計算結果進行快取,以節約我們的系統開銷;
七、內容分發 slot
在Vue.js中我們使用 元素作為承載分發內容的出口,作者稱其為插槽,可以應用在組合組件的場景中;
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
</head>
<body>
<div id="app">
<todo>
<todo-title slot="todo-title" v-bind:name="title"></todo-title>
<todo-items slot="todo-items" v-for="item in todoItems" v-bind:item="item"></todo-items>
</todo>
</div>
<!--1.匯入vue.js-->
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.min.js"></script>
<script>
//slot 插槽 這個組件要定義在前面不然出不來資料
Vue.component("todo", {
template: '<div>\
<slot name="todo-title"></slot>\
<ul>\
<slot name="todo-items"></slot>\
</ul>\
<div>'
});
Vue.component("todo-title", {
//屬性
props: ['name'],
template: '<div>{{name}}</div>'
});
Vue.component("todo-items", {
props: ['item'],
template: '<li>{{item}}</li>'
});
let vm = new Vue({
el: "#app",
data: {
//標題
title: "圖書館系列圖書",
//串列
todoItems: ['三國演義', '紅樓夢', '西游記', '水滸傳']
}
});
</script>
</body>
</html>
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647
八、自定義事件內容分發
通過以上代碼不難發現,資料項在Vue的實體中,但洗掉操作要在組件中完成,那么組件如何才能洗掉Vue實體中的資料呢?此時就涉及到引數傳遞與事件分發了,Vue為我們提供了自定義事件的功能很好的幫助我們解決了這個問題;
使用this.$emit (‘自定義事件名’,引數) ![[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-nYOsg3HY-1595254922312)(D:\我\MyBlog\狂神說 VUE 筆記.assets\image-20200718165535075.png)]](https://img-blog.csdnimg.cn/20200720222413865.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0RERERlbmdf,size_16,color_FFFFFF,t_70)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
</head>
<body>
<div id="app">
<todo>
<todo-title slot="todo-title" v-bind:name="title"></todo-title>
<todo-items slot="todo-items" v-for="(item,index) in todoItems" v-bind:item="item"
v-bind:index="index" v-on:remove="removeItems(index)"></todo-items>
</todo>
</div>
<!--1.匯入vue.js-->
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.min.js"></script>
<script>
//slot 插槽 這個組件要定義在前面不然出不來資料
Vue.component("todo", {
template: '<div>\
<slot name="todo-title"></slot>\
<ul>\
<slot name="todo-items"></slot>\
</ul>\
<div>'
});
Vue.component("todo-title", {
//屬性
props: ['name'],
template: '<div>{{name}}</div>'
});
Vue.component("todo-items", {
props: ['item','index'],
template: '<li>{{index}}---{{item}} <button @click="remove">洗掉</button></li>',
methods: {
remove: function (index) {
// this.$emit 自定義事件分發
this.$emit('remove',index)
}
}
});
let vm = new Vue({
el: "#app",
data: {
//標題
title: "圖書館系列圖書",
//串列
todoItems: ['三國演義', '紅樓夢', '西游記', '水滸傳']
},
methods: {
removeItems: function (index) {
console.log("洗掉了"+this.todoItems[index]+"OK");
this.todoItems.splice(index,1);
}
}
});
</script>
</body>
</html>
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859
九、第一個vue-cli專案
1. 什么是vue-cli
vue-cli 官方提供的一個腳手架,用于快速生成一個 vue 的專案模板;
預先定義好的目錄結構及基礎代碼,就好比咱們在創建 Maven 專案時可以選擇創建一個骨架專案,這個骨架專案就是腳手架,我們的開發更加的快速;
主要功能:
-
統一的目錄結構
-
本地除錯
-
熱部署
-
單元測驗
-
集成打包上線
2. 需要的環境
-
Node.js : http://nodejs.cn/download/
安裝就無腦下一步就好,安裝在自己的環境目錄下
-
Git : https://git-scm.com/downloads 鏡像:https://npm.taobao.org/mirrors/git-for-windows/
確認nodejs安裝成功:
-
cmd 下輸入
node -v,查看是否能夠正確列印出版本號即可! -
cmd 下輸入
npm-v,查看是否能夠正確列印出版本號即可!
這個npm,就是一個軟體包管理工具,就和linux下的apt軟體安裝差不多!
npm 是 JavaScript 世界的包管理工具,并且是 Node.js 平臺的默認包管理工具,通過 npm 可以安裝、共享、分發代碼,管理專案依賴關系,
安裝 Node.js 淘寶鏡像加速器(cnpm)
這樣子的話,下載會快很多~
# -g 就是全域安裝
npm install cnpm -g
# 若安裝失敗,則將源npm源換成淘寶鏡像
# 因為npm安裝插件是從國外服務器下載,受網路影響大
npm config set registry https://registry.npm.taobao.org
# 然后再執行
npm install cnpm -g
123456789
安裝的位置:C:\Users\Administrator\AppData\Roaming\npm
3. 安裝vue-cli
#在命令臺輸入
cnpm install vue-cli -g
#查看是否安裝成功
vue list
1234
4. 第一個 vue-cli 應用程式
創建一個Vue專案,我們隨便建立一個空的檔案夾在電腦上,
我這里在D盤下新建一個目錄D:\Project\vue-study;
創建一個基于 webpack 模板的 vue 應用程式
# 這里的 myvue 是專案名稱,可以根據自己的需求起名
vue init webpack myvue
12
一路都選擇no即可;
初始化并運行
cd myvue
npm install
npm run dev
123
執行完成后,目錄多了很多依賴 ![[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-y4pwU8CT-1595254922314)(D:\我\MyBlog\狂神說 VUE 筆記.assets\image-20200719103326926.png)]](https://img-blog.csdnimg.cn/20200720222444717.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0RERERlbmdf,size_16,color_FFFFFF,t_70)
十、Webpack
WebPack 是一款模塊加載器兼打包工具,它能把各種資源,如 JS、JSX、ES6、SASS、LESS、圖片等都作為模塊來處理和使用,
npm install webpack -g
npm install webpack-cli -g
12
測驗安裝成功: 輸入以下命令有版本號輸出即為安裝成功
webpack -v
webpack-cli -v
12
1. 什么是Webpack
本質上,webpack是一個現代JavaScript應用程式的靜態模塊打包器(module bundler),當webpack處理應用程式時,它會遞回地構建一個依賴關系圖(dependency graph),其中包含應用程式需要的每個模塊,然后將所有這些模塊打包成一個或多個bundle. ?Webpack是當下最熱門的前端資源模塊化管理和打包工具,它可以將許多松散耦合的模塊按照依賴和規則打包成符合生產環境部署的前端資源,還可以將按需加載的模塊進行代碼分離,等到實際需要時再異步加載,通過loader轉換,任何形式的資源都可以當做模塊,比如CommonsJS、AMD、ES6、 CSS、JSON、CoffeeScript、LESS等; ?伴隨著移動互聯網的大潮,當今越來越多的網站已經從網頁模式進化到了WebApp模式,它們運行在現代瀏覽器里,使用HTML5、CSS3、ES6 等新的技術來開發豐富的功能,網頁已經不僅僅是完成瀏覽器的基本需求; WebApp通常是一個SPA (單頁面應用) ,每一個視圖通過異步的方式加載,這導致頁面初始化和使用程序中會加載越來越多的JS代碼,這給前端的開發流程和資源組織帶來了巨大挑戰, ?前端開發和其他開發作業的主要區別,首先是前端基于多語言、多層次的編碼和組織作業,其次前端產品的交付是基于瀏覽器的,這些資源是通過增量加載的方式運行到瀏覽器端,如何在開發環境組織好這些碎片化的代碼和資源,并且保證他們在瀏覽器端快速、優雅的加載和更新,就需要一個模塊化系統,這個理想中的模塊化系統是前端工程師多年來一直探索的難題,
2. 使用Webpack
-
先創建一個包 交由idea打開 會生成一個.idea檔案 那么就說明該檔案就交由idea負責
-
在idea中創建modules包,再創建hello.js,hello.js 暴露介面 相當于Java中的類
//暴露一個方法
exports.sayHi = function () {
document.write("<h1>狂神說ES6</h1>>")
}
1234 -
創建main.js 當作是js主入口 , main.js 請求hello.js 呼叫sayHi()方法
var hello = require("./hello");
hello.sayHi()
12 -
在主目錄創建webpack-config.js , webpack-config.js 這個相當于webpack的組態檔
enrty請求main.js的檔案
output是輸出的位置和名字
module.exports = {
entry: './modules/main.js',
output: {
filename: './js/bundle.js'
}
}
123456 -
在idea命令臺輸入webpack命令(idea要設定管理員啟動)
-
完成上述操作之后會在主目錄生成一個dist檔案 生成的js檔案夾路徑為/ dist/js/bundle.js
-
在主目錄創建index.html 匯入bundle.js index.html
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://www.cnblogs.com/wscsdn/p/dist/js/bundle.js"></script>
</head>
<body>
</body>
</html>
123456789

十一、vue-router路由
Vue Router是Vue.js官方的路由管理器(路徑跳轉),它和Vue.js的核心深度集成,讓構建單頁面應用變得易如反掌,包含的功能有:
-
嵌套的路由/視圖表
-
模塊化的、基于組件的路由配置
-
路由引數、查詢、通配符
-
基于Vue.js過渡系統的視圖過渡效果
-
細粒度的導航控制
-
帶有自動激活的CSS class的鏈接
-
HTML5歷史模式或hash模式,在IE9中自動降級
-
自定義的滾動條行為
1. 安裝
基于第一個vue-cli進行測驗學習;先查看node_modules中是否存在 vue-router ?vue-router 是一個插件包,所以我們還是需要用 npm/cnpm 來進行安裝的,打開命令列工具,進入你的專案目錄,輸入下面命令,
npm install vue-router --save-dev
1
安裝完之后去node_modules路徑看看是否有vue-router資訊 有的話則表明安裝成功,
2. vue-router demo實體
-
將之前案例由vue-cli生成的案例用idea打開
-
清理不用的東西 assert下的logo圖片 component定義的helloworld組件 我們用自己定義的組件
-
清理代碼 以下為清理之后的代碼 src下的App.vue 和main.js以及根目錄的index.html 這三個檔案的關系是
index.html呼叫main.js呼叫App.vueindex.html:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<title>myvue</title>
</head>
<body>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>
123456789101112main.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/>'
})
12345678910111213App.vue:
<template>
<div id="app">
<img src="https://img.uj5u.com/2022/03/16/304054160610173.png">
<h1>迪師傅</h1>
<router-link to="/main">首頁</router-link>
<router-link to="/content">內容頁</router-link>
<router-link to="/kuang">Kuang</router-link>
<router-view></router-view>
</div>
</template>
<script>
export default {
name: 'App',
components: {
}
}
</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>
1234567891011121314151617181920212223242526272829303132 -
在components目錄下創建一個自己的組件Content,Test,Main(這兩個和Content內容一樣的就不放示例代碼了
Content.vue:
<template>
<h1>內容</h1>
</template>
<script>
export default {
name: "Content"
}
</script>
<style scoped>
</style>
12345678910111213
-
安裝路由,在src目錄下,新建一個檔案夾 : router,專門存放路由 index.js(默認組態檔都是這個名字)
import Vue from "vue";
import VueRouter from "vue-router";
import Content from "../components/Content";
import Main from "../components/Main";
import Kuang from "../components/Kuang";
//安裝路由
Vue.use(VueRouter);
//配置匯出路由
export default new VueRouter({
routes: [
{
//路由路徑
path: '/content',
name: 'content',
//跳轉的組件
component: Content
},
{
//路由路徑
path: '/main',
name: 'main',
//跳轉的組件
component: Main
},
{
//路由路徑
path: '/kuang',
name: 'kuang',
//跳轉的組件
component: Kuang
}
]
})
1234567891011121314151617181920212223242526272829303132333435 -
在main.js中配置路由
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/>'
})
12345678910111213 -
在App.vue中使用路由
App.vue:
<template>
<div id="app">
<img src="https://img.uj5u.com/2022/03/16/304054160610173.png">
<h1>迪師傅</h1>
<router-link to="/main">首頁</router-link>
<router-link to="/content">內容頁</router-link>
<router-link to="/kuang">Kuang</router-link>
<router-view></router-view>
</div>
</template>
<script>
export default {
name: 'App',
components: {
}
}
</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>
1234567891011121314151617181920212223242526272829303132 -
啟動測驗一下 : npm run dev
-
專案結構圖&運行效果圖

十二、vue + ElementUI
根據之前創建vue-cli專案一樣再來創建一個新專案
-
創建一個名為 hello-vue 的工程
vue init webpack hello-vue
1 -
安裝依賴,我們需要安裝
vue-router、element-ui、sass-loader和node-sass四個插件
# 進入工程目錄
cd hello-vue
# 安裝 vue-router
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
123456789101112
-
Npm命令解釋
-
npm install moduleName:安裝模塊到專案目錄下 -
npm install -g moduleName:-g 的意思是將模塊安裝到全域,具體安裝到磁盤的哪個位置,要看 npm config prefix的位置 -
npm install moduleName -save:–save的意思是將模塊安裝到專案目錄下,并在package檔案的dependencies節點寫入依賴,-S為該命令的縮寫 -
npm install moduleName -save-dev:–save-dev的意思是將模塊安裝到專案目錄下,并在package檔案的devDependencies節點寫入依賴,-D為該命令的縮寫
-
-
創建成功后用idea打開,并洗掉凈東西 創建views和router檔案夾用來存放視圖和路由

-
在views創建Main.vue
Main.vue:
<template>
<h1>首頁</h1>
</template>
<script>
export default {
name: "Main"
}
</script>
<style scoped>
</style>
12345678910 -
在views中創建Login.vue視圖組件
Login.vue:(用的ElementUI中的代碼)
<template>
<div>
<el-form ref="loginForm" :model="form" :rules="rules" label- >
<h3 >歡迎登錄</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"
:before-close="handleClose">
<span>請輸入賬號和密碼</span>
<span slot="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>
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
-
創建路由
在 router 目錄下創建一個名為 index.js 的 vue-router 路由組態檔
index.js:
import Vue from "vue";
import Router from "vue-router";
import Main from "../views/Main";
import Login from "../views/Login";
Vue.use(Router);
export default new Router({
routes: [
{
path: '/main',
component: Main
},
{
path: '/login',
component: Login
}
]
});
12345678910111213141516171819 -
在main.js中配置相關
main.js是index.html呼叫的 所以前面注冊的組件要在這里匯入
一定不要忘記掃描路由配置并將其用到new Vue中
main.js:
import Vue from 'vue'
import App from './App'
//掃描路由配置
import router from './router'
//匯入elementUI
import ElementUI from "element-ui"
//匯入element css
import 'element-ui/lib/theme-chalk/index.css'
Vue.use(router);
Vue.use(ElementUI)
new Vue({
el: '#app',
router,
render: h => h(App),//ElementUI規定這樣使用
})
1234567891011121314151617 -
在App.vue中配置顯示視圖
App.vue :
<template>
<div id="app">
<router-link to="/login">login</router-link>
<router-view></router-view>
</div>
</template>
<script>
export default {
name: 'App',
}
</script>
1234567891011 -
測驗運行
npm run dev
1

> 測驗:在瀏覽器打開 http://localhost:8080/#/login
> 如果出現錯誤: 可能是因為sass-loader的版本過高導致的編譯錯誤,當前最高版本是8.0.2,需要退回到7.3.1 ;
> 去package.json檔案里面的 "sass-loader"的版本更換成7.3.1,然后重新cnpm install就可以了;
123
十三、路由嵌套
嵌套路由又稱子路由,在實際應用中,通常由多層嵌套的組件組合而成,
Demo
-
創建用戶資訊組件,在 views/user 目錄下創建一個名為 Profile.vue 的視圖組件;
Profile.vue
<template>
<h1>個人資訊</h1>
</template>
<script>
export default {
name: "UserProfile"
}
</script>
<style scoped>
</style>
12345678910 -
在用戶串列組件在 views/user 目錄下創建一個名為 List.vue 的視圖組件;
List.vue
<template>
<h1>用戶串列</h1>
</template>
<script>
export default {
name: "UserList"
}
</script>
<style scoped>
</style>
12345678910 -
修改首頁視圖,我們修改 Main.vue 視圖組件,此處使用了 ElementUI 布局容器組件,代碼如下:
Main.vue
<template>
<div>
<el-container>
<el-aside >
<el-menu :default-openeds="['1']">
<el-submenu index="1">
<template slot="title"><i ></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 ></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 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 {
color: #333;
line-height: 60px;
}
.el-aside {
color: #333;
}
</style>
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
-
配置嵌套路由修改 router 目錄下的 index.js 路由組態檔,使用children放入main中寫入子模塊,代碼如下
index.js
import Vue from "vue";
import Router from "vue-router";
import Main from "../views/Main";
import Login from "../views/Login";
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
}
]
});
1234567891011121314151617181920212223242526 -
路由嵌套效果圖

十四、引數傳遞
1. Demo
-
前端傳遞引數
此時我們在Main.vue中的route-link位置處 to 改為了 :to,是為了將這一屬性當成物件使用,注意 router-link 中的 name 屬性名稱 一定要和 路由中的 name 屬性名稱 匹配,因為這樣 Vue 才能找到對應的路由路徑;
<!--name:傳組件名 params:傳遞引數,需要系結物件:v-bind-->
<router-link v-bind:to="{name: 'UserProfile', params: {id: 1}}">個人資訊</router-link>
12 -
修改路由配置,增加props:true屬性
主要是router下的index.js中的 path 屬性中增加了 :id 這樣的占位符
{
path: '/user/profile/:id',
name: 'UserProfile',
component: UserProfile,
props:true
}
123456 -
前端顯示
在要展示的組件Profile.vue中接收引數
Profile.vue:
<template>
<div>
個人資訊
{{ id }}
</div>
</template>
<script>
export default {
props: ['id'],
name: "UserProfile"
}
</script>
<style scoped>
</style>
1234567891011121314 -
運行

2. 組件重定向
重定向的意思大家都明白,但 Vue 中的重定向是作用在路徑不同但組件相同的情況下,比如: ? 在router下面index.js的配置
{
path: '/main',
name: 'Main',
component: Main
},
{
path: '/goHome',
redirect: '/main'
}
123456789
說明:這里定義了兩個路徑,一個是 /main ,一個是 /goHome,其中 /goHome 重定向到了 /main 路徑,由此可以看出重定向不需要定義組件;
使用的話,只需要在Main.vue設定對應路徑即可;
<el-menu-item index="1-3">
<router-link to="/goHome">回到首頁</router-link>
</el-menu-item>
123
十五、路由鉤子與異步請求
1. 路由模式與 404
路由模式有兩種
-
hash:路徑帶 # 符號,如 http://localhost/#/login
-
history:路徑不帶 # 符號,如 http://localhost/login
修改路由配置,代碼如下:
export default new Router({
mode: 'history',
routes: [
]
});
12345404界面:
-
創建一個NotFound.vue視圖組件
<template>
<div>
<h1>404,你的頁面走丟了</h1>
</div>
</template>
<script>
export default {
name: "NotFound"
}
</script>
<style scoped>
</style>
123456789101112 -
修改路由配置index.js
import NotFound from '../views/NotFound'
{
path: '*',
component: NotFound
}
12345
-
2. 路由鉤子與異步請求
beforeRouteEnter:在進入路由前執行 beforeRouteLeave:在離開路由前執行
在Profile.vue中寫:
export default {
name: "UserProfile",
beforeRouteEnter: (to, from, next) => {
console.log("準備進入個人資訊頁");
next();
},
beforeRouteLeave: (to, from, next) => {
console.log("準備離開個人資訊頁");
next();
}
}
1234567891011
引數說明:
-
to:路由將要跳轉的路徑資訊
-
from:路徑跳轉前的路徑資訊
-
next:路由的控制引數
-
next() 跳入下一個頁面
-
next(’/path’) 改變路由的跳轉方向,使其跳到另一個路由
-
next(false) 回傳原來的頁面
-
next((vm)=>{}) 僅在 beforeRouteEnter 中可用,vm 是組件實體
3. 在鉤子函式中使用異步請求
-
安裝 Axios
cnpm install --save vue-axios
1 -
main.js參考 Axios
import axios from 'axios'
import VueAxios from 'vue-axios'
Vue.use(VueAxios, axios)
123 -
準備資料 : 只有我們的 static 目錄下的檔案是可以被訪問到的,所以我們就把靜態檔案放入該目錄下, 資料和之前用的json資料一樣 需要的去上述axios例子里
// 靜態資料存放的位置
static/mock/data.json
12 -
在 beforeRouteEnter 中進行異步請求
Profile.vue:
export default {
//第二種取值方式
// props:['id'],
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)
})
}
}
}
1234567891011121314151617181920212223242526272829 -
執行
javascript export default {undefined name: “UserProfile”, beforeRouteEnter: (to, from, next) => {undefined console.log(“準備進入個人資訊頁”); next(); }, beforeRouteLeave: (to, from, next) => {undefined console.log(“準備離開個人資訊頁”); next(); } }
==**引數說明:**==
- to:路由將要跳轉的路徑資訊
- from:路徑跳轉前的路徑資訊
- next:路由的控制引數
- next() 跳入下一個頁面
- next(’/path’) 改變路由的跳轉方向,使其跳到另一個路由
- next(false) 回傳原來的頁面
- next((vm)=>{}) 僅在 beforeRouteEnter 中可用,vm 是組件實體
### 3. 在鉤子函式中使用異步請求
1. 安裝 Axios
12345678910111213141516171819
cnpm install --save vue-axios
2. main.js參考 Axios
```javascript
import axios from 'axios'
import VueAxios from 'vue-axios'
Vue.use(VueAxios, axios)
1234567
-
準備資料 : 只有我們的 static 目錄下的檔案是可以被訪問到的,所以我們就把靜態檔案放入該目錄下, 資料和之前用的json資料一樣 需要的去上述axios例子里
// 靜態資料存放的位置
static/mock/data.json
12 -
在 beforeRouteEnter 中進行異步請求
Profile.vue:
export default {
//第二種取值方式
// props:['id'],
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)
})
}
}
}
1234567891011121314151617181920212223242526272829 -
執行
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/444310.html
標籤:Java
上一篇:Swing
下一篇:Linux常用檔案管理命令詳解
