一 前言
最近找了些教程,順帶著趴在官網上,看了看 Vue 的一些內容,入門的一些概念,以及基礎語法,還有一些常用的操作,瞄了一眼,通篇文字+貼了部分程式碼 9000 多字,入門語法什麼的還是很好理解的,以前也有一定做小程式的基礎,感覺還是很相似的,不過對於一些稍複雜的點,感覺還是總結的不夠細緻,例如插槽,和計算屬性等,平時前端的東西看的也不是很多,學習過程中整理的筆記,和大家一起分享交流!歡迎各位大大交流意見~
二 初始 Vue
(一) Vue 概念理解
(1) Vue.js 是什麼
Vue (讀音 /vjuː/,類似於 view) 是一套用於構建使用者介面的漸進式框架。與其它大型框架不同的是,Vue 被設計為可以自底向上逐層應用。Vue 的核心庫只關注檢視層,不僅易於上手,還便於與第三方庫或既有專案整合。
(2) 漸進式框架是什麼
看了一些教程以及文章,簡單理解的漸進式框架就三個字【不強求】,Vue並不強求你用它的所有內容(功能特性),使用者完全可以根據自己情況進行選擇,使用其部分即可。
這一塊某乎上有一個比較好的答案,很容易度娘到,貼了部分
vue即主張較少,也就是說可以在原有系統上面,引入vue直接就可以當jquery用,使用 vue,你可以在原有大系統的上面,把一兩個元件改用它實現,當 jQuery 用;也可以整個用它全家桶開發
(二) MVVM 架構
正式學習 Vue 前我們首先還需要了解一個基於前端的架構模式,也就是 MVVM ,它是 Model-View-ViewMode 的簡寫,其關係簡單的描述為下圖:
-
Model(模型層):表示 Javascript 資料物件
-
View(檢視層):表示 DOM,也可以簡單理解為前端展示的內容
-
ViewModel:連線檢視和資料,即用於雙向繫結資料與頁面
在 MVVM 架構中,檢視和資料是沒有辦法直接進行溝通的,只能通過 ViewModel 來做一箇中間關係,ViewModel 可以觀察到資料的變化,然後更新檢視內容,亦或者監聽到檢視的變化,並能通知資料發生改變
後面我馬上會寫一個入門的小案例,可以一起來體會一下它的特點!
(三) Vue 的優點
1、體積小
- 壓縮後33K
2、更高的執行效率
- 基於虛擬dom一種可以預先通過 javascript 進行各種計算,把最終的 DOM操作計算出來並優化的技術,由於這個DOM操作屬於預處理操作,並沒有真實的操作DOM,所以 叫做虛擬DOM。
3、雙向資料繫結
- 讓開發者不用再去操作 dom 物件,把更多的精力投入到業務邏輯上
4、生態豐富、學習成本低
- 市場上擁有大量成熟、穩定的基於 vue.js 的 ui 框架、常用元件!
- 拿來即用實現快速開發
- 對初學者友好、入門容易、學習資料多
(四) 入門案例
編寫 Vue 你可以選擇使用 Vscode 、 HBuilder 、sublime、Webstrom、甚至 IDEA 都是可以的,自行選擇就好了
首先我們需要引入 Vue,你可以去官網直接 down 下檔案,進行一個本地的引入,類似引入 jQuery,或者使用一個網路的引用,例如下文中,在官網中就可以找到這種引入或下載的地址
可以看到,引入後,我們通過 new 的這種形式建立了一個 Vue 的例項,其中通過 el 找到 id 值為 hello 的 div 進行繫結,在 data 中進行一個賦值,而在div 中 通過兩組大括號來對資料進行回顯
如果你有一些微信小程式的基礎的話,其實可以發現,這兩者結構看起來似乎有一些相似的
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="hello">
<h2>{{content}}</h2>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.11"></script>
<script>
var vm = new Vue({
el: "#hello",
data:{
content: "Hello Vue!"
}
})
</script>
</body>
</html>
回顯資料肯定是沒問題的,我們試著在控制檯修改 content 的值,可以看到隨之頁面也就發生改變了
我們已經成功建立了第一個 Vue 應用!看起來這跟渲染一個字串模板非常類似,但是 Vue 在背後做了大量工作。現在資料和 DOM 已經被建立了關聯,所有東西都是響應式的。我們要怎麼確認呢?開啟你的瀏覽器的 JavaScript 控制檯 (就在這個頁面開啟),並修改
app.message
的值,你將看到上例相應地更新。注意我們不再和 HTML 直接互動了。一個 Vue 應用會將其掛載到一個 DOM 元素上 (對於這個例子是
#app
) 然後對其進行完全控制。那個 HTML 是我們的入口,但其餘都會發生在新建立的 Vue 例項內部。—— Vue 官網
三 Vue 基本語法
(一) 宣告式渲染
如果有接觸過 Thymeleaf 這樣的模板,你可以看出來,上面的 Vue 案例就是採用了一個簡潔模板語法,即兩組大括號包裹值,來宣告式宣告式地將資料渲染進 DOM 的系統,這其實和 Thymeleaf 中的 $ 加一組大括號 是相似的
我們還有一種繫結元素的方式:即使用指令
<div id="hello-2">
<span v-bind:title="content">
滑鼠懸停幾秒鐘檢視此處動態繫結的提示資訊!
</span>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.11"></script>
<script>
var vm = new Vue({
el: "#hello-2",
data:{
content: '頁面載入於 ' + new Date().toLocaleString()
}
})
</script>
觀察結果,我們將滑鼠懸停在文字上方,被繫結的資料就會出現
你看到的 v-bind
attribute 被稱為指令。指令帶有字首 v-
,以表示它們是 Vue 提供的特殊 attribute,程式碼的意思就是將這個元素節點的 title
attribute 和 Vue 例項的 content
property 保持一致”
如果你在控制檯進行修改 vm.content 的值,繫結的資料依舊會發生變化
注:使用 v-bind 需要頭部引入一個約束
<html lang="en" xmlns:v-bind="http://www.w3.org/1999/xhtml">
如果使用 IDEA 安裝 Vue.js 外掛 會有提示補全
(二) 條件判斷
條件判斷使用的指令就是 v-if
、v-else-if
、v-else
來看兩個例子,首先是對於 true 或者 false 的判斷
<div id="hello-3">
<h2 v-if="isBoy">是男孩</h2>
<h2 v-else>是女孩</h2>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.11"></script>
<script>
var vm = new Vue({
el: "#hello-3",
data:{
isBoy: true
}
})
</script>
預設顯示是男孩,我們接著在控制檯修改為false
接著是對於值的判斷,我們拿一個比較成績的小例子,不過對數值的約束還是不夠嚴謹的,僅僅為了講解 if 這個例子,明白意思就行
<div id="hello-3">
<h2 v-if="score < '60'">成績不及格</h2>
<h2 v-else-if="score >= '60' && score < '80'">成績及格</h2>
<h2 v-else>成績優秀</h2>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.11"></script>
<script>
var vm = new Vue({
el: "#hello-3",
data:{
score: 66
}
})
</script>
在結果中繼續修改看看
(三) 迴圈
通過 v-for
就可以進行迴圈遍歷,真例如 java 中的 增強for 只不過是把 冒號 換成了 in,students 對應 data 中的陣列名,student 代表其中的每一項,通過 XXX.xx 的形式取出具體的屬性值
<div id="hello-4">
<li v-for="student in students">
{{student.name}}
</li>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.11"></script>
<script>
var vm = new Vue({
el: "#hello-4",
data: {
students: [{name: '張三'}, {name: '李四'}, {name: '王五'}]
}
})
</script>
試著在控制檯 push 一個新的,同樣會更新出來
說明:這裡演示的只是最基本的一種情況,很多時候,若遍歷的陣列中為物件,且物件有多個值,例如含有 id 這樣的值,一般會將這種唯一的 id 值作為 key 值,例如:
<div v-for="item in items" v-bind:key="item.id">
<!-- 內容 -->
</div>
為了給 Vue 一個提示,以便它能跟蹤每個節點的身份,從而重用和重新排序現有元素,你需要為每項提供一個唯一
key
attribute:建議儘可能在使用
v-for
時提供key
attribute,除非遍歷輸出的 DOM 內容非常簡單,或者是刻意依賴預設行為以獲取效能上的提升。
(四) 事件繫結
經常我們需要通過點選一些按鈕或者標籤元件等,使得使用者可以與應用進行互動,也就是進行事件繫結,在 Vue 中我們可以通過 v-on
指令新增一個事件監聽器來進行
注:使用 v-on 引入約束
<html lang="en" xmlns:v-on="http://www.w3.org/1999/xhtml">
示例程式碼
<div id="hello-5">
<button v-on:click="helloWorld">你好世界</button>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.11"></script>
<script>
var vm = new Vue({
el: "#hello-5",
data: {
content: "Hello World !"
},
methods: {
helloWorld: function () {
alert(this.content);
}
}
})
</script>
可以看到,通過 v-on:click
就將 helloWorld 這個事件繫結了,而事件的具體邏輯需要定義在 Vue 物件的 methods 中
(五) 雙向繫結
早在開篇介紹 MVVM 架構模式的時候,圖中就提到了 View 和 ViewModel 之間的雙向繫結,通俗的說就是:當資料發生變化時,檢視也變化,而當檢視發生變化的時候,資料也跟著變化
其實在前面的基本語法中,我們已經能很明顯的體會到了前半句,即修改 data 中的資料,從而引起檢視中的變化,我們這裡就重點提一下後半句
首先,Vue 提供了 v-model
指令,它能輕鬆實現表單輸入和應用狀態之間的雙向繫結
從常見的表單中的幾種形式來講,我們可以使用 v-model
指令在表單的 input
、textarea>
、select
等上進行資料的雙向繫結,它可以根據控制元件型別選取正確的方法來更新元素
不過使用 v-model
指令後會忽略表單原先的 value、checked、selected 等的初始值,而總將 Vue 例項中的資料最為資料來源
input 中 ,輸入文字
<div id="hello-6">
輸入: <input type="text" v-model="content" > 輸出: {{content}}
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.11"></script>
<script>
var vm = new Vue({
el: "#hello-6",
data: {
content: "Hello World !"
},
})
</script>
在輸出的位置使用兩組大括號進行 content 這個值的回顯我們之前就已經能做到了,而我們在 input 的屬性中使用 v-model 進行對於 content 的繫結,這樣就可以使得輸入框中輸入的值可以直接影響 data 中 content 的值,即隨著你 input 中輸入值的修改,隨之輸出位置的內容也會變化
input 中 ,單選框
<div id="hello-6">
性別:
<input type="radio" name="gender" value="男" v-model="gender">男
<input type="radio" name="gender" value="女" v-model="gender">女
輸出: {{gender}}
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.11"></script>
<script>
var vm = new Vue({
el: "#hello-6",
data: {
gender: '男'
},
})
</script>
效果顯示
select 中
<div id="hello-6">
<select v-model="choose">
<option value="" disabled>---請選擇---</option>
<option>A-蘋果</option>
<option>B-櫻桃</option>
<option>C-西瓜</option>
</select>
輸出: {{choose}}
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.11"></script>
<script>
var vm = new Vue({
el: "#hello-6",
data: {
choose: ''
},
})
</script>
(六) Vue元件
Vue 中元件也是一個很重要的概念,例如一個頁面中,頭部、底部、側邊欄、主內容區 都可以看做一個一個元件,不過有一些元件是固定的,例如頭部,還有一些是變換的例如內容區
Vue 中就允許我們使用小型、獨立和通常可複用的元件構建大型應用
注:實際都是建立 .vue 模板檔案,並不會用直接在頁面中書寫的這種形式,僅為講解方便
直接拿一個簡單,不過還算相對完善的案例來進行講解‘
先說一下最終我們想幹嘛,例如 div 或者 input 等等 都是一個一個標籤,我們現在向做的就是通過建立自定義元件模板,自定義出一個這樣的標籤,我們在需要的地方只需要引用這個標籤,我們就可以達到顯示出模板中想要的效果,達到抽取複用的效果
首先使用 Vue.component....... 這樣的格式建立元件,在其中 ideal-20 就是元件標籤的名字, template 就代表模板中的內容,props 代表我們在引用處傳入的引數名
接著在一個已經繫結好的 hello-7 的 div 中引入自定義元件標籤 ideal-20,而我們想要遍歷 data 中的 fruits 陣列,在 ideal-20 屬性中進行 for 遍歷即可,同時我們需要將每一項通過 v-bind:ideal="item"
繫結引數到元件模板中,因為陣列不是一個普通的陣列,所以賦 id 為 key值
<div id="hello-7">
<ideal-20 v-for="item in fruits" v-bind:ideal="item" v-bind:key="item.id"></ideal-20>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.11"></script>
<script>
// 定義名為 todo-item 的新元件
Vue.component('ideal-20', {
props: ['ideal'],
template: '<li>{{ideal.name}}</li>'
})
var vm = new Vue({
el: "#hello-7",
data: {
fruits: [
{id: 0, name: '蘋果'},
{id: 1, name: '櫻桃'},
{id: 2, name: '山竹'}
]
}
})
</script>
效果展示
(七) Axios 入門
首先我們需要提一下,為什麼要用這個東西呢?
我們在以前傳統的開發中,我們一般會使用 Ajax 進行通訊,而 Vue,js 作為一個檢視層框架,並不支援 Ajax 的通訊功能,所以可以使用 Axios 來實現 Ajax 的非同步通訊
首先看一下它的特點:
- 從瀏覽器中建立 XMLHttpRequests
- 從 node.js 建立 http 請求
- 支援 Promise API
- 攔截請求和響應
- 轉換請求資料和響應資料
- 取消請求
- 自動轉換 JSON 資料
- 客戶端支援防禦 XSRF
首先我們拿一段 json 來模擬資料
{
"name": "BWH_Steven",
"blog": "www.ideal-20.cn",
"about": {
"country": "中國",
"phone": "13888888888"
},
"students": [
{
"id": 0,
"name": "張三"
},
{
"id": 1,
"name": "李四"
},
{
"id": 2,
"name": "王五"
}
]
}
通過下圖我們就可以知道 我們可以將程式碼寫到 mounted() 中去
接著就是使用的程式碼了
首先除了引入 Vue 還需要引入 Axios 的 CDN,在 mounted() 方法中,去拿到這個json檔案,同時將 response.data 也就是拿到的值,賦值給我們在 data() 中定義的 info 中
注意:data 和 data() 是不一樣的
接著在繫結好的 hello-8 div 中就可以呼叫回顯了
說明:為什麼給 v-clock 新增了一個樣式呢,這是因為,顯示資料的過程是先顯示出{{info.name}}
這樣的字樣,拿到值後,再去渲染,如果網速慢的情況下可以看到 info.name 的,體驗不是很好
<!DOCTYPE html>
<html lang="en" xmlns:v-on="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
[v-clock] {
display: none;
}
</style>
</head>
<body>
<div id="hello-8" v-clock>
<div>{{info.name}}</div>
<div>{{info.blog}}</div>
<div>{{info.about.country}}</div>
<div>{{info.about.phone}}</div>
<div>{{info.students[0].name}}</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.11"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script>
var vm = new Vue({
el: "#hello-8",
data() {
return {
info: {}
}
},
mounted() {
axios.get("../json/data.json").then(response => (this.info = response.data));
}
})
</script>
</body>
</html>
(八) 計算屬性
這一段,我認為官方文件說的還是比較清楚的
模板內的表示式非常便利,但是設計它們的初衷是用於簡單運算的。在模板中放入太多的邏輯會讓模板過重且難以維護。例如:
<div id="example">
{{ message.split('').reverse().join('') }}
</div>
在這個地方,模板不再是簡單的宣告式邏輯。你必須看一段時間才能意識到,這裡是想要顯示變數 message
的翻轉字串。當你想要在模板中多包含此處的翻轉字串時,就會更加難以處理。
所以,對於任何複雜邏輯,你都應當使用計算屬性。
<div id="hello-9">
<p>原始資料: "{{ message }}"</p>
<p>翻轉資料: "{{ reversedMessage }}"</p>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.11"></script>
<script>
var vm = new Vue({
el: '#hello-9',
data: {
message: 'Hello'
},
computed: {
// 計算屬性的 getter
reversedMessage: function () {
// `this` 指向 vm 例項
return this.message.split('').reverse().join('')
}
}
})
</script>
結果:
原始資料: "Hello"
翻轉資料: "olleH"
這裡我們宣告瞭一個計算屬性 reversedMessage
。我們提供的函式將用作 property vm.reversedMessage
的 getter 函式:
console.log(vm.reversedMessage) // => 'olleH'
vm.message = 'Goodbye'
console.log(vm.reversedMessage) // => 'eybdooG'
你可以開啟瀏覽器的控制檯,自行修改例子中的 vm。vm.reversedMessage
的值始終取決於 vm.message
的值。
你可以像繫結普通 property 一樣在模板中繫結計算屬性。Vue 知道 vm.reversedMessage
依賴於 vm.message
,因此當 vm.message
發生改變時,所有依賴 vm.reversedMessage
的繫結也會更新。而且最妙的是我們已經以宣告的方式建立了這種依賴關係:計算屬性的 getter 函式是沒有副作用 (side effect) 的,這使它更易於測試和理解。
計算屬性和方法的區別 ?
看到這裡,你會不會覺得,貌似我用方法也可以實現這種效果啊,將具體的業務邏輯放在定義的方法中,但是他們最大的區別是計算屬性是基於它們的響應式依賴進行快取的,也就是說,我們上文中所依賴的 message 不發生改變,reversedMessage 會馬上獲取之前的結果,就不用再次執行函式了,計算屬性可以幫我們節省大量的效能開銷,不過如果我們並不希望出現快取內容,就可以使用方法來代替它
(九) 插槽 Slot
在 2.6.0 中,我們為具名插槽和作用域插槽引入了一個新的統一的語法 (即 v-slot 指令)。它取代了 slot 和 slot-scope 這兩個目前已被廢棄但未被移除且仍在文件中的 attribute。新語法的由來可查閱這份 RFC。
這塊寫的太淺了,不看也罷
插槽就是子元件給父元件一個佔位符即 <slot></slot>
父元件就能在這個佔位符,填一些模板或者 HTML 程式碼
簡單點理解就是元件套元件
就像下面我定義了三個元件,ideal是父元件,在其中用 slot 進行佔位,同時用 name 屬性指向到了這兩個子元件 ideal-title 和 ideal-content,而為了子元件中顯示的資料來自伺服器(模擬)所以需要動態地顯示,即通過傳參(前面講解元件模板有說過),配合遍歷等讀出 data 中的資料即可
<div id="hello-10">
<ideal>
<ideal-title slot="ideal-title" v-bind:title="title"></ideal-title>
<ideal-content slot="ideal-content" v-for="contentItem in contents" v-bind:content="contentItem"></ideal-content>
</ideal>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.11"></script>
<script>
Vue.component("ideal", {
template: '<div>\
<slot name="ideal-title"></slot>\
<ul>\
<slot name="ideal-content"></slot>\
</ul>\
</div>'
})
Vue.component("ideal-title", {
props: ['title'],
template: '<div>{{title}}</div>'
})
Vue.component("ideal-content", {
props: ['content'],
template: '<li>{{content}}</li>'
})
var vm = new Vue({
el: '#hello-10',
data: {
title: "理想二旬不止",
contents: ["Java", "Linux", "資料庫"]
}
})
</script>
結果如下:
四 Vue 入門
(一) 建立 Vue-cli 專案
Vue-cli 是官方提供的一個用於快速建立 Vue 專案的腳手架,可以簡單的理解為 Maven ,即建立時選擇一個骨架那種感覺,能讓開發更加便捷
(1) 準備
A:安裝 Node.js
- Node.js 去官網或者中文網進行下載
cmd 下輸入 node -v
,出現版本號即正常,輸入 npm -v
同樣出現版本號即正常
- 將 Node.js 的映象調整為淘寶映象加速(cnpm)
# -g 代表全域性安全 推薦此方法
npm install cnpm -g
# 還有一種辦法就是每次使用 npm 都在後面加一串字串,不推薦
npm install --registry=https://registry.npm.tabao.org
安裝後開啟此路徑(abc是我這臺機器的使用者名稱,根據自己的來):
C:\Users\abc\AppData\Roaming\npm\node_modules
正常情況下里面會有安裝好的 cnpm,接著我們就開始安裝 vue-cli
B:安裝 vue-cli
cnpm install vue-cli -g
安裝後在 npm 資料夾下開啟 cmd 輸入 vue-list
,若出現下圖這種星狀內容,則完畢
C:建立 vue-cli 程式
自己在想要的位置建立一個目錄,選擇基於 webpack 的 vue 應用程式
此資料夾下的 cmd 中輸入命令
vue init webpack vue_02_myvue
輸入一些基本資訊,例如 專案名 作者名
下面的內容如果有選項的回車配合 n(也就是no)進行
這時,它會詢問你是否自動執行 npm install(如下),是的話則會自動安裝一些依賴,點選否,需要自行再輸入命令安裝,所以選擇是就行了
Should we run npm install for you after the project has been created? (recommended) npm
完成之後,專案中的 node_modules 就會多出很多很多依賴
再接著,它又會提醒初始化好了,你如果想啟動就可以執行這兩條,第一句是從外面的資料夾進入到我自定義的那個專案資料夾中,第二句則是啟動
出現如果所示內容則啟動成功,通過後面的地址和埠就可以訪問
找個編輯器看一下,我用 IDEA Open進這個資料夾來,就可以進行修改了,具體的程式碼檔案還是在 src 目錄下,同時還可以配置 IDEA 的 Terminal 為有管理員許可權的 cmd 或者終端,能更便捷一些
如何快速建立專案
-
可以通過 HBuilder 進行相對快速的建立專案,其新建中直接就可以建立 vue 專案 以及終端執行
-
在想建立專案的目錄下終端輸入 vue ui 進入圖形介面(此方法需要 vue-cli 版本為 3.x ,通過 vue --version 查詢到 vue-cli 的版本 例如為 2.9.6 是不能使用的,可用的命令可以通過 vue -h 檢視 )
(二) 簡單認識 Webpack
(1) 認識安裝
蓋菜我們建立 vue 專案的時候,選擇的是 webpack 進行打包,但是都是自動化的過程,我們手動的操作一下,能更好的理解
webpack是一個現代 Javascript應用程式的靜態模組打包器( module bundler)。當webpack處理應用程式時,它會遞迴地構建一個依賴關係 Dependency graph),其中包含應用程式需要的毎個模組,然後將所有這些模組打包成一個或多個 bundle
webρack是當下最熱門的前端資源模組化管理和打包工具,它可以將許多鬆散耦合的模組按照
依賴和規則打包成符合生產環境部署的前端資源。還可以將按需載入的模組進行程式碼分離,等到實際
需要時再非同步載入。通過 loader轉換,任何形式的資源都可以當做模組,比如 Commonis、AMD、ES6、CSS、JSON、 Coffee Script、LESS等;
安裝 webpack、webpack-cli ,如果 npm 不太慢先考慮使用 npm 再考慮使用 cnpm
cnpm install webpack -g
cnpm install webpack-cli -g
通過 webpack -v
、webpack-cli -v
檢視是否出現版本號確定安裝是否成功
(2) 使用 webpack
-
建立專案(IDEA 的話,直接建立一個普通資料夾 Open進入就行了)
-
新建一個 modules 目錄,放置 JS 模組等內容
-
在 modules 下建立模組檔案,例如 demo.js 用於編寫 Js 模組相關程式碼,例如
exports.test = function () {
document.write("<h2>理想二旬不止</h2>")
}
- 在 moduels 下建立 main.js ,這是一個入口檔案,用於打包時設定 entry 屬性對應
var demo = require("./demo")
demo.test();
- 在專案根目錄下建立 webpack.config.js 檔案,用於配置
module.exports = {
entry: "./modules/main.js",
output: {
filename: "./js/bundle.js"
}
};
- 在 terminal 中輸入 webpack 命令進行打包(進入專案目錄後 輸入 webpack 就行了,這是執行結果)
abc@LAPTOP-5T03DV1G MINGW64 /f/develop/IdeaProjects/framework-code/vue/webpack_01_first
$ webpack
Hash: 7f61ef9440a6bab63058
Version: webpack 4.44.1
Time: 334ms
Built at: 2020-09-05 4:18:40 PM
Asset Size Chunks Chunk Names
./js/bundle.js 1020 bytes 0 [emitted] main
Entrypoint main = ./js/bundle.js
[0] ./modules/main.js 42 bytes {0} [built]
[1] ./modules/demo.js 82 bytes {0} [built]
WARNING in configuration
The 'mode' option has not been set, webpack will fallback to 'production' for this value. Set 'mode' option to 'development' or 'production' to enable defaults for each e
nvironment.
You can also set it to 'none' to disable any default behavior. Learn more: https://webpack.js.org/configuration/mode/
- 打包後專案目錄多出 dist 資料夾 其中有一個 js 資料夾,放著打包的 js,建立index.html 引入此 js
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<script src="dist/js/bundle.js"></script>
</body>
</html>
- 頁面效果如下:
補充:配置檔案中可能會有哪些內容
- entry:入口檔案,指定 Web Pack用哪個檔案作為專案的入口
- output:輸出,指定 Web pack把處理完成的檔案放置到指定路徑
- module:模組,用於處理各種型別的檔案plugins:外掛,如:熱更新、程式碼重用等
- resolve:設定路徑指向
- watch:監聽,用於設定檔案改動後直接打包
(三) 簡單認識 Vue Router 路由
Vue Router是 Vue.js 的官方路由器。它與 Vue.js 核心深度整合,使使用 Vue.js 輕鬆構建單頁應用程式變得輕而易舉。功能包括:
簡單的說,可以實現一些頁面的跳轉,例如我們頭部的內容是不變的,內容部分需要根據連結改變
- 巢狀路線/檢視對映
- 模組化,基於元件的路由器配置
- 路由引數,查詢,萬用字元
- 檢視由Vue.js過渡系統提供動力的過渡效果
- 細粒度的導航控制
- 與自動活動CSS類的連結
- HTML5歷史記錄模式或雜湊模式,在IE9中具有自動回退
- 可自定義的滾動行為
安裝步驟:
由於 vue-router 是一個外掛包,還是老辦法,npm/cnpm
npm install vue-router --save-dev
安裝後如果有一些問題,根據提示,輸入對應命令即可,就像我遇到了提示輸入 npm audit fix
建立好專案後,刪掉預設的 HelloWorld那個元件,然後再 components 中新建兩個自定義元件,例如我建立的 FirstDemo.vue 和 Main.vue 前者是一個子頁面,後者代表主頁面,隨便自擬
FirstDemo.vue
<template>
<h1>第一個Demo頁面</h1>
</template>
<script>
export default {
name: "FirstDemo.vue"
}
</script>
<style scoped>
</style>
Main.vue
<template>
<h1>首頁</h1>
</template>
<script>
export default {
name: "Main.vue"
}
</script>
<style scoped>
</style>
接著建立 router 資料夾,以及其中的 index.js 主配置
注:如果在一個模組化工程中使用它,必須要通過 Vue.use() 明確地安裝路由功能
import Vue from 'vue'
import VueRouter from 'vue-router'
import FirstDemo from '../components/FirstDemo'
import Main from '../components/Main'
Vue.use(VueRouter);
export default new VueRouter({
routes: [
{
// 路由路徑
path: "/firstDemo",
name: 'firstDemo',
// 跳轉的元件
component: FirstDemo
},
{
// 路由路徑
path: "/main",
name: 'main',
// 跳轉的元件
component: Main
}
]
})
修改 main.js 這個入口檔案
// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue'
import App from './App'
import router from './router'
Vue.config.productionTip = false
Vue.use(router);
/* eslint-disable no-new */
new Vue({
el: '#app',
//配置路由
router,
components: {App},
template: '<App/>'
})
以及正式的書寫頁面,引入連結
<template>
<div id="app">
<h1>理想二旬不止</h1>
<router-link to="/main">首頁</router-link>
<router-link to="/firstDemo">第一個Demo頁面</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>
(四) Vue + ElementUi 基本使用
建立名字為 vue_03_vue_elementui 的專案,同時安裝 vue-router、e1ement-ui、sass-loader 、node-sass 外掛
# 建立專案
vue init webpack vue_03_vue_elementui
# 進入工程目錄
cd vue_03_vue_elementui
# 安裝vue-router
npm install vue-router --save-dev
# 安裝e1ement-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 moduleNMame:-g 的意思是將模組安裝到全域性,具體安裝到磁碟哪個位置,要看 npm config prefix的位置
-
npm install - save moduleName:--save 的意思是將模組安裝到專案目錄下,並在package檔案的 dependencies 節點寫入依賴,-S為該命令的縮寫
-
npm install -save -dev moduleName:--save-dev 的意思是將模組安裝到專案目錄下,並在 package 檔案的 devdependencies節點寫入依賴, -D為該命令的縮寫
接著就可以在編輯器中開啟了,看個人選擇,我這裡用 IDEA 開啟,開啟後注意看一下 modules 資料夾中是否已經把 router sass 等內容成功安裝了
接著將預設的 HelloWorld 那個元件和預設 logo 刪掉,開始編寫程式碼,建立一個 views 資料夾用來放檢視
建立 Login.vue 和 Main.vue
Login.vue
<template>
<h1>主頁面</h1>
</template>
<script>
export default {
name: "Main.vue"
}
</script>
<style scoped>
</style>
Main.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: 40px 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 Login from '../views/Login'
import Main from '../views/Main'
Vue.use(VueRouter);
export default new VueRouter({
routes: [
{
path: "/main",
component: Main
},
{
path: "/login",
component: Login
}
]
})
修改 main.js ,使用 router 和 elementui,關於 router 前面就說過,至於後者,照著官網起步文件就明白了
https://element.eleme.cn/#/zh-CN/component/quickstart
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.config.productionTip = false;
Vue.use(router);
Vue.use(ElementUI);
/* eslint-disable no-new */
new Vue({
el: '#app',
router,
render: h => h(App)
});
App.vue
<template>
<div id="app">
<h1>理想二旬不止</h1>
<router-link to="/main">首頁</router-link>
<router-link to="/login">登入頁面</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>
到這裡就寫好了,我們可以開始執行了,但是執行時,我分別出現瞭如下錯誤
TypeError [ERR_INVALID_ARG_TYPE]: The "path" argument must be of type string. Received type undefined
Module build failed: TypeError: this.getResolve is not a function
經查閱後,修改專案目錄下 package.json 中的 sass-loder 的版本 從 10.0.2 到 8.0.2 到 7.3.1 才可以正常通過 npm run dev 執行
"sass-loader": "^7.3.1",
注:修改配置後需要重新 npm install 或者 cnpm install
展示一下最終效果:
點選首頁效果:
點選登入頁面效果:
五 Vue和Java資料互動簡單案例
最後,在某馬上找了一個現成的頁面案例,簡單搭了下後臺跑了一下,也算鞏固一下最前面的基礎語法,後臺就基本的 SSM ,給了三個介面方法,作為一個後端,這應該算基本功了哇
/user/findAll
、/user/indById
、 /user/updateUser
就是簡單的查詢和一個更新操作,查詢的主體是一個使用者類,有這麼幾個基本欄位
public class User implements Serializable {
private Integer id;
private String username;
private String password;
private Integer age;
private String sex;
private String email;
......
}
頁面中承接的資料的關鍵程式碼如下
首先是關於所有使用者資料展示的,通過一個對於 userList 的遍歷,然後通過大括號組和 X.x 的形式取出屬性值
<tr v-for="u in userList">
<td><input name="ids" type="checkbox"></td>
<td>{{u.id}}</td>
<td>{{u.username}}
</td>
<td>{{u.password}}</td>
<td>{{u.sex}}</td>
<td>{{u.age}}</td>
<td class="text-center">{{u.email}}</td>
<td class="text-center">
<button type="button" class="btn bg-olive btn-xs">詳情</button>
<button type="button" class="btn bg-olive btn-xs" @click="findById(u.id)">編輯</button>
</td>
</tr>
點選編輯後執行對於當前使用者的查詢方法,用於回顯,下面通過 v-model 進行與 user 的繫結(js後面給出)
<div class="box-body">
<div class="form-horizontal">
<div class="form-group">
<label class="col-sm-2 control-label">使用者名稱:</label>
<div class="col-sm-5">
<input type="text" class="form-control" v-model="user.username">
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label">密碼:</label>
<div class="col-sm-5">
<input type="text" class="form-control" v-model="user.password">
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label">性別:</label>
<div class="col-sm-5">
<input type="text" class="form-control" v-model="user.sex">
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label">年齡:</label>
<div class="col-sm-5">
<input type="text" class="form-control" v-model="user.age">
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label">郵箱:</label>
<div class="col-sm-5">
<input type="text" class="form-control" v-model="user.email">
</div>
</div>
</div>
</div>
要實現資料互動,最重要的還是定義資料,與使用 axios 進行非同步請求
var vue = new Vue({
el: "#app",
data: {
user: {id: "", username: "", password: "", age: "", sex: "", email: ""},
userList: []
},
methods: {
findAll: function () {
var _this = this;
axios.get("user/findAll.do").then(function (response) {
_this.userList = response.data;
console.log(_this.userList);
}).catch(function (err) {
console.log(err);
});
},
findById: function (userid) {
var _this = this;
axios.get("user/findById.do", {
params: {
id: userid
}
}).then(function (response) {
_this.user = response.data;
$('#myModal').modal("show");
}).catch(function (err) {
});
},
update: function (user) {
var _this = this;
axios.post("user/updateUser.do", _this.user).then(function (response) {
_this.findAll();
}).catch(function (err) {
});
}
},
created() {
this.findAll();
}
});
上述程式碼其實很好理解,首先定義了 user 和 userList 兩個資料,userList 就是前面展示所有使用者資料的一個遍歷內容,用來承載 findAll 後的資料,user 則是對於進行單個使用者查詢,即修改時回顯當前使用者舊資訊的一個承載實體,因為查詢所有的操作是一開始就進行,所以在 created() 中就執行 findAll 方法,在 methos 中建立查和改的方法,通過 axios 進行 get 或者 post 請求,同時將返回的結果進行處理
說明:.then
中的是請求成功後執行的內容,.catch
中是請求失敗後執行的內容
注意:最關鍵的一個內容就是在 axios 前定義了 var _this = this
如果有接觸過小程式可能會感到很熟悉,這裡定義的原因是因為 例如在 axios 中有這樣的語句 _this.userList = response.data;
如果 userList 中前直接使用 this,這就代表著查詢 axios 中的此內容,但我們明顯想指代的是 data 中的 userList,所以此定義 _this
步驟不可省略
效果如下:
查詢所有
六 結尾
如果文章中有什麼不足,歡迎大家留言交流,感謝朋友們的支援!
如果能幫到你的話,那就來關注我吧!如果您更喜歡微信文章的閱讀方式,可以關注我的公眾號
在這裡的我們素不相識,卻都在為了自己的夢而努力 ❤
一個堅持推送原創開發技術文章的公眾號:理想二旬不止