什么是Vue
Vue.js 是一套構建用戶界面的框架 只關注視圖層 易于上手,還便于與第三方庫或即有項目整合
MVC:(數(shù)據(jù)層,頁面層,邏輯層)
-
MVVM模式:model-view-ViewModel
model:負責純javascript對象表示
view:view負責顯示
兩者做到最大極限的分離
viewModel:負責將model數(shù)據(jù)同步到view顯示出來,還負責把view的修改同步到model
Vue選項
var vm = new Vue({
el: "#app",//元素名字 列如:#id,.class 要控制的區(qū)域
data: {
//數(shù)據(jù)(需要注意的是,在組件中的data必須是函數(shù) 數(shù)據(jù)都需要return)
message: "hello",
name:'zz'
},
computed: {
// 在computed中罕容,可以定義一些屬性,這些屬性叫做計算屬性稿饰,計算屬性的本質就是一個方法锦秒,只不過在使用這些計算屬性的時候,是把 方法名稱 直接當作屬性來使用的湘纵;并不會把 計算屬性 當做方法去調用
//* 注意1:計算屬性在調用時候不要加()脂崔,直接把他當作一個屬性去調用就好
//* 注意2:只要計算屬性(function)內部所用到的任何data數(shù)據(jù)發(fā)生了變化,就會立即重新計算這個屬性的值
// * 注意3:計算屬性的求值結果梧喷,會被緩存起來砌左,方便下次直接使用脖咐;如果 計算屬性 方法中,data的任何數(shù)據(jù)沒有發(fā)生改變汇歹,而你又在此調用屁擅,則返回的是緩存好的結果
"result":function(){
return this.name + this.message
//返回結果: hello zz
}
},
methods: {
//這里可以自定義方法
},
watch: {
//偵聽器 當某個數(shù)據(jù)發(fā)生改變就會觸發(fā) 讓數(shù)據(jù)發(fā)生變更
//監(jiān)聽的方法一般都會有兩個參數(shù),newVal,oldval
//列如標簽有一個 v-model='name'
'name':function(newVal,oldval){
//newVal:是新的數(shù)據(jù) 結果: zz
//oldVal:是舊的數(shù)據(jù) 結果: undefined
},
//典型案列
'$route.push':function(newVal,oldval){
console.log(newVal ------ oldval)
// 注冊好了 跳轉 登錄頁
//newVal:當前跳轉到的頁面 結果:登錄頁
//oldVal: 從上一個頁面 跳轉到當前頁面的 頁面 結果:注冊頁
}
// watch 最好用來監(jiān)聽非 DOM 元素的改變 列如:$route
}
});
-
總結:
watch,computed产弹,methods之間的對比
1.
computed:
屬性的結果會被緩存派歌,除非依賴的響應式屬性變化才會重新計算。主要當作屬性來使用痰哨;2.
methods:
方法表示一個具體的操作胶果,主要書寫業(yè)務邏輯;-
watch:
一個對象斤斧,鍵是需要觀察的表達式早抠,值是對應回調函數(shù)。主要用來監(jiān)聽某些特定數(shù)據(jù)的變化撬讽,從來進行某些具體的業(yè)務邏輯操作蕊连;可以看做是methods
和computed
的結合體;
-
Vue v-指令
-
v-bind:(縮寫:) 數(shù)據(jù)綁定
- 在使用==號以后 后面跟的就是一個js表達式
{{ }}:差值表達式 注意react里沒有差值表達式一說而是jsx語法
v-on: (縮寫@:)事件處理
v-for="(item, index) in array"(遍歷 (元素,下標)) 要配合:key( String/Number )
v-model :雙向數(shù)據(jù)綁定(只能運用到表單元素中...)
v-cloak :可以用來解決插值表達式閃爍問題
-
v-pre:表示該會跳過該標簽及其子元素的編譯
v-指令區(qū)別
-
v-show 和 v-if
v-if
v-else-if
v-else
v-show
一般來說游昼,v-if有更高的切換消耗 v-show有更高的初始渲染消耗甘苍。因此如果頻繁切換使用v-show較好,如果運行時條件不大可能改變 v-if較好
如果一個元素一直都不會顯示出來 并操作他 v-if更好
v-if特點:每次都會重新刪除或創(chuàng)建元素
v-show:只會切換diplay:none/block
-
v-html 和 v-text
v-html : 真正的HTML也可以是 標簽
v-text : 只是一串字符串
Vue 修飾符
-
事件修飾符:
v-on:click.stop:阻止冒泡的
v-on:click.prevent:阻止默認行為
v-on:click.once :只會執(zhí)行一次
v-on:click.capture:添加事件監(jiān)聽器時使用事件捕獲模式
@click.self:只當事件在該元素本身(比如不是子元素) 觸發(fā)時觸發(fā)回調
-
self 與 stop的區(qū)別
self只取消當前事件本身的冒泡并不影響其他的冒泡
stop則是取消所有的冒泡
-
按鍵修飾符:
v-on:keyup.enter:按回車觸發(fā)
分別還有:.tab烘豌,.delete载庭,.esc, .space
自定義修飾符
`Vue.config.keyCodes.f2 =113` @Keyup.f2調用
-
修飾鍵:
@keyup.alt.13:同時按下 alt+回車
分別還有: .ctrl .alt .shift .meta
修飾鍵與修飾符不同 修飾鍵單獨按并不會觸發(fā) 需要按修飾鍵+修飾符才會觸發(fā)
-
事件處理:
@touchstart:也是類似點擊事件 但是相比click他沒有延遲 而click有300毫秒的延遲所以 touchstart相對來說會先執(zhí)行
@touchend:也比click快但是比start慢 也是點擊事件
@touchmove:在end之前 start之后 還是比click快 鼠標移動事件
Vue使用Class樣式
- 數(shù)組
<h1 :class="['red','thin']"> 這是一個樣式運用方法 </h1>
- 數(shù)組中使用三元表達式
<h1 :class="['red','thin', flag? 'active' : 'isactive' ]"> 這是一個樣式運用方法 </h1>
data :{
flag : true; //ture引用active, false則不用active
}
- 數(shù)組中嵌套對象
<h1 :class="['red','thin',{ 'active' : flag }]"> 這是一個樣式運用方法 </h1>
data:{
flag : true; //ture引用active, false則不用active 類似三元表達式
}
- 直接使用對象
<h1 :class="{red:true,thin:true,active:false,isactive:false }"> 這是一個樣式運用方法 </h1>
<h1 :class="obj"> 這是一個樣式運用方法 </h1>
//直接傳對象 且只有true的被使用 或者可以直接寫一個對象
data:{
obj:{
red:true,
thin:true,
active:false,
isactive:false
}
}
Vue使用內聯(lián)樣式-style
- 直接在元素上通過 :style 的形式,書寫樣式對象
<h1 :style='{color:'red', 'font-size':'40px'}'> 這是一個內聯(lián)樣式的H1</h1>
- **將樣式對象扇谣,定義到
Data
中昧捷,并直接引用到:style
中
data:{
handleObj:{
color:'red',
'font-size':'40px',
fontSize:40 // 兩種寫法羅峰寫法 或者 字符串 直接數(shù)組則默認px
}
}
- **在
:style
中通過數(shù)組,應用多個data
上的樣式對象
<h1 :style="[handleObj,handleObj2 ]"> 這是一個內聯(lián)樣式的H1</h1>
data:{
handleObj:{
color:'red',
'font-size':'40px',
fontSize:40 // 兩種寫法羅峰寫法 或者 字符串 直接數(shù)組則默認px
},
handleObj2:{
backgroundColor:'#0f6',
background-color:'#0f6'
}
}
Vue 過濾器
//過濾器的格式
// \ 術語叫做 管道符
{{ name | isname('Dad+1') | test('Nb')}}
//過濾器的語法
isname: 過濾器的名字
Vue.filter("isname",function(name ,msg){
//replace 第一個參數(shù)也可以寫正則
return name.replace( '弟弟','Dad') //只會改第一個弟弟
return name.replace(/弟弟/g,'Dad')//全改
return name.replace(/弟弟/g,msg)//第三種方法可以通過傳參來更改
})
Vue.filter('test',function(name,msg){
return name + '====='
})
//定義私有過濾器
//私有的話 過濾器的名字變成方法名
var vm = new Vue({
data:{
name:'就是一個弟弟就是一個弟弟就是一個弟弟,'
},
filters:{
isname:function(name,msg){
//replace 第一個參數(shù)也可以寫正則
return name.replace( '弟弟','Dad') //只會改第一個弟弟
return name.replace(/弟弟/g,'Dad')//全改
return name.replace(/弟弟/g,msg)//第三種方法可以通過傳參來更改
}
}
})
過濾器調用的時候罐寨,采用的是就近原則,如果私有過濾器和全局過濾器一致了序矩,這時候鸯绿,會優(yōu)先調用私有過濾器
自定義全局的指令
//第一個參數(shù)在調用時候,必須在指令前加上v- 前綴來進行調用
//第二個參數(shù)是一個對象簸淀,這個對象身上瓶蝴,有一些指令相關的函數(shù),這些函數(shù)可以在特定的階段租幕,執(zhí)行相關的操作
Vue.directive('focus',{
//每個函數(shù)中,第一個參數(shù)都是el,表示被綁定了指令的那個元素舷手,這個el參數(shù),是一個原生的Js對象
bind:function(el){
//每當指令綁定到元素上的時候劲绪,會立即執(zhí)行這個bind函數(shù)男窟, 只執(zhí)行一次
el.focus() //focus 獲取焦點 input lode原生方法 但是在這里使用時不行的
//在元素剛綁定了指令的時候盆赤,還沒有插入到DOM中,這時候歉眷,調用focus方法沒有作用
//因為一個元素牺六,只有插入Dom之后,才能獲取焦點
},
inserted:function(el){
//inserted 表示元素 插入到DOM中的時候汗捡,會執(zhí)行inserted函數(shù)[觸發(fā)一次]
//一般來說從內存(JavaScript)渲染到數(shù)據(jù) 也就是 從model 渲染到 view 就要執(zhí)行的話用bind 列如:樣式 而js的事件操作 需要等Dom生成完畢才能執(zhí)行 最好放在 inserted里
},
updata:function(el){
//當vNode更新的時候淑际,會執(zhí)行updata,可能觸發(fā)多次
}
})
`自定義 私有指令`
var vm = new Vue({
dirctives:{
focus:function(){
//之后操作和全局一樣
},
focus: function(){
//如果想 bind 和 updata都重復操作 那么可以直接在function里寫操作
//等同于 bind 和 updata
}
}
})
* Vue生命周期
-
什么是生命周期:
從Vue實列創(chuàng)建扇住,運行春缕,銷毀,會伴著各種函數(shù)艘蹋,這些統(tǒng)稱為 生命周期
生命周期鉤子:就是生命周期的別名
-
主要的生命周期函數(shù)分類:
-
創(chuàng)建期間的生命周期函數(shù):
beforeCreate:實列剛在內存中被創(chuàng)建出來锄贼,此時,還沒有初始化好 data 和 methods屬性簿训。
Created:實列已經(jīng)在內存中創(chuàng)建OK咱娶,此時data和 methods已經(jīng)創(chuàng)建OK,此時沒有開始 編譯模板
beforeMount:此時已經(jīng)完成了編譯的模板强品,但是還沒有掛載到頁面上
Mounted:此時膘侮,已經(jīng)將編譯好的模板,掛載到了頁面指定的容器中顯示了
-
運行期間的生命周期函數(shù):
beforeUpdate:狀態(tài)更新之前執(zhí)行此函數(shù)的榛,此時data中的狀態(tài)值是最新的琼了,但是界面上顯示的數(shù)據(jù)還是舊的,因為此時還沒有開始重新渲染Dom節(jié)點
Update:實列更新完畢之后調用此函數(shù)夫晌,此時 data 中的狀態(tài)值 和 界面上顯示的數(shù)據(jù)雕薪,都已經(jīng)完成了更新,界面已經(jīng)被重新渲染好了
-
銷毀期間的生命周期函數(shù):
beforeDestroy:實列銷毀之前調用晓淀,在這一步所袁,實列容然可用
Destroyed:Vue 實列銷毀后調用,調用后凶掰,Vue實列指示的所有東西都會解綁燥爷,所有事件監(jiān)聽器會被移除,所有的子實列也會被銷毀
-
* Ajax
Ajax的原理簡單來說通過xmlHttpRequest 對象來想服務器發(fā)異步請求懦窘,從服務器獲得數(shù)據(jù)前翎,然后用JavaScript來操作DOM而更新頁面。這其中最關鍵的一步就是從服務器獲得請求數(shù)據(jù)畅涂。要清楚這個過程和原理港华,必須對XMLHttpquerst有所了解
XMLHttprequest 是 Ajax的核心控制,它是在IE5中首先引入的午衰,是一種支持異步請求的技術立宜,簡單說冒萄,也就是JavaScript可以及時向服務器提出請求和處理響應,而不阻塞用戶赘理,打到無刷新的效果宦言。
* JSONP的實現(xiàn)原理
由于游覽器的安全限制,不允許AJAX訪問 協(xié)議不同商模,域名不同奠旺,端口號不同的數(shù)據(jù)接口,游覽器認為這種訪問不安全
可以通過動態(tài)創(chuàng)建Script標簽的src屬性施流,指向數(shù)據(jù)接口的地址响疚,因為script標簽不存在跨域限制,這種數(shù)據(jù)數(shù)據(jù)獲取方式瞪醋,稱作JSONP(*注意:JSONP的實現(xiàn)原理忿晕,知曉,JSONP只支持GET請求)
-
具體實現(xiàn)過程:
* 先在客戶端定義一個回調方法银受,預定義對數(shù)據(jù)的操作践盼; * 再把這個回調方法的名稱夯到,通過URL傳參的形式桑孩,提交到服務器的數(shù)據(jù)接口; * 服務器數(shù)據(jù)接口組織好要發(fā)送給客戶端的數(shù)據(jù) 糯俗,再拿著客戶端傳遞過來的回調方法名稱顶霞,拼接出一個調用這個方法的字符串肄程,發(fā)送給客戶端去解析執(zhí)行 * 客戶端拿到服務器返回的字符串之后,當作Script腳本去解析執(zhí)行选浑,這樣就能拿到JSON數(shù)據(jù)了
Axios
npm install --save --save-exact axios vue-axios
-
axios的特點有哪些蓝厌?
Axios 是一個基于 promise 的 HTTP 庫,支持promise所有的API
它可以攔截請求和響應
它可以轉換請求數(shù)據(jù)和響應數(shù)據(jù)古徒,并對響應回來的內容自動轉換成 JSON類型的數(shù)據(jù) 安全性更高拓提,客戶端支持防御 XSRF
-
axios有哪些常用方法?
axios.get(url[, config]) //get請求用于列表和信息查詢
axios.delete(url[, config]) //刪除
axios.post(url[, data[, config]]) //post請求用于信息的添加
axios.put(url[, data[, config]]) //更新操作
-
說下你了解的axios相關配置屬性隧膘?
url
是用于請求的服務器URLmethod
是創(chuàng)建請求時使用的方法,默認是getbaseURL
將自動加在url
前面崎苗,除非url
是一個絕對URL。它可以通過設置一個baseURL
便于為axios實例的方法傳遞相對URLtransformRequest
允許在向服務器發(fā)送前舀寓,修改請求數(shù)據(jù),只能用在'PUT','POST'和'PATCH'這幾個請求方法headers
是即將被發(fā)送的自定義請求頭
// 添加請求攔截器
axios.interceptors.request.use(function (config) {
// 在發(fā)送請求之前做些什么
//Loading
Indicator.open({
text: '加載中...',
spinnerType: 'double-bounce'
});
return config;
}, function (error) {
// 對請求錯誤做些什么
return Promise.reject(error);
});
// 添加響應攔截器
axios.interceptors.response.use(function (response) {
// 對響應數(shù)據(jù)做點什么
//響應到數(shù)據(jù)以后 close 關閉Loading
Indicator.close();
if(res.data.res_code === 1){
return res.data.res_body
}
else{
Toast({
message: '提示:數(shù)據(jù)請求異常',
position: 'bottom',
duration: 3000
});
}
}, function (error) {
// 對響應錯誤做點什么
return Promise.reject(error);
});
// 請求數(shù)據(jù)
export const getHomeSwipe = ()=>{
return ajax.get('/api/swiperimgs')
}
定義Vue組件
什么是組件: 組件的出現(xiàn)肌蜻,就是為了拆分Vue實列的代碼量的互墓,能夠讓我們以不同的組件,來劃分不同的功能模塊蒋搜,將來我們需要什么樣的功能篡撵,就可以
什么是模塊化:
文件作用域
-
通信規(guī)則
加載 require
導出
模塊規(guī)范:
模塊作用域
-
使用 require 方法用來加載模塊
-
作用:
執(zhí)行被加載中的代碼判莉,得到被加載模塊中的export 導出接口對象
-
-
使用 exports 接口對象來導出模塊中的成員
-
作用
模塊作用域:默認文件中所有的成員只在當前文件模塊中有效
對于希望可以被其他模塊訪問的成員,我們就需要吧這些公開的成員都掛載到 export 接口對象中就可以了
-
模塊化:是從代碼邏輯的角度進行劃分的育谬;
組件化:是從UI界面的角度進行劃分的券盅;
全局組件定義的三種方法
- 使用Vue.extend 配合 Vue.component 方法:
var login = Vue.extend({
tamplate:` <h1> 登錄 </h1>`
})
Vue.component('login',login)
- 直接使用Vue.component 方法:
Vue.component('register',{
template:`<h1> 注冊 </h1>`
});
- 將模板字符串,定義到script標簽種:
<script id="tmpl" type="x-tamplate">
<div> <a href='#' > 登錄 </a> | <a href='#' > 注冊 </a> </div>
</script>
- 創(chuàng)建私有組件:
var vm = new Vue({
components:{
login:{
template:·<h1>這是一個私有組件</h1>·
}
}
})
在使用組件的時候 組件名列如myCol 那么渲染就要使用 <my-col></my-col>渲染
組件中 只允許有一個根元素
組件中的 data 必須一個是方法膛檀,這個方法內必須return一個對象才行
組件切換除了 v-if 以外 還可以是用 :IS="組件名"
* Vue 父子組件通信
-
父組件通過props向子組件傳值
- 父組件锰镀,可以引用子組件的時候,通過屬性綁定(v-bind:)的形式咖刃,把需要傳值給子組件的數(shù)據(jù)泳炉,以屬性綁定的形式,傳遞到子組件的內部嚎杨,供子組件使用
//HTML模板
<div id="app">
<col :parenMsg='msg'> </col>
</div>
var vm = new Vue({
el:'#app',
data:{
msg:'這是一個子組件所需要的值'
},
//子組件中花鹅,默然無法訪問到 父組件中的 data 上的數(shù)據(jù)和 methods 中的方法
components:{
col:{
//* 注意:子組件中的 data 數(shù)據(jù),并不是通過父組件傳遞過來的枫浙,而是子組件自身私有的刨肃,比如:子組件通過 Ajax。請求回來的數(shù)據(jù)箩帚,都可以放到 data 身上
`* 注意:在子組件中 data 數(shù)據(jù)時可讀可寫的真友,props綁定屬性的參數(shù)是只讀的`
data(){
return{
name:'zz',
age:23
}
},
//把父組件傳過來的 parentMsg屬性,現(xiàn)在props數(shù)組中定義一下膏潮,這樣才能使用這個數(shù)據(jù)
//* 注意:組件中的所有 props中的數(shù)據(jù)锻狗,都是通過父組件傳遞給子組件的
props:["parentMsg"],
template:'<h1>收到了父組件的值了---{{parentMsg}}</h1>'
}
}
})
-
子組件通過調用事件向父組件傳值
- 子組件通過事件 this.$emit('第一參數(shù)為父組件的方法',第二個是要穿過去的參數(shù)對象')
<div id='app'>
<!---父組件-->
<col @func="show"></col>
</div>
<!---子組件-->
<template id='tmp'>
<div>
<h1>這是子組件</h1>
<input type="button" value="觸發(fā)父組件來傳值" @click="childClick"/>
</div>
</template>
var vm = new Vue({
data:{
detail:{}
},
methods:{
show(data){
this.detail = data
}
},
components:{
col:{
template:'#tmp',
data(){
return{
msg:{
name:'zz',
age:23
}
}
},
methods:{
childClick(){
this.$emit('show',this.msg)
}
}
}
}
})
Vue ref獲取Dom元素和組件組件引用
<div id='app'>
<Input type='button' value='獲取元素' @click='getElement' ref='mybtn'>
<h3 id='tmp' ref='tmp'>獲取成功的 innerHTML</h3>
<col ref='col'></col>
</app>
var vm = new Vue({
el:'#app',
data:{},
methods:{
getElement(){
this.$refs.tmp.innerHtml//獲取ref名為tmp的元素
this.$refs.col.data// 組件上使用ref會吧整個組件vue實列存到ref 這樣的話可以通過 $refs 來獲取子組件里的data
}
},
components:{
col :{
template:"<h1> 登錄注冊 </h1>",
data:{
name:'zz'
},
methods:{
show(){
console.log('子組件的方法')
}
}
},
}
})
Vue動畫
- 使用transition
!需求:點擊按鈕讓h3顯示再按隱藏
1. 使用 transition 元素焕参,把需要把動畫控制的元素轻纪,包裹起來(transition元素是 vue 官方提供)
2. 自定義兩組樣式,來控制 transition 內部的元素實現(xiàn)動畫
/*v-enter 【這是一個時間點】 是進入之前,元素的起始狀態(tài)叠纷,此時還沒有開始進入*/
/*v-leave-to 【這是一個時間點】是動畫離開之后刻帚,離開的終止狀態(tài),此時涩嚣,元素動畫已結束*/
v.enter,
v-leave-to{
opatity: 0;
},
v-enter-active,
v-leave-active{
.v-enter-active[入場動畫的時間段],
.v-leace-active[離場時間的時間段]{
transition: all 0.4s ease
}
}
<transition>
<h3 v-show='flag'>這是一個會動的標簽</h3>
</transition>
Vue-Router
什么是路由
后端路由: 對于普通的網(wǎng)站崇众,所有的鏈接都是URL地址,所有的URL地址都對應服務器上對應的資源航厚;
前端路由: 對于單頁用程序來說顷歌,主要通過URL中的hash(#號)來實現(xiàn)不同頁面之間的切換,同時 hash 中有一個特點:HTTP請求不會包含hash相關的內容幔睬;所有單頁面程序中的頁面跳轉主要用hash實現(xiàn)眯漩;
在單頁面程序中,這種通過hash改變來切換頁面的方式,稱作前端路由(區(qū)別于后端路由)
安裝
- CDN安裝
<script src="/path/to/vue.js"></script>
<script src="/path/to/vue-router.js"></script>
- Npm
npm install vue-router
- 如果在一個模塊化工程中使用它,必須要通過 Vue.use() 明確地安裝路由功能:
import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter)
- 構建開發(fā)版:
如果你想使用最新的開發(fā)版,就得從 GitHub 上直接 clone赦抖,然后自己 build 一個 vue-router
git clone https://github.com/vuejs/vue-router.git node_modules/vue-router
cd node_modules/vue-router
npm install
npm run build
vue-router中
router
-
$route 表示(當前路由信息對象)
表示當前激活的路由的狀態(tài)信息舱卡,包含了當前 URL 解析得到的信息,還有 URL 匹配到的 route records(路由記錄)队萤。路由信息對象:即$router會被注入每個組件中轮锥,可以利用它進行一些信息的獲取。
-
$route.path
字符串要尔,對應當前路由的路徑舍杜,總是解析為絕對路徑,如 "/foo/bar"盈电。
-
$route.params
一個 key/value 對象蝴簇,包含了 動態(tài)片段 和 全匹配片段,
如果沒有路由參數(shù)匆帚,就是一個空對象熬词。
-
$route.query
一個 key/value 對象,表示 URL 查詢參數(shù)吸重。
例如互拾,對于路徑 /foo?user=1,則有 $route.query.user == 1嚎幸, 如果沒有查詢參數(shù)颜矿,則是個空對象。
-
$route.hash
當前路由的 hash 值 (不帶 #) 嫉晶,如果沒有 hash 值骑疆,則為空字符串。錨點
-
$route.fullPath
完成解析后的 URL替废,包含查詢參數(shù)和 hash 的完整路徑箍铭。
-
$route.matched
數(shù)組,包含當前匹配的路徑中所包含的所有片段所對應的配置參數(shù)對象椎镣。
-
$route.name
當前路徑名字
-
$route.meta
路由元信息
-
route object 出現(xiàn)在多個地方
(1) 在組件內诈火,即 this.$route
(2) 在 $route 觀察者回調內 router.match(location) 的返回值
(3) 導航守衛(wèi)的參數(shù):
router.beforeEach((to, from, next) => {
// to 和 from 都是 路由信息對象
})
watch: {
$route(to, from) {
// to 和 from 都是 路由信息對象
}
}
$router對象
全局的路由實例,是router構造方法的實例状答。在 Vue 實例內部冷守,你可以通過 $router 訪問路由實例
const router = new Router({
routes: [
{
path: "/",
name: "首頁",
redirect: '/home'
},
{
path: '/login',
name: 'Login',
component: Login
},
{ path: '*', component: NotFoundComponent }
],
linkActiveClass: "active-router",
linkExactActiveClass: "exact-router"
})
路由實列方法 push
// 字符串
this.$router.push('home')
// 對象
this.$router.push({ path: 'home' })
// 命名的路由
this.$router.push({ name: 'user', params: { userId: 123 }})
// 帶查詢參數(shù),變成 /register?plan=123
this.$router.push({ path: 'register', query: { plan: '123' }})
push方法其實和<router-link :to="...">是等同的惊科。注意:push方法的跳轉會向 history 棧添加一個新的記錄拍摇,當我們點擊瀏覽器的返回按鈕時可以看到之前的頁面。
路由實列方法 go
// 頁面路由跳轉 前進或者后退
this.$router.go(-1) // 后退
路由實列方法 replace
//push方法會向 history 棧添加一個新的記錄馆截,而replace方法是替換當前的頁面授翻,
不會向 history 棧添加一個新的記錄
<router-link to="/05" replace>05</router-link>
// 一般使用replace來做404頁面
this.$router.replace('/')
使用
- CDN簡單使用Vue-router
- Css
.myactive{
/*如果不想麻煩 也可以吧class名直接改為 router-link-active 但是不推薦*/
}
- HTML
<div id='#app'>
<!-- router-link 默認渲染為一個a 標簽-->
<!-- tag是讓 router-link 以什么標簽進行渲染 但是都會綁定一個跳轉的點擊事件-->
<!--如果在路由中,使用 查詢字符串,給路由傳遞參數(shù)堪唐,則不需要修改路由的 path 屬性-->
<!--這種傳參方式為 query傳參方式 -->
<router-link to='/login?id=10&name='zz'' tag='button'>登錄</router-link>
<template id='login'>
<!--mine-->
<router-link to='/login/mine' tag='div'>我的</router-link>
<router-view></router-view>
</template>
<router-link to='/register/12/zhao' tag='span'>注冊</router-link>
<!--這是 vue-router 提供的元素,專門用來當做占位符的翎蹈,將來淮菠,路由規(guī)則,匹配到的組件荤堪,就會展示到這個 router-view 中去-->
<router-view></router-view>
</div>
- JavaScript
let login = {
//在插值表達式中 this是可以省略掉的
template:'<h1> 登錄組件-----{{ $route.query.name }} </h1>',
created(){
this.$route.query.id //調用到id
this.$route.query.name //調用到name
}
}
let register = {
template:'<h1> 注冊組件-----{{ $route.query.name}}</h1>',
created(){
this.$route.query.id //調用到id
this.$route.query.name //調用到name
}
}
let mine = {
template:'<h1> 這是一個login的子組件</h1>',
}
// 創(chuàng)建一個路由對象合陵,當導入vue-router包之后,在 window 全局對象中澄阳,就有了一個 路由的構造函數(shù)拥知,叫做VueRouter
//在new 路由對象的時候,可以為構造函數(shù)碎赢,傳遞一個配置對象
var routerObj = new VueRouter({
//route 這個配置對象中的 route 表示【路由匹配規(guī)則】的意思
routes:{
// 路由匹配規(guī)則
//每個路由規(guī)則低剔,都是一個對象,這個規(guī)則對象肮塞,身上有兩個必須的屬性
// 屬性1: 是path襟齿,表示監(jiān)聽 那個路由的地址
//屬性2: component,表示枕赵,如果路由是前面匹配到的 path 猜欺,則展示 component屬性對應的那個組件
//注意:component 的屬性值,必須是一個組件的模塊對象拷窜,不能組件的應用名稱
{path:'/',component:login;}//默認跳轉頁面
{path:'/',redirect:'.login'}//默認頁第二種方法开皿,重定向,強制性的顯示
{ path:'/login',
component: login,
children:{
//子組件中不需要 / 如果加了/ 就說明你是要從根訪問 在組件不加則是從父 /longin/mine 訪問
{path:'mine', component:mine;}
}
}
{path:'register/:id/:name',component:register;}//第二種傳參方法 path中設置 也叫params方式傳參
},
linkActiveClass: 'myactive',//new VueRouter 的一個屬性點擊時執(zhí)行這個樣式
})
var vm = new Vue({
el:"#app",
data:{},
methods:{},
router: routerObj //將路由規(guī)則對象篮昧,注冊vm實列上赋荆,用來監(jiān)聽 URL 地址的變化 ,然后展示對應的組件
})
vue-Router實現(xiàn)默認頁多組件
<div id='#app'>
<!--router-view name 指定要渲染的組件名-->
<router-view name='header'></router-view>
<router-view name='left'></router-view>
<router-view name='main'></router-view>
</div>
//css仔細想 完成經(jīng)典布局
let header = {
template:"<div class='header_css'>這是一個頭部</div>"
}
let left= {
template:"<div class='left_css'>這是一個左側</div>"
}
let main = {
template:"<div class='main_css'>這是一個主體</div>"
}
var router = new VueRouter({
routes:[
{
path:'/',
components:{ //需要注意的是 一個頁面要個組件是 components
'default':header, //默認的
"left":left,
"main":main
}
}
]
})
滾動行為
使用前端路由恋谭,當切換到新路由時糠睡,想要頁面滾動到頂部,或者時保持原先的滾動位置疚颊,就像重新加載頁面那樣狈孔,vue-router就能做到
ps:這個功能只在支持 history.pushState 的瀏覽器中可用
當創(chuàng)建一個 Router 實例,你可以提供一個 scrollBehavior 方法:
const router = new VueRouter({
routes: [...]
scrollBehavior(to,from,savedPosition){
// return 期望滾動到哪個的位置
}
})
scrollBehavior 方法接收 to 和 from 路由對象材义,第三個參數(shù) savedPosition 當且僅當 popstate 導航(通過瀏覽器的 前進\后退 按鈕觸發(fā))時才可用
路由懶加載
當打包構建應用時均抽,javascript包會變得非常大其掂、影響頁面加載,如果我們能把不同路由對應得組件分割成不同得代碼塊,然后當路由訪問的時候才在家對應組件攘乒,這樣更加高效
結合Vue的異步組件和webpack的代碼分割功能惋鹅,輕松實現(xiàn)路由組件的懶加載。
首先闰集,可以將異步組件定義為返回一個Promise的工廠函數(shù)
const Foo = () => Promise.resolve({// 組件定義對象})
第二,在webpack2中爽雄,我們可以使用動態(tài) import語法來定義代碼分塊import('./Foo.vue')
ps: 如果使用的時babel沐鼠,你將需要添加 sybtax-dynamic-import 插件,才能使Babel可以正確的解析語法
結合這兩者迟杂,這就使如何定義一個能夠被webpack自動代碼分割的異步組件
const Foo = () => import('./Foo.vue')
在路由配置中什么都不需要改變,只需要像往常一樣使用
Foo:const router = new VueRouter({
routes: [{
path: '/foo', component: Foo
}]
})
把組件按組分塊
有時候我們想把某個路由下的所有組件都打包在同個異步塊中排拷,只需要使用命名 chunk侧漓,一個特殊的注釋語法來提高chunk name(需要webpack>2.4)
const Foo = () => import(/* webpackChunkName: "group-foo" */ './Foo.vue')
webpack 會將任何一個異步模塊與相同的塊名稱組合到相同的異步塊中
nrm的安裝使用
作用:提供一些最常用的npm包鏡像地址,能夠讓我們快速切換安裝包的服務器地址监氢;
什么是鏡像:原包剛一開始只是存在國外的npm服務器布蔗,但是由于網(wǎng)絡原因,經(jīng)常訪問不到浪腐,這時候纵揍,我們有在國內,創(chuàng)建一個和官網(wǎng)完全一樣的npm服務器议街,只不過泽谨,數(shù)據(jù)都是從人家那里拿過來的,使用方式完全一樣特漩;
1.運行npm i nrm -g
全局安裝npm
包
2.使用npm ls
查看當前所有可用的鏡像源地址以及當前所使用的鏡像源地址吧雹;
3.使用nrm use npm
或 nrm use taobao
切換不同的鏡像源地址
注意:nrm只是單純的提供了幾個常用的下載包URL地址,并能夠讓我們在這幾個地址之間很方便的進行切換涂身,但是雄卷,我們每次裝包的時候,使用的 裝包工具都是
npm
Webpack
-
在網(wǎng)頁中會引用那些常見的靜態(tài)資源:
-
js
- .js .jsx .conffe .ts(TypeScript)
-
css
- .css .less .sass(更新以后叫 scss 基本上和less 只是語法不同)
-
Images
- .jpg .png .git .bmp .svg .webp
-
字體文件(Fonts)
- .svg .ttf .eot .woff .woff2
-
模板文件
- .ejs .jade .vue【這是在webpack中定義組件的方式】
-
-
網(wǎng)頁引入靜態(tài)資源多了以后有什么問題蛤售?丁鹉?
網(wǎng)頁加載速度慢妒潭,因為 我們要發(fā)起很多的二次請求;
要處理錯綜復雜的依賴關系
-
如何解決上述問題
合并揣钦,壓縮雳灾,精靈圖,圖片Base64編碼
可以使用requireJs 或 webpack解決各個包之間的復雜依賴關系
-
什么是webpack/gulp
webpack他是基于Node.js開發(fā)的模塊化打包工具
gulp基于流的自動化構建工具,流,一個操作的輸出結果作為另一個操作的輸入
-
如何完美實現(xiàn)上述的2種方案
-
使用Gulp可以進行html拂盯,css佑女,img的壓縮打包谈竿,是自動化構建工具空凸,可以將多個js文件或是css壓縮成一個文件呀洲,并且可以壓縮為一行道逗,以此來減少文件體積滓窍,加快請求速度和減少請求次數(shù)吏夯;并且gulp有task定義處理事務噪生,從而構建整體流程跺嗽,它是基于流的自動化構建工具
-
優(yōu)點:
小巧 靈活 方便去做一些靈活任務的處理
它能自動化地完成 前端代碼的測試桨嫁、檢查、合并弥鹦、壓縮、格式化膝晾、瀏覽器自動刷新血当、部署文件生成臊旭,并監(jiān)聽文件在改動后重復指定的這些步驟
-
-
Webpack是前端構建工具离熏,實現(xiàn)了模塊化開發(fā)和文件處理滋戳。他的思想就是“萬物皆為模塊”奸鸯,它能夠將各個模塊進行按需加載娄涩,不會導致加載了無用或冗余的代碼钝满。所以他還有個名字叫前端模塊化打包工具
借助于webpack這個前端自動化構建工具弯蚜,可以完美實現(xiàn)資源的合并碎捺,打包收厨,壓縮,混淆等諸多功能钦椭;
webpack打包的過程 見筆記
-
[圖片上傳失敗...(image-3cca2e-1553654416703)]
-
webpack安裝的兩種方式:
運行
npm i webpack -g
全局安裝webpack碑诉,這樣就能在全局使用webpack的命令在項目跟目錄中運行
npm i webapck --save-dev
安裝到項目依賴中
- 初步使用webpck打包構建列表隔行變色案列
import $ form 'jquery'
$('#list li:even').css('backgroundColor','#0f6');
$('#list li:odd').css('backgroundColor','pink');
1. 運行`npm init`初始化項目,使用npm管理項目中的依賴包
2. 創(chuàng)建項目基本的目錄結構
3. 使用`npm i jquery --save`(ES6寫法)安裝jquery類庫(`const $ = require("jquery")第二種方法`)
4. 創(chuàng)建`main.js`并書寫各行變色的代碼邏輯:
5. 直接在頁面上引用`main.js`會報錯,因為游覽器不認識`import`這種高級的js語法快毛,需要使用webpack進行處理唠帝,webpack默認會把這種高級的語法轉換為低級的游覽器能識別的語法没隘;
6. 運行`webpack 入口文件路徑 輸出文件路徑`對`main.js`進行處理;
//webpack 3x 版本
webpack src/js/main.js dist/bundle.js
之后webpack 進入webapck筆記
什么是Vuex
概念:vuex是 vue 配套的公共數(shù)據(jù)管理工具赶熟,它有把一些共享的數(shù)據(jù)映砖,保存到vuex中邑退,方便整個程序中的任何組件直接獲取或修改我們的公共數(shù)據(jù)地技;
Vuex是為了保存組件之間共享數(shù)據(jù)而誕生的莫矗,如果組件之間有要共享的數(shù)據(jù)作谚,可以直接掛載到vuex中,而不必通過 父子組件之間傳值了双吆,如果組件的數(shù)據(jù)不需要共享,此時回官,這些不需要共享的私有數(shù)據(jù)歉提,沒有必要放到vuex中苔巨;
只有共享的數(shù)據(jù),才有權利放到vuex中蜻韭; 組件內部私有的數(shù)據(jù)肖方,只要放到組件 data 中即可析桥;
props 和 data 和 vuex的區(qū)別
Vuex 是一個全局的共享數(shù)據(jù)存儲區(qū)域泡仗,就相當于一個數(shù)據(jù)的倉庫
使用Vuex
import Vuex from 'vuex'
Vue.use(Vuex)
// 如果在模塊化構建系統(tǒng)中娩怎,請確保在開頭調用了 Vue.use(Vuex)
const store = new Vuex.Store({
state: {
// state 可以想象成 組件中的 data ,專門用來存儲數(shù)據(jù)的
// 如果在 組件中,想要訪問,store 中的數(shù)據(jù),只能通過 this.$store.state.*** 來訪問
count: 0
},
mutations: {
// 注意:如果要操作 stroe 中的 state 值旦事,只能通過 調用 mutations 提供的方法谷遂,才能操作定義的數(shù)據(jù)肾扰,不推薦直接操作 state 中的數(shù)據(jù),應為萬一導致了數(shù)據(jù)的紊亂窗悯,不能快速定位到錯誤的原因蒋院,因為每個組件都有可能操作數(shù)據(jù)的方法欺旧;
// mutations 里的方法第一個參數(shù)固定是state
// 在組件中調用mutations中的方法辞友,要使用 this.$store.commit('方法名')
// 傳參方法 this.$store.commit('方法名','傳參值'),注意mutations內部方法只能有2個參數(shù) 如果要傳多個就傳一個對象
increment (state,a) { //a 接收參數(shù)值
state.count++
},
getters: {
//注意:這里的getters茵瀑,只負責對外提供數(shù)據(jù),不負責修改數(shù)據(jù)扛施,如果想要修改 state 中的數(shù)據(jù),請去找 mutations
doneTodos: state => {
return '當前count值是:'+ state.count
}
//getters就相當于是 store 的計算屬性, 只要 state 中的數(shù)據(jù)發(fā)生了變化妄荔,那么正好 getters 也引用了這個數(shù)據(jù)啦租,那么就會立即觸發(fā) getters 來重新求值
}
}})