Vue 基礎學習筆記
1 Vue 簡介
1.1 什麼是 Vue
-
Vue 是一套用於構建使用者介面的漸進式框架
-
Vue 被設計為可以自底向上逐層應用
-
Vue 的核心庫只關注檢視層,不僅易於上手,還便於與第三方庫或既有專案整合
-
當與現代化的工具鏈以及各種支援類庫結合使用時,Vue 也完全能夠為複雜的單頁應用提供驅動
1.2 第一個 Vue 程式
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> </head> <body> <div id="app">{{message}}</div> <script src="../statics/vue.js"></script> <script> let vm = new Vue({ el: '#app', <!--使用 id 選擇器繫結 div 元素--> data: { message: 'Hello Vue!' } }); </script> </body> </html>
1.3 MVVM 模式
-
MVVM 全稱 Model-View-ViewNodel,是一種軟體架構設計,是一種簡化使用者介面的事件驅動程式設計方式
-
MVVM 模式與 MVC 一樣,目的都是為了分離檢視和模型
-
它具有低耦合、可複用、獨立開發、可測試幾大特點
2 基本語法
在 Vue 中,所有的 v- 開頭的東西都稱之為指令,它會在渲染的 DOM 上應用特殊的響應行為
2.1 v-bind
v-bind 表示將該元素結點的某屬性與 Vue 的某屬性保持一致
<!--表示將 id=app 的 div 元素的 title 屬性,與 Vue 的 message 屬性保持一致--> <div id = "app" v-bind:title="message">滑鼠懸停檢視資訊</div> <script> let vm = new Vue({ el: '#app', data: { message: 'Hello' } }); </script>
2.2 v-if、v-else
很顯然,就是流程控制中的判斷
<div id="app">
<div v-if="msg">Yes</div>
<div v-else>No</div>
</div>
<script>
let vm = new Vue({
el: '#app',
data: {
msg: true
}
});
</script>
2.3 v-if-else
<div id="app"> <div v-if="msg==='A'">A</div> <div v-else-if="msg==='B'">B</div> <div v-else>C</div> </div> <script> let vm = new Vue({ el: '#app', data: { msg: 'B' } }); </script>
2.4 v-for
流程控制中的迴圈
<div id="app">
<p v-for="(item, index) in items">
{{item.msg}} ==> {{index}}
</p>
</div>
<script>
let vm = new Vue({
el: '#app',
data: {
arrays: [
{user: '荒天帝'},
{user: '林楓'},
{user: '石昊'}
]
}
});
</script>
3 繫結事件
<div id="app">
<button v-on:click="sayHai">點選我</button>
</div>
<script src="../statics/vue.js"></script>
<script>
let vm = new Vue({
el: '#app',
data: {
message: '你好'
},
methods: { //所有的方法都必須寫在 methods 裡面
sayHai: function () {
alert(this.message);
}
}
});
</script>
4 雙向繫結
v-model 會忽略所有表單元素的 value、checked、selected 屬性,總是將 Vue 例項的資料作為資料來源
<!--model 和 view,兩者其一改變,另外一個也必定改變-->
<div id="app">
輸入的文字:<input type="text" v-model="message"> 繫結的文字:{{message}}
</div>
<script src="../statics/vue.js"></script>
<script>
let vm = new Vue({
el: '#app',
data: {
message: ""
}
});
</script>
<div id="app">
<select v-model="checked">
<option disabled>--請選擇--</option>
<option>A</option>
<option>B</option>
<option>C</option>
</select>
<span>選擇的是:{{checked}}</span>
</div>
<script src="../statics/vue.js"></script>
<script>
let vm = new Vue({
el: '#app',
data: {
checked: ''
}
});
</script>
5 元件基礎
-
元件就是可以複用的 Vue 例項,本質就是一組可以重複使用的模板
-
Vue.component 註冊元件
<div id="app">
<my-diy v-for="item in items" v-bind:info="item"></my-diy>
</div>
<script src="../statics/vue.js"></script>
<script>
Vue.component("my-diy", {
props: ['info'],
template: '<li>{{info}}</li>'
});
let vm = new Vue({
el: '#app',
data: {
items: ["Java", "Linux", "Python"]
}
});
</script>
6 Axios
- Axios 是一個開源的可以用在瀏覽器和 Node.js 的非同步通訊框架,它的主要作用就是實現 Ajax 非同步通訊
偽造一個 json 資料,然後使用 axios 將其渲染到頁面
{
"name": "荒天帝",
"teacher": "柳神",
"url": "https:www.xxxx.com",
"address": {
"street": "石村",
"city": "荒域",
"era": "亂古紀元末期"
}
}
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Title</title>
<!--解決網速慢時先顯示模板的問題-->
<style>[v-clock]{ display: none;}</style>
</head>
<body>
<div id="vue" v-clock>
人物姓名:{{info.name}}<br>
護道人: {{info.teacher}}<br>
家庭住址: {{info.address.era}}-{{info.address.city}}-{{info.address.street}}<br>
<a v-bind:href="info.url">連結</a>
</div>
<script src="../statics/vue.js"></script>
<script src="../statics/axios.min.js"></script>
<script>
let vm = new Vue({
el: '#vue',
data(){ //這裡的 data() 是方法,不是原來的那個 data,那個是屬性
return { //這裡的返回值,必須是 json 格式,只需要指定格式不需要指定值
info: {
name: null,
teacher: null,
url: null,
address: {
street: null,
city: null,
era: null
}
}
}
},
mounted(){ //鉤子函式
axios.get("../statics/data.json")
.then(response=>(this.info=response.data));
}
});
</script>
</body>
</html>
7 計算屬性
計算屬性,它是一個屬性,但是計算又是一個函式,簡而言之,就是一個能夠將計算結果快取起來的屬性
<div id="app">
<!--methods 裡的方法,呼叫需要使用括號,因為它是一個方法-->
<p>Time01 : {{getTime01()}}</p>
<!--computed 裡的方法,呼叫不需要使用括號,因為它是一個屬性-->
<p>Time02 : {{getTime02}}</p>
</div>
<script src="../statics/vue.js"></script>
<script>
let vm = new Vue({
el: '#app',
methods: {
getTime01: function (ns) {
return new Date();
}
},
computed: { //計算屬性
getTime02: function () {
this.message; //類似於 MyBatis 中的快取機制,只要發生重新整理(增刪改),快取立馬失效
return new Date();
}
}
});
</script>
8 插槽 slot
<div id="app">
<todo>
<todo-title slot="todo-title" v-bind:title="ti"></todo-title>
<todo-items slot="todo-items" v-for="toIt in todoItems" v-bind:item="toIt"></todo-items>
</todo>
</div>
<script src="../statics/vue.js"></script>
<script>
Vue.component("todo", {
template: '<div>\
<slot name="todo-title"></slot>\
<ul>\
<slot name="todo-items"></slot>\
</ul>\
</div>'
});
Vue.component("todo-title",{
props: ['title'],
template: '<div>{{title}}</div>'
});
Vue.component("todo-items",{
props: ['item'],
template: '<li>{{item}}</li>'
});
let vm = new Vue({
el: '#app',
data: {
ti: '小說人物列表',
todoItems: ['荒天帝','凌風','君莫邪']
}
});
</script>
9 自定義事件內容分發
Vue 的刪除操作要在元件中完成,那麼元件應該怎麼才能刪除 Vue 例項中的元素呢?這樣的功能就涉及到了引數傳遞和事件分發,可以使用 this.$emit('事件名', 引數)
來實現
仍然以上面的例子為例,要求點選刪除按鈕就刪除對應的條目
<div id="app">
<todo>
<todo-title slot="todo-title" v-bind:title="ti"></todo-title>
<todo-items slot="todo-items" v-for="(toIt, index) in todoItems"
:item="toIt" :index="index" :key="index"
v-on:remove="removeItems(index)"></todo-items>
</todo>
</div>
<script src="../statics/vue.js"></script>
<script>
Vue.component("todo", {
template: '<div>\
<slot name="todo-title"></slot>\
<ul>\
<slot name="todo-items"></slot>\
</ul>\
</div>'
});
Vue.component("todo-title",{
props: ['title'],
template: '<div>{{title}}</div>'
});
Vue.component("todo-items",{
props: ['item', 'index'],
template: '<li>{{item}} <button @click="remove">刪除</button></li>',
methods: {
remove: function (index) {
//自定義事件分發
this.$emit('remove', index);
}
}
});
let vm = new Vue({
el: '#app',
data: {
ti: '小說人物列表',
todoItems: ['荒天帝','凌風','君莫邪'],
methods: {
removeItems: function (index) { //刪除 todoItems 元素
this.todoItems.splice(index, 1);
}
}
}
});
</script>
10 Vue-cli
-
Vue-cli 是官方提供的一個腳手架,可以用來快速的生成 Vue 的模板專案
-
它具有預先定義好的目錄結構以及基礎程式碼,較好比建立了一個骨架專案
-
它主要具有:統一的目錄結構、本地除錯、熱部署、單元測試、整合打包上線的功能
- 安裝配置好 Node.js 之後,安裝兩個模組
npm install -g webpack vue-cli
- 然後隨便選擇一個資料夾建立我們的 myvue 專案,在當前目錄下,管理員身份執行終端,執行命令
vue init webpack myvue //myvue 為專案名,不能出現大寫字母
出現如下報錯,大致意思就是網路的問題,無法從 github 上下載到 vuejs-templates/webpack,那我們就去離線安裝
先使用 git 將 webpack 克隆到本地
git clone [email protected]:vuejs-templates/webpack.git
然後在回到剛剛建立專案的目錄下,重新執行命令
//這裡的 E:\MyCode\test\webpack 是剛剛使用 git 克隆的專案路徑,myvue 仍然為專案名稱
vue init E:\MyCode\test\webpack myvue
為了瞭解 vue 專案,這裡全部選擇 No,後續手動安裝
執行成功後,可以發現專案已經成功建立
- 接下來是安裝該專案的所有依賴環境,首先終端進入該專案,然後執行
npm install
//進入專案根目錄
cd myvue
//安裝專案所需的依賴
npm install
- 安裝完所有依賴之後,使用
npm run dev
啟動專案,然後訪問 https://localhost:8080 埠,就可以訪問初始的 vue 專案了
11 路由
-
由於 vue 只針對於檢視層,所以如法控制檢視跳轉,此時就需要使用 vue-router 外掛來實現
-
若要進行類比,他就類似於 Java 的 Servlet,控制檢視的跳轉
- 首先使用 npm 安裝該外掛
npm install vue-router --save-dev
- 安裝好之後,為了測試,我們在 compentents 元件目錄下,新建兩個元件
- 關於我元件
<template>
<h2>歡迎來到關於我頁面</h2>
</template>
<script>
export default {
name: "InfoPage"
}
</script>
<style scoped></style>
- 後臺頁面元件
<template>
<h2>歡迎來到後臺頁面</h2>
</template>
<script>
export default {
name: "MainPage"
}
</script>
<style scoped></style>
- 然後去 router 路徑下新建一個 index.js,去配置路由
import Vue from 'vue'
import Router from 'vue-router'
import InfoPage from "../components/InfoPage";
import MainPage from "../components/MainPage";
Vue.use(Router)
export default new Router({
routes: [
{
name: 'MainPage', //路由的名稱
path: '/main', //路由進行跳轉的路徑,對應 <router-link> 中的 to 所指的屬性,及要跳轉的連結地址
component: MainPage //進行路由註冊的元件名稱
},
{
name: 'InfoPage',
path: '/info',
component: InfoPage
}
]
})
- 使用 App.vue 來模仿網站主頁,將測試的兩個元件使用 router-link 連結進來
<template>
<div id="app">
<h2>網站首頁</h2>
<router-link to="/info">關於我</router-link>
<router-link to="/main">後臺主頁</router-link>
<!-- router-view 標籤必須要有,否則路由跳轉成功後,雖然地址已經改變,但是不顯示頁面-->
<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>
- 然後去主配置 main.js 中將配置的路由 ./components/index.js 匯入
import Vue from 'vue'
import App from './App'
import router from './router/index'
Vue.config.productionTip = false
new Vue({
el: '#app',
router,
components: { App },
template: '<App/>'
})
- 在終端使用命令
npm run dev
啟動專案,訪問 8080 埠,網站主頁面顯示成功
- 分別點選下面的兩個元件,可以看到會成功跳轉到相應的頁面,測試成功
12 路由巢狀
在實際的業務開發中,經常會遇到以下需求,當用戶登入之後(假設路由的路徑為 /user
),接下來使用者所有的操作都會在該路由路徑下進行二次巢狀,比如使用者個人資訊頁面(/user/info
)、使用者列表頁面(/user/list
)等等,諸如此類,就需要進行路由巢狀
- 路由配置
import Vue from 'vue'
import Router from 'vue-router'
import User from '../user'
import UserInfo from '../views/user/Info'
import UserList from '../views/user/List'
Vue.use(Router);
export default new Router({
routes: [
{
path: '/user',
component: User,
children: [
{
path: '/user/info',
component: UserInfo
},
{
path: '/user/list',
component: UserList
}
]
}
]
});
- vue 樣式配置
<templates>
<router-link to='/user'>使用者首頁</router-link>
<router-link to='/user/info'>使用者資訊頁面</router-link>
<router-link to='/user/list'>使用者列表頁面</router-link>
<router-view></router-view>
</templates>
13 引數傳遞和重定向
13.1 引數傳遞
還是以使用者資訊為例,要根據不同使用者來展示不同的資訊,就需要進行引數傳遞
- 路由配置
import Vue from "vue"
import VueRouter from "vue-router";
import User from "../views/User"
import UserInfo from "../views/user/Info"
Vue.use(VueRouter);
export default new VueRouter({
routes: [
{
path: '/user',
name: 'User',
component: User,
children: [
{
path: '/user/info/:username',
name: 'UserInfo',
component: UserInfo,
props: true
}
]
}
]
});
- vue 樣式配置
<template>
<div id="app">
<router-link v-bind:to="{name: 'UserInfo', params: {username: 'Jack'}}">使用者資訊頁面</router-link>
<router-view></router-view>
</div>
</template>
- 使用者資訊頁面取值
<template>
<div>
使用者名稱為:{{username}}
</div>
</template>
<script>
export default {
props: ['username'],
name: "Info",
}
</script>
<style scoped></style>
13.2 重定向
- 路由配置
import Vue from "vue"
import VueRouter from "vue-router";
import User from "../views/User"
import GoHome from "../views/user/GoHome"
Vue.use(VueRouter);
export default new VueRouter({
routes: [
{
path: '/user',
name: 'User',
component: User,
children: [
{
path: '/goHome',
component: GoHome,
redirect: '/main'
}
]
}
]
});
- vue 配置
<template>
<div id="app">
<router-link to="/user/goHome">回到首頁</router-link>
<router-view></router-view>
</div>
</template>
14 404 與路由鉤子
路由預設有兩種模式:history 與 hash 模式
-
history 模式:路徑不帶 # 號,比如 http://localhost:8080/login
-
hash 模式:該模式為預設模式,路徑帶有 # 號,比如 http://localhost:8080/#/login
若要修改模式,只需要設定 mode 即可
export default new Router({
mode: 'history',
routes: []
});
14.1 404
除過業務規定的請求之外,其他的請求都應該走 404 頁面
import Vue from "vue"
import VueRouter from "vue-router";
import NotFound from "../views/NotFound"
Vue.use(VueRouter);
export default new VueRouter({
routes: [
//其他路由配置資訊.....
{
path: "*",
component: NotFound
}
]
});
14.2 路由鉤子
<script>
export default {
//其他配置...
beforeRouteEnter: ((to, from, next) => {
console.log("進入路由之前");
next();
}),
beforeRouteLeave: ((to, from, next) => {
console.log("進入路由之後");
next();
})
}
</script>