Vue官方文檔
以下內容作為本人日常學習使用,不作為參考
一、Vue環境搭建以及vue-cli的使用
Vue多頁面應用文件引用
直接用 <script>
引入
· 對于制作原型或學習,你可以這樣使用:
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
· npm進行安裝
npm install vue
vue-cli構建SPA應用
· npm install -g vue-cli
全局安裝vue-cli
· vue init webpack-simple demo
demo是項目名字(簡單)
· vue init webpack demo
demo是項目名字(詳細)
構建完成后 npm install
通過npm run dev
開始項目
二、 網頁怎么在瀏覽器上顯示
natapp 映射到公網
瀏覽器默認端口號 80 端口
telnet 判斷端口是否開啟
http://192.18.0.20:3000/index.html 請求協議+sourceIP+目標端口+請求路徑
SEO
VUE:
基本用法:網址上自己看
路由用法:可以自己定義,也可以VueRouter
狀態管理:Vuex
服務端渲染:nuxt
三、利用寫好的打包工具生成目錄
build —— 打包的配置文件所在的文件夾
config —— 打包的配置 webpack
src —— 開發源碼 .vue都是入口文件
static —— 靜態資源文件
.babelrc —— 項目的配置文件,解析例如es6等等
.gitignore —— 忽略我們git提交的配置
.postcssrc.js —— HTML添加前綴的配置
index.html —— 單頁面應用程序入口文件
package.json —— 項目的基礎信息和引用的依賴dependencies(本身依賴) devDependencies(開發依賴)
src文件夾中的main.js中的new的vue實例就是整個項目的入口,el中的#app監聽對象區域(也可以在實例末尾 .$mount("#app") ),router是路由,component是組件,template是模板( 也可以在實例內部 render:h=>h(App) )
src 文件夾中的assets文件夾放的也是靜態資源,不過更偏向于組件的靜態資源
在src中新建一個views文件夾當作頁面文件夾,新建 頁面名.vue,內容和引用格式大概如下
<template>
<div>
<h1>里面是頁面的內容</h1>
<nav-footer>組件</nav-footer>
</div>
</template>
<script>
import 'css文件地址'
import 組件名 from '組件地址xx/xx/xx.vue'
export default {
data(){
return {
}
},
components:{
組件名(上面引用的時候要小寫NavFooter=><nav-footer></nav-footer>)
},
methods: {
jump: function() {
// this.$router.push({ path: "/cart?goodsId=123" // });
this.$router.go(-2);
}
}
}
</script>
然后在router中的index.js中渲染出來
import Goodlist from './../views/頁面名'
Vue.use(Router)
export default new Router({
routes: [
{
path: '/good',
name: 'Goodlist',
component: Goodlist
}
]
})
其實配置主要就是build的webpack.base.conf.js和config里面的配置文件 其他就是一些輔助工具
四、Vue基礎語法介紹
.vue文件中template下面必須有一個根元素<div></div>
模板語法
· Mustache語法:{{ msg }}
· Html賦值:v-html=""
· 綁定屬性:v-bind:id=""
· 使用表達式:{{ ok ? 'YES' : 'NO'}}
· 文本賦值:v-text=""
· 指令:v-if=""
· 過濾器:{{ message | capitalize}} 和 v-bind:id="rawId | formatId"
Class和Style綁定
· 對象語法:v-bind:class="{ active:isActive , 'text-danger' : hasError}"
· 數組語法:<div v-bind:class="[ activeClass , errorClass]" > data : { activeClass : 'active' , errorClass:'text-danger' }
· style綁定-對象語法:v-bind:style="{ color : activeColor , fontSize : fontSize + 'px' }"
條件渲染
· v-if
· v-else
· v-else-if
· v-show
· v-clock //會隱藏
vue事件處理器
· v-on:click="greet"或者@click="greet"
· v-on:click.stop(阻止按鈕默認事件<a>) 、 v-on:click.prevent(點擊后失效)、 v-on:click.self(給綁定事件的本身綁定事件)、 v-on:click.once(綁定事件只生效一次)
· v-on:keyup.enter ( 修飾符 .tab .delete捕獲刪除和退格鍵 .esc .spave .up .down .left .right) (搜索回車判斷等等)
vue組件
- 全局組件和局部組件
- 父子組件通訊-數據傳遞 parent--->child(Pass Props) child--->parent(Emit Events)
- Slot插槽
在組件中添加
<solt name="插槽名"></slot>
在頁面中引用的組件中使用插槽
<nav-footer>
<span slot="插槽名">想要插入的內容</span>
</nav-footer>
關于Vue指令的詳細介紹
4.?1 v-text
說明: 文本數據渲染
用法:v-text = "Vue實例中的數據" => 簡寫 {{Vue實例中的數據}}
相當于JavaScript中的innerText
4.?1.?2 v-text指令 和 {{ }}插值表達式 的區別
- v-text 會直接替換元素中的所有內容
- {{ }} 只會替換插值表達式中的占位符
4.?2 v-html
說明: HTML渲染數據
用法:v-html = "Vue實例中的數據"
會解析html結構 渲染至頁面
相當于JavaScript中的innerHTML
4.?2.?1 v-html指令 和 v-text指令的區別
- v-html 會將數據解析成html 渲染至頁面
- v-text 只會輸出成文本(字符串形式)
注意: 在網站上動態渲染任意的 HTML 是非常危險的!!! 因為容易導致 XSS 攻擊 只在可信內容上使用 v-html 絕對不要用在用戶通過(提交)的內容上使用
4.?3 v-on
說明: 事件綁定(綁定事件監聽器)
用法: v-on:事件名 = "事件處理函數" => 簡寫 @事件名 = "事件處理函數"
4.?3.?1 詳細用法
- @事件名.修飾符 = "事件處理函數"
- 邏輯比較少的可以直接寫在行內
- 邏輯較多的寫到 methods 中 注意: 操作Vue實例上的數據要跟上 this
- 可以通過實參傳遞($event) 獲取事件參數e
$event.target
獲取當前事件觸發的DOM元素$event.path[0](el.path[0])
也可以獲取當前事件觸發的DOM元素 path數組中有從觸發事件源的元素的所有上一級元素 直到window- 實參不傳遞(沒有任何參數) 默認在形參中第一個就是事件參數
實參傳遞 就必須傳遞$event 來獲取獲取事件參數
4.?3.?2 事件修飾符
- .stop
阻止事件冒泡 - .prevent
阻止事件默認行為 - .once
只觸發一次回調 - .native
監聽組件根元素的原生事件
很重要!有些第三方組件可能內部并沒有設置原生的事件 就可以通過.native來觸發事件
面試問及
之前在使用餓了么UI的時候給一個組件添加一個原生的事件
但是一直觸發不了
后面查閱文檔發現這個組件內部并沒有注冊我使用的原生事件
事件修飾符.native就可以直接監聽并觸發組件的原生事件
- .capture
添加事件偵聽器時使用 capture 模式 - .{keyCode | keyAlias}
只當事件是從特定鍵觸發時才觸發回調 - .left
(2.2.0版本) 只當點擊鼠標左鍵時才觸發 - .right
(2.2.0版本) 只當點擊鼠標右鍵時才觸發 - .middle
(2.2.0版本) 只當點擊鼠標中鍵時才觸發 - .self
只當事件使用偵聽器綁定的元素本身觸發時才觸發回調 - .passive
(2.3.0版本)以{ passive:true } 模式添加偵聽器
4.?4 v-bind
說明: 屬性綁定(行內屬性)
用法: v-bind:屬性名="Vue實例中的數據" => 簡寫 :屬性名="Vue實例中的數據"
當Vue實例中的數據改變之后 頁面會同步更新
4.?4.1 屬性綁定修飾符
- .prop
被用于綁定 DOM 屬性 (property) - .camel
(2.1.0+) 將 kebab-case 特性名轉換為 camelCase. (從 2.1.0 開始支持) - .sync
(2.3.0+) 語法糖,會擴展成一個更新父組件綁定值的 v-on 偵聽器
4.?4.2 對象的方式綁定class
- :class = "{'red' : isRed}"
isRed = true 就有red這個類
isRed = false 就沒有red這個類
isRed 在 Vue 實例data中聲明
- 默認的class 和 :class(綁定的class) 一起使用不會沖突 后面的會作為追加或者移除來解析
class = "red" :class = "{'yellow' : isYellow}"
4.?4.3 對象的方式綁定style
- :style = "{fontSize : mySize + 'px'}"
- 樣式名需要使用駝峰命名法
- 后面的mySize需要在Vue實例data中定義
4.?5 v-model
說明: 雙向數據綁定
用法:v-model = "Vue實例中的數據"
4.?5.?1 雙向
- 視圖層
- 數據層
數據能夠自動的從內存中顯示到頁面上去
4.?5.?2 雙向綁定修飾符
v.lazy
懶載入 當表單屬性失去光標或按下回車鍵后 再將頁面中的數據和Vue實例中的數據雙向綁定
v.trim
輸入的數據首位空格過濾
- .number
輸入字符串轉為有效的數字
注意: v-model 只能設置給from表單屬性
4.?6 v-for
說明: 循環渲染
用法: v-for = "(item,index) in items" :key = "index"
items是源數據數組
item是被迭代的數組元素的別名
index是被迭代的數組元素的下標(索引)
4.?6.?1 :key
- 數據唯一標識綁定
- v-for默認行為試著不改變整體 而是替換元素 迫使其重新排序的元素需要提供一個key(用戶刪除數據后 數據需重新排列序號 就可以使用key來實現)
- 數據實現重用和重新排序現有的元素
- s值最好為字符串或數值類型(唯一的)
4.?6.?2 遍歷數組注意點
- Vue本身只是監視了Vue實例Data中數組的改變(監視內存地址) 沒有監視數組內部數據的改變
- (變異方法)Vue重寫了數組中的一系列改變數組內部數據的方法(先調用原生的方法 再更新頁面) 所以實現了使用數組提供的方法 數組內部改變 界面自動改變
push()
pop()
shift()
unshift()
splice()
sort()
reverse()
...
this.arr[index] = 新值
`
這種修改數組中的元素是無法實現數據改變后頁面會同步改變(只會修改data中的數據 但是頁面不會同步改變)
splice()的增刪改
增 this.arr.splice(index,0,新值)
刪 this.arr.splice(index,1)
改 this.arr.splice(index,1,新值)
4.?7 v-if,v-else,v-else-if
說明: 條件(表達式或布爾值)判斷渲染
用法:
v-if = "表達式或布爾值"
v-else-if = "表達式或布爾值"
v-else
4.?7.?1 注意
v-if 和 v-else-if 后面必須跟表達式或布爾值
v-else-if 和 v-else 不能獨立使用 必須跟在 v-if 后面
4.?8 v-show
說明: 條件渲染
用法:v-show = "表達式或布爾值"
根據表達式或布爾值的真假切換元素的display屬性
4.?8.?1 注意
v-show 不支持 <template>元素 也不支持 v-else
4.?9 v-if vs v-show
都是用來判斷渲染數據的
- v-if
1.有較高的切換性能消耗
2.惰性渲染 第一次如果條件為false 則不會渲染到頁面 需要等后面條件切換后才會進行第一次渲染
3.條件切換是切換DOM數中這個元素的移除或添加
4.如果運行時條件很少改變則使用v-if
- v-show
1.有較高的初始渲染消耗
2.初始渲染 不管條件 第一次加載頁面的時候都會渲染到頁面
3.條件切換只是切換元素的display屬性
4.如果運行時條件會非常頻繁的切換則使用v-show
4.??10 v-cloak
說明: 這個指令保存在這個元素上 直到關聯實例結束編譯
4.??10.?1 詳細說明
插值表達式在網絡較滿的情況下可能會出現數據閃爍問題
可以通過給實例(#app)盒子添加一個 v-cloak 指令
通過這個指令的特性(如頁面中還有插值表達式就會存在這個指令 如果頁面的插值表達式都被替換成數據 就會自動移除這個標簽)
配合css [v-cloak]{display:none|opacity:0}來解決數據閃爍的問題
某些元素只需要解析一次 后續不需要更新 就可以使用這個指令 提升性能
五、vueRouter的介紹
什么是前端路由
路由是根據不同的url地址去展示不同的內容或頁面
前端路由就是把不同的路由對應不同的內容或者頁面的任務交給前端來做,之前是通過服務端根據url的不同返回不同的頁面實現的
什么時候使用前端路由
在單頁面應用,大部分應用結構步變,只改變部分內容的使用
前端路由有什么優點和缺點
優點:用戶體驗好,不需要每次都從服務端全部獲取,快速展現給用戶
缺點:不利于SEO(網站優化), 使用瀏覽器的前進后退的時候會重新發送請求,沒有合理的利用緩存
vue-router
· vue-router用來構建SPA
· <router-link></router-link>或者this.$router.push({path:"})
· <router-view></router-view>
實例
1.動態路由匹配
什么是動態路由
我們經常需要將具有給定模式的路線映射到同一個組件。例如,我們可能有一個User應該為所有用戶呈現但具有不同用戶ID的組件。在vue-router我們可以在路徑中使用動態段以實現(來自官方例子):
const User = {
template: '<div>User</div>'
}
const router = new VueRouter({
routes: [
// dynamic segments start with a colon
{ path: '/user/:id', component: User }
]
})
現在,網址喜歡/user/foo和/user/bar將映射到相同的路由。
動態段由冒號表示:。匹配路徑時,動態段的值將this.$route.params在每個組件中公開。因此,我們可以通過更新User模板來呈現當前用戶ID :
const User = {
template: '<div>User {{ $route.params.id }}</div>'
}
可以在同一路線中擁有多個動態細分,它們將映射到相應的字段$route.params。例子:
pattern | matched path | $route.params |
---|---|---|
/user/:username | /user/evan | { username: 'evan' } |
/user/:username/post/:post_id | /user/evan/post/123 | { username: 'evan', post_id: '123' } |
下面是一個引用的例子
index.js中
import Vue from 'vue'
import Router from 'vue-router'
import Goodlist from './../views/Goodlist'
Vue.use(Router)
export default new Router({
routes: [
{
path: '/good/:goodsId',
name: 'Goodlist',
component: Goodlist
}
]
})
Goodlist.vue中引入
<span>{{$route.params.goodsId}}</span>
那么就可以獲取到請求地址中的路徑部分
2.嵌套路由
什么是嵌套路由
就是路由里面嵌套路由
在主路由下面有兩個子路由,點擊之后會在主路由的頁面顯示子路由的東西
下面是一個例子:
在新建的views文件夾中分別創建Image.vue文件和Title.vue文件
在div標簽中寫入對他們的描述
在index.js文件中引入子路由
import Vue from 'vue'
import Router from 'vue-router'
import Goodlist from './../views/Goodlist'
import Title from '@/views/Title'
import Image from '@/views/Image'
Vue.use(Router)
export default new Router({
routes: [
{
path: '/good',
name: 'Goodlist',
component: Goodlist,
children: [
{
path: 'title', // 不能加杠,子路由
name: 'title',
component: Title
},
{
path: 'img', // 不能加杠,子路由
name: 'img',
component: Image
}
]
}
]
})
在上面的Goodlist文件中引入
<template>
<div>
這個是列表
<span>{{$route.params.goodsId}}</span>
<router-link to="/good/title">顯示標題</router-link>
<router-link to="/good/img">顯示圖片</router-link>
<div>
<router-view></router-view>
</div>
</div>
</template>
3.編程式路由
什么是編程式路由
通過js來實現頁面的跳轉
陳述 | 編程 |
---|---|
<router-link :to="..."> | router.push(...) |
參數可以是字符串路徑或位置描述符對象。例子:
$router.push("name")
$router.push(path:"name")
$router.push({path:"name?a=123"}) 或者 $router.push({path:"name",query:{a:123}})
$router.go //此方法采用單個整數作為參數,指示在歷史堆棧中前進或后退的步數,類似于window.history.go(n)。
注意:params如果path提供了a,則會被忽略,但不是這種情況query,如上例所示。相反,您需要提供name路由或path使用任何參數手動指定整個:
const userId = '123'
router.push({ name: 'user', params: { userId } }) // -> /user/123
router.push({ path: `/user/${userId}` }) // -> /user/123
// This will NOT work
router.push({ path: '/user', params: { userId } }) // -> /user
注意:如果目標與當前路由相同且只有params正在更改(例如,從一個配置文件轉到另一個配置文件/users/1
- > /users/2
),則必須使用beforeRouteUpdate
以對更改做出反應(例如,獲取用戶信息)。
例子:
在views文件夾中新建一個Cart.vue的文件,并且在div中說明這是一個購物車界面
在index.js文件中引入主路由
import Vue from 'vue'
import Router from 'vue-router'
import Goodlist from './../views/Goodlist'
import cart from '@/views/Cart'
Vue.use(Router)
export default new Router({
routes: [
{
path: '/good',
name: 'Goodlist',
component: Goodlist
},
{
path: '/cart',
component: cart
}
]
})
重點在這里,在Goodlist文件中引入jump方法
<template>
<div>
這個是列表
<router-link to="/cart">跳轉到購物車頁面</router-link>
<button @click="jump">button</button>
</div>
</template>
<script>
export default {
methods: {
jump: function() {
// this.$router.push({ path: "/cart?goodsId=123" }); 在cart.vue中加入 <span>{{$route.query.goodsId}}</span>
this.$router.go(-2);
}
}
};
</script>
4.命名路由和命名視圖
什么是命名路由和命名視圖
給路由定義不同的名字,根據名字進行匹配
給不同的router-view定義名字,通過名字進行對應組件的渲染
例子:
在index.js文件夾中將父子路由合并為命名視圖
routes: [
// {
// path: '/good',
// name: 'Goodlist',
// component: Goodlist,
// children: [
// {
// path: 'title', // 不能加杠,子路由
// name: 'title',
// component: Title
// },
// {
// path: 'img', // 不能加杠,子路由
// name: 'img',
// component: Image
// }
// ]
// },
//命名視圖寫法
{
path: '/',
name: 'Goodslist',
components: {
default: Goodlist,
title: Title,
img: Image
}
},
{
path: '/cart', // 不能加杠,子路由
component: cart
}
]
在app.vue中引入
<router-view name="title"></router-view>
<router-view name="img"></router-view>
六、Vue-Resource基礎
vue-resource是Vue.js的一款插件,它可以通過XMLHttpRequest或JSONP發起請求并處理響應。也就是說,$.ajax能做的事情,vue-resource插件一樣也能做到,而且vue-resource的API更為簡潔。另外,vue-resource還提供了非常有用的inteceptor功能,使用inteceptor可以在請求前和請求后附加一些行為,比如使用inteceptor在ajax請求時顯示loading界面。
特征
- 支持Promise API和URI模板
- 支持請求和響應的攔截器
- 支持最新的Firefox,Chrome,Safari,Opera和IE9 +
- 支持Vue 1.0和Vue 2.0
- 緊湊尺寸14KB(壓縮5.3KB)
安裝
$ yarn add vue-resource
$ npm install vue-resource
提供的API
vue-resource的請求API是按照REST風格設計的,它提供了7種請求API:
- get(url , [options])
- head(url , [options])
- delete(url , [options])
- jsonp(url , [options])
- post(url , [body] , [options])
- put(url , [body] , [options])
- patch(url , [body] , [options])
除了jsonp以外,另外6種的API名稱是標準的HTTP方法。當服務端使用REST API時,客戶端的編碼風格和服務端的編碼風格近乎一致,這可以減少前端和后端開發人員的溝通成本。
options對象
發送請求時的options選項對象包含以下屬性:
參數 | 類型 | 描述 |
---|---|---|
url | string |
請求的URL |
method | string |
請求的HTTP方法,例如:'GET', 'POST'或其他HTTP方法 |
body |
Object , FormData string
|
request body |
params | Object |
請求的URL參數對象 |
headers | Object |
request header |
timeout | number |
單位為毫秒的請求超時時間 (0 表示無超時時間) |
before | function(request) |
請求發送前的處理函數,類似于jQuery的beforeSend函數 |
progress | function(event) |
ProgressEvent回調處理函數 |
credentials | boolean |
表示跨域請求時是否需要使用憑證 |
emulateHTTP | boolean |
發送PUT, PATCH, DELETE請求時以HTTP POST的方式發送,并設置請求頭的X-HTTP-Method-Override
|
emulateJSON | boolean |
將request body以application/x-www-form-urlencoded content type發送 |
全局攔截器interceptors
Vue.http.interceptors.push((request, next) => {
// ...
// 請求發送前的處理邏輯
// ...
next((response) => {
// ...
// 請求發送后的處理邏輯
// ...
// 根據請求的狀態,response參數會返回給successCallback或errorCallback
return response
})
})
在response返回給successCallback或errorCallback之前,你可以修改response中的內容,或做一些處理。
例如,響應的狀態碼如果是404,你可以顯示友好的404界面。
七、模塊化開發中AMD、CMD、CommonJs 和 ES6的對比
什么是AMD、CMD、CommonJs
- AMD是RequireJS在推廣過程中對于模塊定義的規范化產出,RequireJS全稱是異步模塊定義
define( [ ' package/lib' ] , function(lib){
function foo(){
lib.log("hello world!");
}
return {
foo:foo
};
});
- CMD是SeaJS(淘寶團隊)在推廣過程中對于模塊定義的規范化產出,SeaJS全稱是同步模塊定義
// 所有模塊都通過define來定義,即用即返回,所以是同步概念
define(function(require , exports , module) {
// 通過require來引入依賴
let $ = require('jquery');
ley Spinning = require('./spinning');
- CommonJS規范 - module.exports (node服務端使用的規范)
exports.area = function (r) {
return Math.PI * r * r ;
- ES6特性 export/import
export default {
props:["num"],
data() {
return{
}
},
methods:{
increment(){
this.$emit("incre");
import('./../util')
},
decrement() {
this.$emit("decre");
}
}
}
八、前端渲染訪問后臺回來的數據
圖片懶加載vue-lazyload
圖片分頁插件vue-infinite-scroll