vue(中心思想:替換app元素)
vue腳手架
- 把vue-cli 安裝到全局:npm install vue-cli -g或者yarn add vue-cli -g
vue-cli:提供了一些vue的命令籽慢,用來(lái)初始化一個(gè)基于webpack的vue項(xiàng)目- 命令一:vue init webpack-simple vue-book(自定義的項(xiàng)目名稱)
- 命令二(一般用這個(gè)):vue init webpack vue-book(自定義的項(xiàng)目名稱)
- 問(wèn)題:重新安裝less宣肚、less-loader 暖呕、axios路鹰、boostrap
- 如果用第三方插件需要use一下 譬如:
//查找路徑vue ---> package.json ---> main.js
import Vue from 'vue'
//第三方模塊
import VueAwesomeSwiper from 'vue-awesome-swiper';
Vue.use(VueAwesomeSwiper);
是一個(gè)MVVM框架评抚,m-model v-view vm-view-model
model:數(shù)據(jù)模型 view:視圖 view-model:數(shù)據(jù)和視圖之間數(shù)據(jù)的傳遞
MVVM
- Mvvm定義MVVM是Model-View-ViewModel的簡(jiǎn)寫(xiě)。即模型-視圖-視圖模型横缔∧杉牛【模型】指的是后端傳遞的數(shù)據(jù)∑粤妫【視圖】指的是所看到的頁(yè)面堤如。【視圖模型】mvvm模式的核心窒朋,它是連接view和model的橋梁搀罢。它有兩個(gè)方向:一是將【模型】轉(zhuǎn)化成【視圖】,即將后端傳遞的數(shù)據(jù)轉(zhuǎn)化成所看到的頁(yè)面侥猩。實(shí)現(xiàn)的方式是:數(shù)據(jù)綁定榔至。二是將【視圖】轉(zhuǎn)化成【模型】,即將所看到的頁(yè)面轉(zhuǎn)化成后端的數(shù)據(jù)欺劳。實(shí)現(xiàn)的方式是:DOM 事件監(jiān)聽(tīng)唧取。這兩個(gè)方向都實(shí)現(xiàn)的,我們稱之為數(shù)據(jù)的雙向綁定划提》愕埽總結(jié):在MVVM的框架下視圖和模型是不能直接通信的。它們通過(guò)ViewModel來(lái)通信鹏往,ViewModel通常要實(shí)現(xiàn)一個(gè)observer觀察者淡诗,當(dāng)數(shù)據(jù)發(fā)生變化,ViewModel能夠監(jiān)聽(tīng)到數(shù)據(jù)的這種變化,然后通知到對(duì)應(yīng)的視圖做自動(dòng)更新韩容,而當(dāng)用戶操作視圖款违,ViewModel也能監(jiān)聽(tīng)到視圖的變化,然后通知數(shù)據(jù)做改動(dòng)群凶,這實(shí)際上就實(shí)現(xiàn)了數(shù)據(jù)的雙向綁定插爹。并且MVVM中的View 和 ViewModel可以互相通信。
- MVC的定義:MVC是Model-View- Controller的簡(jiǎn)寫(xiě)座掘。即模型-視圖-控制器递惋。M和V指的意思和MVVM中的M和V意思一樣。C即Controller指的是頁(yè)面業(yè)務(wù)邏輯溢陪。使用MVC的目的就是將M和V的代碼分離【龋‘MVC是單向通信形真。也就是View跟Model,必須通過(guò)Controller來(lái)承上啟下超全。MVC和MVVM的區(qū)別并不是VM完全取代了C咆霜,ViewModel存在目的在于抽離Controller中展示的業(yè)務(wù)邏輯,而不是替代Controller嘶朱,其它視圖操作業(yè)務(wù)等還是應(yīng)該放在Controller中實(shí)現(xiàn)蛾坯。也就是說(shuō)MVVM實(shí)現(xiàn)的是業(yè)務(wù)邏輯組件的重用。由于mvc出現(xiàn)的時(shí)間比較早疏遏,前端并不那么成熟脉课,很多業(yè)務(wù)邏輯也是在后端實(shí)現(xiàn),所以前端并沒(méi)有真正意義上的MVC模式财异。而我們今天再次提起MVC倘零,是因?yàn)榇笄岸说膩?lái)到,出現(xiàn)了MVVM模式的框架戳寸,我們需要了解一下MVVM這種設(shè)計(jì)模式是如何一步步演變過(guò)來(lái)的呈驶。2. 為什么會(huì)有MVVM框架?在過(guò)去的10年中疫鹊,我們已經(jīng)把很多傳統(tǒng)的服務(wù)端代碼放到了瀏覽器中袖瞻,這樣就產(chǎn)生了成千上萬(wàn)行的javascript代碼,它們連接了各式各樣的HTML 和CSS文件拆吆,但缺乏正規(guī)的組織形式聋迎,這也就是為什么越來(lái)越多的開(kāi)發(fā)者使用javascript框架。比如:angular锈拨、react砌庄、vue。瀏覽器的兼容性問(wèn)題已經(jīng)不再是前端的阻礙。前端的項(xiàng)目越來(lái)越大娄昆,項(xiàng)目的可維護(hù)性和擴(kuò)展性佩微、安全性等成了主要問(wèn)題。當(dāng)年為了解決瀏覽器兼容性問(wèn)題萌焰,出現(xiàn)了很多類(lèi)庫(kù)哺眯,其中最典型的就是jquery。但是這類(lèi)庫(kù)沒(méi)有實(shí)現(xiàn)對(duì)業(yè)務(wù)邏輯的分成扒俯,所以維護(hù)性和擴(kuò)展性極差奶卓。綜上兩方面原因,才有了MVVM模式一類(lèi)框架的出現(xiàn)撼玄。比如vue,通過(guò)數(shù)據(jù)的雙向綁定夺姑,極大了提高了開(kāi)發(fā)效率。3. MVVM框架:VUE的介紹Vue就是基于MVVM模式實(shí)現(xiàn)的一套框架掌猛,在vue中:Model:指的是js中的數(shù)據(jù)盏浙,如對(duì)象,數(shù)組等等荔茬。View:指的是頁(yè)面視圖viewModel:指的是vue實(shí)例化對(duì)象為什么說(shuō)VUE是一個(gè)漸進(jìn)式的javascript框架, 漸進(jìn)式是什么意思废膘?1.如果你已經(jīng)有一個(gè)現(xiàn)成的服務(wù)端應(yīng)用,你可以將vue 作為該應(yīng)用的一部分嵌入其中慕蔚,帶來(lái)更加豐富的交互體驗(yàn);2.如果你希望將更多業(yè)務(wù)邏輯放到前端來(lái)實(shí)現(xiàn)丐黄,那么VUE的核心庫(kù)及其生態(tài)系統(tǒng)也可以滿足你的各式需求(core+vuex+vue-route)。和其它前端框架一樣孔飒,VUE允許你將一個(gè)網(wǎng)頁(yè)分割成可復(fù)用的組件灌闺,每個(gè)組件都包含屬于自己的HTML、CSS十偶、JAVASCRIPT以用來(lái)渲染網(wǎng)頁(yè)中相應(yīng)的地方菩鲜。3.如果我們構(gòu)建一個(gè)大型的應(yīng)用,在這一點(diǎn)上惦积,我們可能需要將東西分割成為各自的組件和文件接校,vue有一個(gè)命令行工具,使快速初始化一個(gè)真實(shí)的工程變得非常簡(jiǎn)單(vue init webpack my-project)狮崩。我們可以使用VUE的單文件組件蛛勉,它包含了各自的HTML、JAVASCRIPT以及帶作用域的CSS或SCSS睦柴。以上這三個(gè)例子诽凌,是一步步遞進(jìn)的,也就是說(shuō)對(duì)VUE的使用可大可小坦敌,它都會(huì)有相應(yīng)的方式來(lái)整合到你的項(xiàng)目中侣诵。所以說(shuō)它是一個(gè)漸進(jìn)式的框架痢法。VUE最獨(dú)特的特性:響應(yīng)式系統(tǒng)VUE是響應(yīng)式的(reactive),也就是說(shuō)當(dāng)我們的數(shù)據(jù)變更時(shí)杜顺,VUE會(huì)幫你更新所有網(wǎng)頁(yè)中用到它的地方财搁。關(guān)于這個(gè)響應(yīng)式原理,官方已經(jīng)講得很清楚躬络,不懂的同學(xué)尖奔,可以去官網(wǎng) 查看。我們講一下主流框架實(shí)現(xiàn)雙向綁定(響應(yīng)式)的做法:1. 臟值檢查:angularangular.js 是通過(guò)臟值檢測(cè)的方式比對(duì)數(shù)據(jù)是否有變更穷当,來(lái)決定是否更新視圖提茁,最簡(jiǎn)單的方式就是通過(guò) setInterval() 定時(shí)輪詢檢測(cè)數(shù)據(jù)變動(dòng),當(dāng)然Google不會(huì)這么low馁菜,angular只有在指定的事件觸發(fā)時(shí)進(jìn)入臟值檢測(cè)茴扁,大致如下: DOM事件,譬如用戶輸入文本火邓,點(diǎn)擊按鈕等丹弱。( ng-click ) XHR響應(yīng)事件 (
location ) Timer事件(
interval ) 執(zhí)行
apply()在 Angular 中組件是以樹(shù)的形式組織起來(lái)的,相應(yīng)地铲咨,檢測(cè)器也是一棵樹(shù)的形狀。當(dāng)一個(gè)異步事件發(fā)生時(shí)蜓洪,臟檢查會(huì)從根組件開(kāi)始纤勒,自上而下對(duì)樹(shù)上的所有子組件進(jìn)行檢查,這種檢查方式的性能存在很大問(wèn)題隆檀。2.觀察者-訂閱者(數(shù)據(jù)劫持):vueObserver 數(shù)據(jù)監(jiān)聽(tīng)器摇天,把一個(gè)普通的 JavaScript 對(duì)象傳給 Vue 實(shí)例的 data 選項(xiàng),Vue 將遍歷此對(duì)象所有的屬性恐仑,并使用Object.defineProperty()方法把這些屬性全部轉(zhuǎn)成setter泉坐、getter方法。當(dāng)data中的某個(gè)屬性被訪問(wèn)時(shí)裳仆,則會(huì)調(diào)用getter方法腕让,當(dāng)data中的屬性被改變時(shí),則會(huì)調(diào)用setter方法歧斟。Compile指令解析器纯丸,它的作用對(duì)每個(gè)元素節(jié)點(diǎn)的指令進(jìn)行解析,替換模板數(shù)據(jù)静袖,并綁定對(duì)應(yīng)的更新函數(shù)觉鼻,初始化相應(yīng)的訂閱。Watcher 訂閱者队橙,作為連接 Observer 和 Compile 的橋梁坠陈,能夠訂閱并收到每個(gè)屬性變動(dòng)的通知萨惑,執(zhí)行指令綁定的相應(yīng)回調(diào)函數(shù)。Dep 消息訂閱器仇矾,內(nèi)部維護(hù)了一個(gè)數(shù)組庸蔼,用來(lái)收集訂閱者(Watcher),數(shù)據(jù)變動(dòng)觸發(fā)notify 函數(shù)若未,再調(diào)用訂閱者的 update 方法朱嘴。
當(dāng)執(zhí)行 new Vue() 時(shí),Vue 就進(jìn)入了初始化階段粗合,一方面Vue 會(huì)遍歷 data 選項(xiàng)中的屬性萍嬉,并用 Object.defineProperty 將它們轉(zhuǎn)為 getter/setter,實(shí)現(xiàn)數(shù)據(jù)變化監(jiān)聽(tīng)功能隙疚;另一方面壤追,Vue 的指令編譯器Compile 對(duì)元素節(jié)點(diǎn)的指令進(jìn)行解析,初始化視圖供屉,并訂閱Watcher 來(lái)更新視圖行冰, 此時(shí)Wather 會(huì)將自己添加到消息訂閱器中(Dep),初始化完畢。當(dāng)數(shù)據(jù)發(fā)生變化時(shí)伶丐,Observer 中的 setter 方法被觸發(fā)悼做,setter 會(huì)立即調(diào)用Dep.notify(),Dep 開(kāi)始遍歷所有的訂閱者哗魂,并調(diào)用訂閱者的 update 方法肛走,訂閱者收到通知后對(duì)視圖進(jìn)行相應(yīng)的更新。因?yàn)閂UE使用Object.defineProperty方法來(lái)做數(shù)據(jù)綁定录别,而這個(gè)方法又無(wú)法通過(guò)兼容性處理朽色,所以Vue 不支持 IE8 以及更低版本瀏覽器。另外组题,查看vue原代碼葫男,發(fā)現(xiàn)在vue初始化實(shí)例時(shí), 有一個(gè)proxy代理方法崔列,它的作用就是遍歷data中的屬性梢褐,把它代理到vm的實(shí)例上,這也就是我們可以這樣調(diào)用屬性:vm.aaa等于vm.data.aaa峻呕。好了利职,關(guān)于mvvm設(shè)計(jì)模式及vue的雙向綁定原理就講到這。說(shuō)實(shí)話瘦癌,寫(xiě)這篇文章很費(fèi)腦子猪贪,我們也參考了很多人的文章,可以說(shuō)是總結(jié)的一個(gè)大雜燴讯私。最近這兩年Vue太火了热押,不懂VUE都不好意思說(shuō)自己是干前端的西傀,程序思維現(xiàn)在正著力把之前寫(xiě)的項(xiàng)目改造成vue的方式,目前已遇到了一堆坑桶癣,之后我們會(huì)把vue實(shí)戰(zhàn)過(guò)程中的坑給大家總結(jié)一下拥褂,方便大家更好的學(xué)習(xí)。歡迎您繼續(xù)關(guān)注程序思維牙寞。
MVC:model view controller :數(shù)據(jù)單項(xiàng)通信饺鹃,只能通過(guò)數(shù)據(jù)影響視圖;
MVVM:model(后端返回的數(shù)據(jù))和view是不能直接進(jìn)行通信的间雀;需要通過(guò)view-model 來(lái)進(jìn)行數(shù)據(jù)的傳遞悔详;model-->view:綁定數(shù)據(jù);model-->view:DOM的監(jiān)聽(tīng)事件【發(fā)布訂閱模式】
- 數(shù)據(jù)是響應(yīng)式的惹挟,當(dāng)數(shù)據(jù)發(fā)生變化茄螃,會(huì)自動(dòng)影響視圖,當(dāng)視圖數(shù)據(jù)發(fā)生變化连锯,會(huì)影響數(shù)據(jù)---> 數(shù)據(jù)的雙向綁定
- vue中常見(jiàn)的指令
v-model:一般用于表單元素归苍,體現(xiàn)雙向綁定,單選框用于一組和name作用一樣运怖,具有互斥的作用拼弃,多選框(1個(gè))false或者true,多個(gè)多選框v-model放的是數(shù)據(jù)摇展,也需要有value值肴敛;在使用下拉框時(shí),如果select有multiple吗购;那么v-model綁定的值最好是一個(gè)數(shù)組類(lèi)型
如果v-model綁定的值不是一個(gè)數(shù)組類(lèi)型的,那么瀏覽器解析吧其換成布爾類(lèi)型砸狞;同時(shí)選中捻勉,同時(shí)不被選中;所以需要給每個(gè)input加上value屬性值進(jìn)行區(qū)分
v-text:把數(shù)據(jù)綁定DOM元素中刀森,具有響應(yīng)式踱启;并且會(huì)把之前的進(jìn)行覆蓋
v-html:可以識(shí)別標(biāo)簽
v-for:要循環(huán)誰(shuí),把v-for放在誰(shuí)身上研底;
v-once:事件埠偿、一次
v-if、 v-else::當(dāng)屬性值是true榜晦,則顯示當(dāng)前的元素冠蒋;為false,那么顯示v-else的元素乾胶,控制的是DOM元素的存在抖剿,不是控制display:none
v-else-if:
v-once:頁(yè)面指揮綁定一次朽寞,視圖和數(shù)據(jù)不在有任何的關(guān)聯(lián),放在小胡子里面
v-cloak:元素加在數(shù)據(jù)比較多斩郎,vue解析事件比較長(zhǎng)脑融;為了防止{{}}出現(xiàn),給該元素加上v-cloak屬性缩宜,直到vue中吧DOM數(shù)據(jù)插入到真實(shí)DOM中時(shí)肘迎,當(dāng)前元素顯示;在css中加樣式[v-cloak]{display:none}锻煌;直接用v-text也可以
v-show:控制元素的顯示隱藏妓布;通過(guò)控制css的display屬性;頻繁操作dom元素
v-bind:用于綁定動(dòng)態(tài)的屬性炼幔,最后簡(jiǎn)寫(xiě)成一個(gè):就可以取到動(dòng)態(tài)的屬性
v-:自定義屬性秋茫;v-開(kāi)頭的屬性值是變量;不是字符串
v-on: <div @click="fn($event,1)" >{{msg}} < /div>- 如果在綁定時(shí)乃秀,fn不帶()肛著,那么函數(shù)會(huì)默認(rèn)接收一個(gè)事件對(duì)象e;mouseEvent跺讯,
- 如果綁定時(shí)枢贿,帶有(),那么不會(huì)默認(rèn)接收事件對(duì)象刀脏,
- 既需要事件對(duì)象局荚,又需要參數(shù),需要在綁定參數(shù)加一個(gè)($event),后面的參數(shù)才是真正的實(shí)參
input 單選input type=‘redio’愈污;v-model=‘b’耀态;value=‘內(nèi)容’ onchange:當(dāng)input的value發(fā)生改變時(shí),就會(huì)觸發(fā)這個(gè)change事件暂雹;在input由于值發(fā)生變化首装,單只觸發(fā)的事件一般都用change事件 onclick:點(diǎn)擊的時(shí)候,立即執(zhí)行這個(gè)行為綁定的方法
@blur="cancel" v-focus
小胡子語(yǔ)法:{{}}不僅僅可以取值杭跪,還可以放運(yùn)算表達(dá)式
在小胡子語(yǔ)法中遇到null仙逻,遇到undefined是沒(méi)顯示任何內(nèi)容的
- 事件修飾符;@click.prevent="fn"
.prevent:阻止事件的默認(rèn)行為
.stop:阻止事件的冒泡行為
.capture:事件行為在捕獲
.once:只執(zhí)行一次
.self:只有自己觸發(fā)自己時(shí)涧尿,自己的事件行為才會(huì)執(zhí)行
- 鍵盤(pán)事件的修飾符:@keydown.enter="fn". .數(shù)字或者.字母也可以
.enter:回車(chē)鍵
.esc:退出
.delete:退格
.space:空格
.tab:tab鍵
.left/.right./.up/.down 上下左右
- data中數(shù)據(jù)最終會(huì)放在vue的實(shí)例上
- vue 會(huì)遍歷data中的所有的屬性系奉,通過(guò)Object.defineProperty把所有的屬性轉(zhuǎn)換成get和set方法
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<input type="text" id="box">
<script>
let obj = {};
// 第三方變量;為了防止獲取obj.name 時(shí)出現(xiàn)無(wú)限循環(huán)姑廉;
let temp = {};
// 讓對(duì)象中的值發(fā)生變化缺亮,那么input內(nèi)容也跟著變化,當(dāng)input框中值發(fā)生改變庄蹋,對(duì)象的值也跟著變化瞬内;name;
Object.defineProperty(obj,"name",{
get(){
return temp.name;// get 的返回值就是obj.name 的獲取值迷雪;
},
set(val){
temp.name = val;
box.value = val;
}
});
// VUE利用DOM事件監(jiān)聽(tīng)機(jī)制;
// 視圖 影響數(shù)據(jù)虫蝶;
box.addEventListener("input",function () {
obj.name = this.value;// 把input框的值賦值給obj.name屬性章咧;
})
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="keywords" content=""/>
<meta name="description" content=""/>
<title>珠峰培訓(xùn)</title>
<link rel="icon" href=""/>
<link rel="stylesheet" href="">
</head>
<body>
<script src="node_modules/vue/dist/vue.js"></script>
<div id="app">
{{a.school}}
</div>
<script>
let vm = new Vue({
el:'#app',
data:{
a:{},
}
});
//vm.a.school = 'zfpx',新增的屬性不會(huì)有響應(yīng)式能真,但是如果原先有這個(gè)屬性可以監(jiān)聽(tīng)
//1赁严、直接覆蓋原有的空間地址;新的地址進(jìn)行替換粉铐;屬性都有響應(yīng)式
vm.a = {school:'zfpx'};
//2疼约、vm.$set() 設(shè)置data對(duì)象的屬性
console.log(vm);
vm.$set(vm.a,'school','珠峰00')
</script>
</body>
</html>
let vm = new Vue({
el:'#app',
data:{
arr:[1,2,3,4,5,6]
}
});
//1、通過(guò)索引不可以修改data中數(shù)組的某一項(xiàng)
//2蝙泼、通過(guò)改變數(shù)組的length程剥,也不能實(shí)現(xiàn)響應(yīng)式
//3、通過(guò)原型上的方法汤踏,可以對(duì)數(shù)組實(shí)現(xiàn)修改织鲸;
//4、數(shù)組的方法中溪胶,原有數(shù)組發(fā)生改變:pop搂擦、push、shift哗脖、unshift瀑踢、splice、sort才避、reverse橱夭,另一個(gè)方法可以給vm.arr重新賦值
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<ul>
<!--v-for : Array -->
<!--v-for : Object-->
<!--v-for : number -->
<!--v-for : string -->
<!--要循環(huán)誰(shuí),就把v-for放在誰(shuí)在身上-->
<!--(a,index) in arr : a 代表是數(shù)組的每一項(xiàng)桑逝,index代表索引-->
<!--<li v-for="(a,index) in arr">{{a}}{{index}}</li>-->
<!--<li v-for="a in num">{{a}}</li>-->
<!--<li v-for="a in str">{{a}}</li>-->
<!--在循環(huán)對(duì)象中徘钥,如果只有一個(gè)值,那么得到是屬性值肢娘;第二個(gè)參數(shù)代表是屬性名,第三個(gè)代表的是索引-->
<!--<li v-for="(a,b,index) in obj">{{a}}{}{{index}}</li>-->
<li v-for="a in arr">
<ul>
<li v-for="b in a">{舆驶}</li>
</ul>
</li>
</ul>
</div>
<script src="node_modules/vue/dist/vue.js"></script>
<script>
let vm = new Vue({
el:"#app",
data:{
arr:[[1,2,3],[4,5,6],[7,8,9]],
num:5,
str:"zfpx",
obj:{name:"12",age:"34",sex:"56"}
}
});
</script>
</body>
</html>
data的屬性和methods中的屬性不能重名
data的屬性和fillter中的屬性能重名
methods的屬性和fillter中的屬性能重名
computed中的屬性不能和data或者methods中的屬性名重名
watch都可以重名
let vm = new Vue({
el:'#app',綁定
data:{},數(shù)據(jù)
methods:{},方法
created(){},一開(kāi)始就執(zhí)行橱健,
computed:{},傳一個(gè)對(duì)象,對(duì)象中有g(shù)et和set方法沙廉;傳一個(gè)方法拘荡,默認(rèn)走get,計(jì)算屬性
watch:{},監(jiān)聽(tīng)數(shù)據(jù)
template:'',
filters:{},過(guò)濾器撬陵,方法中有兩個(gè)參珊皿,第一個(gè)參數(shù)是前面這個(gè)元素网缝,第二個(gè)參數(shù)是傳進(jìn)來(lái)的
directives:{},自定義方法,自動(dòng)執(zhí)行蟋定,函數(shù)的名字和自定義的名字必須一致粉臊;自定義方法第一個(gè)參數(shù)是此元素,第二個(gè)參數(shù)是個(gè)對(duì)象驶兜,對(duì)象中value值是我們需要的
})
computed
computed :計(jì)算的屬性會(huì)緩存
checkAll:這個(gè)屬性的屬性值是由下面兩個(gè)input的v-model計(jì)算的來(lái)的扼仲;當(dāng)下面有一個(gè)是false,checkAll就是false抄淑,兩個(gè)都是true屠凶,結(jié)果是true;
在computed中的肆资,屬性都有一個(gè)get和一個(gè)sat方法矗愧;當(dāng)獲取checkAll時(shí),會(huì)執(zhí)行g(shù)et方法,那么checkAll是get方法的返回值
computed中的屬性都會(huì)被vue實(shí)例所代理蛀序,最終放在實(shí)例的屬性中
computed中的屬性不能和data或者methods中的屬性名重名
computed屬性還可以是一個(gè)函數(shù)典徊,那么函數(shù)執(zhí)行會(huì)默認(rèn)調(diào)用get方法,那么sum函數(shù)執(zhí)行的返回值就是sum這個(gè)屬性的屬性值
computed不支持異步的方法纽哥,watch可以支持異步的方法
computed的數(shù)據(jù)不需要再data有,但是watch數(shù)據(jù)必須存在于data中
如果一個(gè)屬性依賴于其他屬性計(jì)算而來(lái)栖秕,那么這個(gè)屬性最好用computed春塌;因?yàn)閏omputed計(jì)算的屬性會(huì)緩存
- computed:
1、支持緩存簇捍,只有依賴數(shù)據(jù)發(fā)生改變只壳,才會(huì)重新進(jìn)行計(jì)算
2、不支持異步
3暑塑、如果一個(gè)屬性是由其他屬性計(jì)算而來(lái)的吼句,這個(gè)屬性依賴于其他屬性,是多對(duì)一事格;一般用computed惕艳;
4、如果computed屬性屬性值是函數(shù)驹愚,那么默認(rèn)會(huì)走get方法远搪;函數(shù)的返回值就是屬性的屬性值;
- watch
1逢捺、不支持緩存谁鳍,數(shù)據(jù)變,直接會(huì)觸發(fā)響應(yīng)的操作
2、watch支持異步
3倘潜、當(dāng)一個(gè)屬性發(fā)生變化是绷柒,需要執(zhí)行對(duì)應(yīng)的操作;一對(duì)多
computed:{
// computed :計(jì)算的屬性會(huì)緩存
//checkAll:這個(gè)屬性的屬性值是由下面兩個(gè)input的v-model計(jì)算的來(lái)的涮因;當(dāng)下面有一個(gè)是false废睦,checkAll就是false,兩個(gè)都是true蕊退,結(jié)果是true郊楣;
//在computed中的,屬性都有一個(gè)get和一個(gè)sat方法瓤荔;當(dāng)獲取checkAll時(shí)净蚤,會(huì)執(zhí)行g(shù)et方法,那么checkAll是get方法的返回值
//computed中的屬性都會(huì)被vue實(shí)例所代理输硝,最終放在實(shí)例的屬性中
//computed中的屬性不能和data或者methods中的屬性名重名
checkAll:{
get(){
return this.products.every(item => item.isSelected)
//checkAll 會(huì)依賴item的isSelected屬性執(zhí)行g(shù)et方法今瀑;由于item發(fā)生改變,所以會(huì)再次觸發(fā)get方法点把;先執(zhí)行set再執(zhí)行g(shù)et橘荠,如果return 固定值,不會(huì)再執(zhí)行g(shù)et方法
//computed屬性會(huì)被緩存郎逃,觸發(fā)當(dāng)依賴的屬性(別人的某個(gè)屬性可以影響自己的屬性)發(fā)生改變時(shí)哥童,會(huì)調(diào)用get方法,在頁(yè)面中需要獲取這個(gè)值(dom元素必須存在)
},
set(val) {
this.products.forEach(item => item.isSelected = val)
//會(huì)把當(dāng)前的值value傳給set的參數(shù)褒翰;true/false
}
}
},
//<td colspan="6">總價(jià)格:{{sum | toFixed(2)}}</td>
sum(){
//計(jì)算出所有選中商品的總價(jià)
return this.products.reduce((prev,next)=>{
//如果當(dāng)前的商品是false贮懈,不需要進(jìn)行求和計(jì)算;但是需要把以前進(jìn)行求和結(jié)果傳給下一次的計(jì)算求和
if(!next.isSelected) {return prev}
return prev + next.productPrice * next.productCount
},0);
}
watch
watch:{
a(newVal,oldVal){
// 監(jiān)聽(tīng)a屬性优训,當(dāng)a屬性發(fā)生變化朵你,會(huì)這行這個(gè)函數(shù);
// watch會(huì)把最新的值和上一次的值傳給這個(gè)函數(shù)揣非;第一個(gè)接收新的數(shù)值抡医,第二個(gè)接收上一次的值;
//console.log(newVal);
//console.log(oldVal);
setTimeout(()=>{
this.msg = "";
if(newVal.length>5){
this.msg = "太長(zhǎng)了"
}
if(newVal.length<3){
this.msg = "太短了";
}
},2000);
// 在工作中早敬,能用computed忌傻,就不要用watch;
}
}
})
// 1. MVVM模式
// 2.vue雙向數(shù)據(jù)綁定原理
// 3.vue的聲明周期
// 4.vue 中computed和watch有什么區(qū)別;
// 5.用過(guò)VUEX嗎搞监;
transition-group
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" href="node_modules/animate.css/animate.css">
</head>
<body>
<div id="app">
<input type="text" v-model="a">
<!--解析出一個(gè)span標(biāo)簽-->
<transition-group enter-active-class="animated bounceInUp" leave-active-class="animated bounceOutDown">
<!--transition-group :子元素會(huì)進(jìn)行復(fù)用芯勘;應(yīng)該給每一個(gè)元素加一個(gè)標(biāo)識(shí);區(qū)分是不同的元素腺逛;元素就不再進(jìn)行復(fù)用-->
<!--key 最好不要相同-->
<div v-for="(val,index) in newArr" :key="index">{{val}}</div>
</transition-group>
</div>
<script src="node_modules/vue/dist/vue.js"></script>
<script>
let vm = new Vue({
el:"#app",
data:{
a:"",
query:[1,2,3,4,5],// 存儲(chǔ)值;
},
computed:{
// newArr: 是根據(jù)input中的輸入值發(fā)生變化;根據(jù)input輸入的內(nèi)容棍矛;得出一個(gè)最新的數(shù)組安疗;
newArr(){
return this.query.filter(item=>item==this.a);
}
}
})
</script>
</body>
</html>
- v-bind的class
class中傳一個(gè)對(duì)象,譬如class='a'够委,v-bind:class{x:true荐类,y:false},- 1茁帽、如果class名字相同玉罐,不會(huì)互相影響;如果樣式相同潘拨,后面的會(huì)把前面的覆蓋
class中傳一個(gè)對(duì)象吊输,譬如class='a',v-bind:class{x:100铁追,y:false}季蚂,- 2、如果動(dòng)態(tài)的class這個(gè)對(duì)象中琅束,class的對(duì)象的屬性名的屬性值如果不是布爾值扭屁,默認(rèn)轉(zhuǎn)成布爾;如果是true涩禀,當(dāng)前class生效料滥;如果false,那么class不生效
class中傳一個(gè)對(duì)象艾船,譬如class='a'葵腹,v-bind:class{a:class1,y:false}['a']- 3丽声、可以通過(guò)對(duì)象獲取屬性名對(duì)應(yīng)的屬性值
class中傳一個(gè)數(shù)組礁蔗,譬如class='a',v-bind:class[class1雁社,class2]浴井、v-bind:class[class1,class2][0]
- v-bind的style
v-bind:style霉撵;動(dòng)態(tài)綁定樣式磺浙,屬性值可以是一個(gè)對(duì)象,或者是一個(gè)數(shù)組徒坡;如果是對(duì)象撕氧,里面可以存儲(chǔ)具體的樣式,如果是數(shù)組喇完,數(shù)組中的數(shù)據(jù)應(yīng)該是從data中或者computed中拿到的
v-bind:style='{width:'100px'}'
v-bind:style=[bg1,bg2]
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="keywords" content=""/>
<meta name="description" content=""/>
<title>珠峰培訓(xùn)</title>
<link rel="icon" href=""/>
<link rel="stylesheet" href="">
<style>
#app div {
width: 100px;
height: 100px;
background: pink;
position: absolute;
}
#app div:nth-child(2) {
top: 200px;
}
</style>
</head>
<body>
<div id="app">
<div v-drag>1</div>
<div v-drag>2</div>
</div>
<script src="node_modules/vue/dist/vue.js"></script>
<script>
let vm = new Vue({
el: '#app',
directives: {
//這里面存儲(chǔ)的都是自定義的指令
drag(el) {
//drag:第一個(gè)參數(shù)就是拖拽這個(gè)元素
el.onmousedown = function (e) {
let disX = e.pageX - this.offsetLeft;
let disY = e.pageY - this.offsetTop;
document.onmousemove = function (e) {
el.style.left = e.pageX - disX + 'px';
el.style.top = e.pageY - disY + 'px';
};
document.onmouseup = function () {
document.onmousemove=document.onmouseup = null
}
}
}
}
})
</script>
</body>
</html>
//生命周期伦泥;
// vue的實(shí)例具有生命周期;vue實(shí)例在生成時(shí),會(huì)經(jīng)歷一系列的初始化過(guò)程不脯;數(shù)據(jù)的監(jiān)聽(tīng)府怯,編譯模板,實(shí)例掛載DOM元素防楷,或者數(shù)據(jù)更新DOM更新;在執(zhí)行的過(guò)程中牺丙,會(huì)運(yùn)行一些叫做生命周期的鉤子函數(shù);在vue實(shí)例生命周期中的特定的時(shí)間點(diǎn)內(nèi)复局,執(zhí)行的函數(shù)冲簿;
// 生命周期鉤子函數(shù),不能控制其執(zhí)行的順序亿昏;

- this就是vm或者別的實(shí)例的名字
> - vue 中提供一個(gè)行間屬性: ref;
> - this.$refs : 獲取到所有的元素帶有行間屬性ref的屬性峦剔;同名字的會(huì)覆蓋除非是for循環(huán)出來(lái)的
> - this.$set :
> - this.$mount : 掛載 `vue實(shí)例中沒(méi)有指定元素` 在實(shí)例外面,
> - this.$el : 掛載的元素龙优;
> - this.$data:
> - this.$options
> - this.$nextTick,傳一個(gè)回調(diào)函數(shù)羊异,回調(diào)函數(shù)會(huì)等待DOM異步渲染完成執(zhí)行,在異步之前
> - this.$emit : 發(fā)布 彤断,在methods里面
> - $emit存在于每一個(gè)vue的實(shí)例上野舶;
> - 需要和DOM行間的的屬性是保持一致;
> - this.$on: 訂閱
###template (template:"")
- 1.template的屬性值會(huì)把外層div給替換掉宰衙;
- 2.template 只支持一個(gè)子元素平道;組件模板中只能由一個(gè)根元素;如果有多個(gè)元素供炼,需要在外面加一個(gè)元素包裹起來(lái)一屋;
- 3.兩個(gè)不同的寫(xiě)法;
template:"#divs" 或者 template:" < div>< div>< /div>< /div> ",
####slot
```javascript
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<model>
<div slot="aaa">122</div>
<div slot="bbb">223</div>
</model>
</div>
<template id="add">
<div>
<!--<slot name="a"></slot>
<slot name="b"></slot>
<slot></slot>
<slot></slot>
<slot></slot>
<slot></slot>-->
<slot name="bbb"></slot>
<slot name="aaa"></slot>
<div>我的使命</div>
</div>
</template>
<script src="node_modules/vue/dist/vue.js"></script>
<script>
let model={
template:'#add'
};
let vm=new Vue({
el:'#app',
data:{},
components:{
model
}
})
</script>
</body>
</html>
組件
全局組件(Vue.componen 創(chuàng)建+注冊(cè))
組件: 把頁(yè)面中公共部分提煉出來(lái)袋哼,可以進(jìn)行復(fù)用冀墨;Vue.componen是一個(gè)函數(shù),傳兩個(gè)參數(shù)涛贯,第一個(gè)參數(shù)是名字诽嘉,第二個(gè)參數(shù)是一個(gè)對(duì)象,對(duì)象里面有個(gè)data是個(gè)函數(shù)return一個(gè)對(duì)象弟翘,要不然報(bào)錯(cuò)
每個(gè)組件都是一個(gè)vue的實(shí)例虫腋;那么具有生命周期;并且也有data ,computed,methods ,watch這些屬性稀余;
- 1.組件的名字悦冀,在JS中可以帶有-;還可以駝峰的命名;
- 2.在HTML中進(jìn)行引用時(shí)睛琳,支持-盒蟆;但是不支持駝峰踏烙;
- 3.Vue.component 是全局注冊(cè)組件,在其他各個(gè)vue的實(shí)例中历等,可以使用宙帝;
注意順序
局部組件(平行組件和嵌套性組件)
局部組件使用三部曲 :
- 1.創(chuàng)建組件;
- 2.注冊(cè)組件
- 3.使用組件募闲;
嵌套性組件
- 1、必須從內(nèi)部往外部寫(xiě)愿待,要不然找不到
- 2浩螺、最里面的組件有template,但是沒(méi)有components仍侥,其他都有要出,并且components使用的是(內(nèi)組件 + 本組件的數(shù)據(jù))
- 3、最大的注冊(cè)一下
動(dòng)態(tài)組件
<div id="app">
<input type="radio" v-model="title" value="home">home
<input type="radio" v-model="title" value="list">list
<!-- 在使用component這個(gè)自定義組件時(shí)农渊,需要配合:is這個(gè)屬性患蹂,動(dòng)態(tài)綁定一個(gè)組件的名稱;-->
<!--is后面的屬性值是哪個(gè)組件的名稱砸紊,顯示哪個(gè)組件传于;不可以同時(shí)顯示兩個(gè)-->
<keep-alive>
<component v-bind:is="title"></component>
</keep-alive>
<!--<component is="home"></component>-->
</div>
<script src="../0905(zujian)/node_modules/vue/dist/vue.js"></script>
<script>
// 創(chuàng)建組件
// 動(dòng)態(tài)組件進(jìn)行切換時(shí),會(huì)將上一個(gè)組件進(jìn)行銷(xiāo)毀醉顽,然后再掛載最新的組件沼溜;
//keep-alive: 保存了組件第一次生成時(shí)的狀態(tài);以后需要該組件游添,直接讀取緩存中的組件就可以系草;不再執(zhí)行掛載,銷(xiāo)毀唆涝;從而提高了瀏覽器的性能找都;
let home = {
template:"<div>home</div>",
mounted(){
console.log("掛載home")
},
destroyed(){
console.log("已銷(xiāo)毀home")
}
};
let list = {
template:"<div>list</div>",
mounted(){
console.log("掛載list")
},
destroyed(){
console.log("已銷(xiāo)毀list")
}
};
let vm = new Vue({
el: '#app',
data: {
title:"home",
},
// 注冊(cè)組件
components:{
home,list
}
});
</script>
keep-alive
keep-alive標(biāo)簽數(shù)據(jù)走緩存不刷新
數(shù)據(jù)傳遞問(wèn)題 (數(shù)組是單向的)
- 1.把父組件中的數(shù)組綁定子組件中的一個(gè)行間屬性;并且是動(dòng)態(tài)綁定的這個(gè)屬性廊酣;
- 2.利用子組件中的props能耻,去接收一下這個(gè)行間的屬性;
- 3.在子組件template中進(jìn)行使用啰扛;
- 4.數(shù)據(jù)被私有化嚎京,改變的話上級(jí)也變
父?jìng)髯?/h4>
<div id="app">
<son :m="msg"></son>
</div>
let son = {
// 在子組件中,data computed watch methods 這些屬性都有隐解;子組件就是一個(gè)vue的實(shí)例鞍帝;
data(){
return {
val:100//沒(méi)用
}
},
// props
props:["m"],
template:"<div>{{m}}</div>"
};
let vm = new Vue({
el:"#app",
data: {
msg:"hello"
},
components:{
son
}
});
子傳父
如果需要當(dāng)觸發(fā)子組件上的操作改變父組件上的數(shù)據(jù)時(shí),需要在父組件定義方法煞茫,改變自己的值帕涌;在父組件中定義的方法摄凡,需要訂閱到子組件的自定義事件上;當(dāng)觸發(fā)子組件中的某個(gè)操作時(shí)蚓曼,通過(guò)$emit 去觸發(fā)這個(gè)自定義的事件亲澡;讓其對(duì)應(yīng)的父組件的方法執(zhí)行;
<div id="app">
父親: {{money}}
<child :a="money" @changem = "change"></child>
</div>
<script src="./node_modules/vue/dist/vue.js"></script>
<script>
// 子傳父: 如果需要當(dāng)觸發(fā)子組件上的操作改變父組件上的數(shù)據(jù)時(shí)纫版,需要在父組件定義方法床绪,改變自己的值;在父組件中定義的方法其弊,需要訂閱到子組件的自定義事件上癞己;當(dāng)觸發(fā)子組件中的某個(gè)操作時(shí),通過(guò)$emit 去觸發(fā)這個(gè)自定義的事件梭伐;讓其對(duì)應(yīng)的父組件的方法執(zhí)行痹雅;
let vm = new Vue({
el: '#app',
data: {
money:400
},
methods:{
change(val){
console.log(1);
this.money = val;
}
},
components:{
child:{
data(){
return {};
},
props:["a"],
template:"<div>兒子:{{a}}<button @click='fn'>多要錢(qián)</button></div>",
methods:{
fn(){
// $emit存在于每一個(gè)vue的實(shí)例上;
// 需要和DOM行間的的屬性是保持一致糊识;
this.$emit("changem",800)
}
}
}
}
});
</script>
事件車(chē)
<div id="app">
<brother1></brother1>
<brother2></brother2>
</div>
<script src="./node_modules/vue/dist/vue.js"></script>
<script>
// 每一個(gè)vue的實(shí)例都是獨(dú)立的绩社;相互之間不能直接進(jìn)行改變數(shù)據(jù);
// 給兩個(gè)不同的組件找一個(gè)載體赂苗;把共同的方法放在這個(gè)載體上愉耙;
let eventBus = new Vue;// 創(chuàng)建一個(gè)新的vue實(shí)例;
// 在這個(gè)新的實(shí)例上哑梳,有$on: 訂閱 $emit: 發(fā)布;
let brother1 ={
data(){
return {
color:"綠色"
}
},
created(){
// $on : param1 : 自定義事件名稱劲阎, param2 :方法名稱;
eventBus.$on('changeG',this.green);
},
methods:{
changeGreen(){
eventBus.$emit("changeR")
},
green(){
this.color="紅色"
}
},
// 變綠改變兄弟的數(shù)據(jù)鸠真;
template:"<div>{{color}}<button @click='changeGreen'>變綠</button></div>"
};
let brother2 ={
data(){
return {
color:"紅色"
}
},
created(){
// 給事件車(chē)訂閱方法悯仙;
eventBus.$on('changeR',this.changeRed);
},
methods:{
changeRed(){
this.color="綠色";
},
red(){
eventBus.$emit("changeG")
}
},
template:"<div>{{color}}<button @click='red'>變紅</button></div>"
}
let vm = new Vue({
el: '#app',
data: {},
components:{
brother1,brother2
}
});
</script>
props
<div id="app">
<child :m="msg"></child>
</div>
<script src="./node_modules/vue/dist/vue.js"></script>
<script>
let vm = new Vue({
el: '#app',
data: {
msg:100
},
components:{
child:{
data(){
return {}
},
// props : 不僅可以傳數(shù)組,還可以傳對(duì)象吠卷;
props:{
// 單個(gè)類(lèi)型校驗(yàn)
//m:Number
//m:[Number,String,Object,Function]
m:{
type:Number,// 校驗(yàn)類(lèi)型的锡垄;
required:true,// 必填項(xiàng)
//default:100,// 默認(rèn)值;
validator(val){
//console.log(val);
// 會(huì)根據(jù)當(dāng)前validator的返回值祭隔,向?yàn)g覽器的控制臺(tái)拋出警告货岭;
/*if(val>100){
return true;
}*/
return false;
}
}
},
template:"<div @click='fn'>{{m}}<div>",
methods:{
fn(){
console.log(typeof this.m);
}
}
}
}
});
路由
- 1.創(chuàng)建組件
- 2.配置路由映射表routes=[{path:'/路徑',component:組件名字}]
- 3.路由映射表放進(jìn)VueRouter 進(jìn)行注冊(cè)疾渴;let router = new VueRouter({ routes});
- 4.在vue的實(shí)例中使用
在元素的自定義屬性取屬性值時(shí)千贯,是取得當(dāng)前父組件中的數(shù)據(jù)
<body>
<div id="app">
<!--to 是一個(gè)router-link 必須一個(gè)屬性-->
<!--router-link 是一個(gè)自定義的標(biāo)簽-->
<!--router-link 中行間屬性tag;屬性值是展示對(duì)應(yīng)的標(biāo)簽;把route-link 解析成對(duì)應(yīng)的標(biāo)簽-->
<router-link to="home" tag="div">首頁(yè)</router-link>
<router-link to="list">列表頁(yè)</router-link>
<!--是一個(gè)標(biāo)簽搞坝,也全局一個(gè)組件-->
<!--顯示真實(shí)的對(duì)應(yīng)的組件-->
<router-view></router-view>
<!--<router-view></router-view>-->
</div>
<script src="./node_modules/vue/dist/vue.js"></script>
<script src="node_modules/vue-router/dist/vue-router.js"></script>
<script>
// 路由: node
// 根據(jù)不同的路徑搔谴,執(zhí)行不同的內(nèi)容;
// 路由 : 切換組件桩撮;
// vue-router : 實(shí)現(xiàn)頁(yè)面的跳轉(zhuǎn)敦第;
// 1.創(chuàng)建組件
// 2.配置路由映射表
// 3.路由映射表放進(jìn)VueRouter 進(jìn)行注冊(cè)峰弹;
// 4.在vue的實(shí)例中使用
let home = {
template:"<div>首頁(yè)</div>"
};
let list = {
template:"<div>列表頁(yè)</div>"
};
// routes ; 路由映射表
//在routes中路徑必須加上/;
let routes = [
{path:"/home",component:home},
{path:"/list",component:list}
];
// vue-router : 提供一個(gè)構(gòu)造函數(shù)
let router = new VueRouter({
// routes : 路由映射表;
routes
});
let vm = new Vue({
el: '#app',
data: {},
router
});
</script>
</body>
路由的參數(shù)
<body>
<div id="app">
<!--:to : 編程式的路徑;一定要加一個(gè)名字-->
<!--在元素的自定義屬性取屬性值時(shí)芜果,是取得當(dāng)前父組件中的數(shù)據(jù)鞠呈;-->
<router-link :to="{name:'product',params:{id:flag,txt:'a'}}">商品1</router-link>
<router-link to="/article/2/b">商品2</router-link>
<router-link to="/article/3/c">商品3</router-link>
<router-view></router-view>
</div>
<script src="./node_modules/vue/dist/vue.js"></script>
<script src="node_modules/vue-router/dist/vue-router.js"></script>
<script>
// $router : 上面放的都是一些方法
// $route : 放了一些鍵值對(duì)
let article ={
data(){
return {f:89}
},
created(){
console.log(this.$route);
console.log(this.$router);
// $route.params :存儲(chǔ)了當(dāng)前路由的參數(shù);
},
template:"<div>第{{$route.params.id}}篇文章</div>"
};
let routes = [
{path:"/article/:id/:txt",component:article,name:'product'}
];
let router = new VueRouter({
routes
});
let vm = new Vue({
el: '#app',
data: {
flag:11
},
router
});
</script>
</body>
<div id="app">
<son :m="msg"></son>
</div>
let son = {
// 在子組件中,data computed watch methods 這些屬性都有隐解;子組件就是一個(gè)vue的實(shí)例鞍帝;
data(){
return {
val:100//沒(méi)用
}
},
// props
props:["m"],
template:"<div>{{m}}</div>"
};
let vm = new Vue({
el:"#app",
data: {
msg:"hello"
},
components:{
son
}
});
如果需要當(dāng)觸發(fā)子組件上的操作改變父組件上的數(shù)據(jù)時(shí),需要在父組件定義方法煞茫,改變自己的值帕涌;在父組件中定義的方法摄凡,需要訂閱到子組件的自定義事件上;當(dāng)觸發(fā)子組件中的某個(gè)操作時(shí)蚓曼,通過(guò)$emit 去觸發(fā)這個(gè)自定義的事件亲澡;讓其對(duì)應(yīng)的父組件的方法執(zhí)行;
<div id="app">
父親: {{money}}
<child :a="money" @changem = "change"></child>
</div>
<script src="./node_modules/vue/dist/vue.js"></script>
<script>
// 子傳父: 如果需要當(dāng)觸發(fā)子組件上的操作改變父組件上的數(shù)據(jù)時(shí)纫版,需要在父組件定義方法床绪,改變自己的值;在父組件中定義的方法其弊,需要訂閱到子組件的自定義事件上癞己;當(dāng)觸發(fā)子組件中的某個(gè)操作時(shí),通過(guò)$emit 去觸發(fā)這個(gè)自定義的事件梭伐;讓其對(duì)應(yīng)的父組件的方法執(zhí)行痹雅;
let vm = new Vue({
el: '#app',
data: {
money:400
},
methods:{
change(val){
console.log(1);
this.money = val;
}
},
components:{
child:{
data(){
return {};
},
props:["a"],
template:"<div>兒子:{{a}}<button @click='fn'>多要錢(qián)</button></div>",
methods:{
fn(){
// $emit存在于每一個(gè)vue的實(shí)例上;
// 需要和DOM行間的的屬性是保持一致糊识;
this.$emit("changem",800)
}
}
}
}
});
</script>
<div id="app">
<brother1></brother1>
<brother2></brother2>
</div>
<script src="./node_modules/vue/dist/vue.js"></script>
<script>
// 每一個(gè)vue的實(shí)例都是獨(dú)立的绩社;相互之間不能直接進(jìn)行改變數(shù)據(jù);
// 給兩個(gè)不同的組件找一個(gè)載體赂苗;把共同的方法放在這個(gè)載體上愉耙;
let eventBus = new Vue;// 創(chuàng)建一個(gè)新的vue實(shí)例;
// 在這個(gè)新的實(shí)例上哑梳,有$on: 訂閱 $emit: 發(fā)布;
let brother1 ={
data(){
return {
color:"綠色"
}
},
created(){
// $on : param1 : 自定義事件名稱劲阎, param2 :方法名稱;
eventBus.$on('changeG',this.green);
},
methods:{
changeGreen(){
eventBus.$emit("changeR")
},
green(){
this.color="紅色"
}
},
// 變綠改變兄弟的數(shù)據(jù)鸠真;
template:"<div>{{color}}<button @click='changeGreen'>變綠</button></div>"
};
let brother2 ={
data(){
return {
color:"紅色"
}
},
created(){
// 給事件車(chē)訂閱方法悯仙;
eventBus.$on('changeR',this.changeRed);
},
methods:{
changeRed(){
this.color="綠色";
},
red(){
eventBus.$emit("changeG")
}
},
template:"<div>{{color}}<button @click='red'>變紅</button></div>"
}
let vm = new Vue({
el: '#app',
data: {},
components:{
brother1,brother2
}
});
</script>
<div id="app">
<child :m="msg"></child>
</div>
<script src="./node_modules/vue/dist/vue.js"></script>
<script>
let vm = new Vue({
el: '#app',
data: {
msg:100
},
components:{
child:{
data(){
return {}
},
// props : 不僅可以傳數(shù)組,還可以傳對(duì)象吠卷;
props:{
// 單個(gè)類(lèi)型校驗(yàn)
//m:Number
//m:[Number,String,Object,Function]
m:{
type:Number,// 校驗(yàn)類(lèi)型的锡垄;
required:true,// 必填項(xiàng)
//default:100,// 默認(rèn)值;
validator(val){
//console.log(val);
// 會(huì)根據(jù)當(dāng)前validator的返回值祭隔,向?yàn)g覽器的控制臺(tái)拋出警告货岭;
/*if(val>100){
return true;
}*/
return false;
}
}
},
template:"<div @click='fn'>{{m}}<div>",
methods:{
fn(){
console.log(typeof this.m);
}
}
}
}
});
- 1.創(chuàng)建組件
- 2.配置路由映射表routes=[{path:'/路徑',component:組件名字}]
- 3.路由映射表放進(jìn)VueRouter 進(jìn)行注冊(cè)疾渴;let router = new VueRouter({ routes});
- 4.在vue的實(shí)例中使用
在元素的自定義屬性取屬性值時(shí)千贯,是取得當(dāng)前父組件中的數(shù)據(jù)
<body>
<div id="app">
<!--to 是一個(gè)router-link 必須一個(gè)屬性-->
<!--router-link 是一個(gè)自定義的標(biāo)簽-->
<!--router-link 中行間屬性tag;屬性值是展示對(duì)應(yīng)的標(biāo)簽;把route-link 解析成對(duì)應(yīng)的標(biāo)簽-->
<router-link to="home" tag="div">首頁(yè)</router-link>
<router-link to="list">列表頁(yè)</router-link>
<!--是一個(gè)標(biāo)簽搞坝,也全局一個(gè)組件-->
<!--顯示真實(shí)的對(duì)應(yīng)的組件-->
<router-view></router-view>
<!--<router-view></router-view>-->
</div>
<script src="./node_modules/vue/dist/vue.js"></script>
<script src="node_modules/vue-router/dist/vue-router.js"></script>
<script>
// 路由: node
// 根據(jù)不同的路徑搔谴,執(zhí)行不同的內(nèi)容;
// 路由 : 切換組件桩撮;
// vue-router : 實(shí)現(xiàn)頁(yè)面的跳轉(zhuǎn)敦第;
// 1.創(chuàng)建組件
// 2.配置路由映射表
// 3.路由映射表放進(jìn)VueRouter 進(jìn)行注冊(cè)峰弹;
// 4.在vue的實(shí)例中使用
let home = {
template:"<div>首頁(yè)</div>"
};
let list = {
template:"<div>列表頁(yè)</div>"
};
// routes ; 路由映射表
//在routes中路徑必須加上/;
let routes = [
{path:"/home",component:home},
{path:"/list",component:list}
];
// vue-router : 提供一個(gè)構(gòu)造函數(shù)
let router = new VueRouter({
// routes : 路由映射表;
routes
});
let vm = new Vue({
el: '#app',
data: {},
router
});
</script>
</body>
<body>
<div id="app">
<!--:to : 編程式的路徑;一定要加一個(gè)名字-->
<!--在元素的自定義屬性取屬性值時(shí)芜果,是取得當(dāng)前父組件中的數(shù)據(jù)鞠呈;-->
<router-link :to="{name:'product',params:{id:flag,txt:'a'}}">商品1</router-link>
<router-link to="/article/2/b">商品2</router-link>
<router-link to="/article/3/c">商品3</router-link>
<router-view></router-view>
</div>
<script src="./node_modules/vue/dist/vue.js"></script>
<script src="node_modules/vue-router/dist/vue-router.js"></script>
<script>
// $router : 上面放的都是一些方法
// $route : 放了一些鍵值對(duì)
let article ={
data(){
return {f:89}
},
created(){
console.log(this.$route);
console.log(this.$router);
// $route.params :存儲(chǔ)了當(dāng)前路由的參數(shù);
},
template:"<div>第{{$route.params.id}}篇文章</div>"
};
let routes = [
{path:"/article/:id/:txt",component:article,name:'product'}
];
let router = new VueRouter({
routes
});
let vm = new Vue({
el: '#app',
data: {
flag:11
},
router
});
</script>
</body>
.vue文件可以把template直接放在對(duì)象中