- 兩個vue實例
var vm1 new Vue({
)}
var vm2 new Vue({
)}
- 外部js訪問vm:
vm1.title = "ok"
實際上vm1內(nèi)部用this訪問其自身,外部用vm1來訪問它
也可以在vm2里面
vm1.title = "ok"data可以在外面js創(chuàng)建
var data = {
title="ok"
number=1
}
var vm1 new Vue({
el:app1,
data = data,
)}
vm的屬性可以在外部添加稽煤,但沒用奔滑,缺少vue的響應(yīng)式特點:
vm1.newProp = 'New!' ,可以這樣設(shè)置合陵,但沒有了響應(yīng)式vm中自動創(chuàng)建了很多get,set之類的屬性,很多澄阳,這些東西構(gòu)成了vue框架曙寡,
用console.log(vm1),然后按按F12可以觀察寇荧。
比如說:
console.log(vm1.$data.title) // 這個$就是系統(tǒng)默認的一個東西ref
ref是可以添加在任何html元素上:ref= "xxx"即可
在vue中用:this.$refs列出全部$refs元素,this.$refs.xxx 訪問指定的單個元素
要點:通過$refs改變DOM元素的內(nèi)容执隧,并非在vue框架下的行為揩抡,當(dāng)vue重新渲染時它還是會根據(jù)模板來設(shè)置數(shù)據(jù),你的修改無效
$refs是取代queryselctor的好方法镀琉,但是用它來修改元素值不好$mount (小知識:$前綴的屬性峦嗤,多半是Vue原生共給的方法或?qū)傩?
var vm1 new Vue({
el:'app1'
)}
以上說明將vm1掛到一個id=app1的div上
var vm1 new Vue({
)}
去掉el, 還可以這樣:
vm1.$mount('app1')
這就是$mount的作用:掛載,
作用和設(shè)置el一樣。$mount的好處是我們可以先創(chuàng)建vue屋摔,事后再掛載到DOM的某處烁设。
template的用法:
var vm1=new Vue({
template: '<h1>Hello world</h1>' //直接在創(chuàng)建vue實例的時候設(shè)置模板
)}
然后,甚至也可以使用原生JS命令來掛載:
document.getElementById('app1').appendChild(vm1.$el)來設(shè)置其中的el屬性來掛載钓试,但是這比較罕見装黑。
vue 虛擬dom 真實dom的關(guān)系
在vue和dom之間,還有一層虛擬dom, 虛擬dom是真實dom的一份拷貝弓熏,
vue 隨時觀察這虛擬dom恋谭,因為沒有渲染動作,他們的交互速度是極快的挽鞠,
當(dāng)虛擬dom的值和dom確實發(fā)生改變的時候疚颊,才去改變真實dom的元素。
比如說vue有一名為message的變量信认,值是hello world,現(xiàn)在我們把他修改為Hello everyone材义,
首先,vue會將它快速反映到虛擬dom上嫁赏,然后其掂,再對比真實dom,發(fā)其中一個元素變了潦蝇,
它就只會去渲染這其中一個元素清寇,避免了全局dom變動喘漏。vue的生命周期
beforeCreate() -> 初始化Data和Events
created() -> 編譯模板(template)或者el的template (比如說是直接從HTML中讀取,還是從template屬性中讀取)
beforeMount() ->尚未將模板掛載到DOM的時候發(fā)生-> 將模板轉(zhuǎn)換成真正的HTML代碼
mounted() -> 寫入DOM
以上一個Vue就被創(chuàng)建好了华烟,在運行時翩迈,當(dāng)數(shù)據(jù)發(fā)生變化的時候,也會觸發(fā)兩個鉤子:
當(dāng)數(shù)據(jù)發(fā)生變化而且需要重新渲染的DOM的時候被調(diào)用:beforeUpdate()盔夜,在數(shù)據(jù)渲染完畢后調(diào)用updated()
注意這兩個鉤子不屬于Vue的“生命周期”范疇负饲,而是當(dāng)Vue在存續(xù)時間內(nèi),當(dāng)某個數(shù)據(jù)發(fā)生變化時觸發(fā)的東西喂链。beforeDestory() -> 當(dāng)決定要銷毀Vue實例但又還沒有真正銷毀時觸發(fā)返十。
destroyed() -> Vue實例已經(jīng)被銷毀時觸發(fā)。
要點:
beforeUpdate() 和 updated() 必須是值真正發(fā)生變化才會觸發(fā)椭微,比如你反復(fù)修改message變量洞坑,但值一直是'Hello',則
不會反復(fù)觸發(fā)這兩個鉤子蝇率,這就是前面所講的虛擬DOM在起作用迟杂,數(shù)據(jù)沒有真正變化,不做渲染動作本慕。
beforeDestory() 和destroyed() 必須顯式地用:this.$destroy() 才會觸發(fā)排拷。
- component (組件)
要點:
一個component就是一個vue實例,通過el: 名字命名锅尘,然后在全局Vue中注冊它:
Vue.component('名字')
然后每一個new Vue监氢,都會自動加載這個component (組件),
定義方法:
a) 直接嵌入式:
Vue.component('hello',{
template: '<h1>Hello world</h1>'
})
相當(dāng)于自定義了一個HTML標(biāo)簽<hell></hello> 藤违,可以在HTML文檔的任意地方使用浪腐,就是顯示一行字:Hello world
這里有一個重點,我們總是會看到顿乒,在根實例創(chuàng)建的時候牛欢,data是長這樣的:
new Vue({
el: '#app',
data: {
a: '',
b:'',
}
})
但在組件中變成了這樣:
data() {
return {
a: '',
b:'',
}
},
這個return將data封裝成了一個函數(shù),變量通過這個名為data的函數(shù)攜帶出來了淆游,
理論插入:
在vue中傍睹,所有同名組件共享同樣的data對象,比如你的頁面中嵌入了3個自定義組件<hello>,
其實這三個<hello>是共享同一個data的, 當(dāng)你修改某一個實例的data對象的一個屬性的時候,
公用的data對象也會發(fā)生改變犹菱,即3個<hello>的data同時改變拾稳,這明顯不是我們想要的效果。
將組件的data封裝成一個函數(shù)腊脱,這樣做的目的是访得,data不再是一個對象名,
而是一個函數(shù),可以創(chuàng)建屬一塊私有空間悍抑,讓各個組件維護各自的數(shù)據(jù)鳄炉。
關(guān)于this :
this只會只想這個Vue組件實例的對象,并不會產(chǎn)生像data那樣共享數(shù)據(jù)的問題搜骡。全局組件與局部組件
-- 全局組件使用Vue.component('組件名', 對象名) 注冊拂盯,組件實例既可以是直接內(nèi)嵌,也可以import一個
-- 局部組件采用變量的方法注冊记靡,
首先定義一個組件谈竿,當(dāng)然此處也可以import
let cmp = {
data: function() {
return {
xx:0,
}
},
template: '',
methods:{
},
}
然后在一個Vue實例中,加入到它的component屬性中:
new Vue({
el: "#app",
components: {
cmp
},
template: '',
methods: {
},
})
-- 關(guān)于render: h => h(App)
這個其實就是template屬性的替代品摸吠,
-- 關(guān)于export default
這個其實是JS的知識空凸,而不是Vue的內(nèi)容了,
在JS中import 函數(shù) from 文件寸痢,
理論上import的函數(shù)名呀洲,必須在文件中以 export 顯式的提供,比如code.js文件中有:
function aaa(){
console.log('Hi')
}
export {aaa}
你在import的時候只能這樣:
import {aaa} from code.js
使用的時候直接使用函數(shù)名aaa() 調(diào)用啼止。
但是道逗,當(dāng)文件中有export default的時候,import的時候可以用任意名稱來取代它族壳,
比如還是code.js,代碼如下:
export default {
aaa:function() {
console.log('hi')
}
}
import的時候:
import Heeellooo from code.js
導(dǎo)出的函數(shù)名隨你高興趣些,可以自定義仿荆。
使用:Heeellooo.aaa() 來調(diào)用
要點整理:
- 注冊組件:
全局法:Vue.component('組件名', 對象名)
局部法:在實例的component屬性中添加組件代碼
組件的本質(zhì):你可以把它想象成一個自定義的HTML標(biāo)簽
組件對象代碼怎么來:
a. 內(nèi)嵌:
Vue.component('aaa', {template:'<h1>Hello</h1>'})
b. 變量:
let aaa = {
template:'<h1>Hello</h1>'
}
Vue.component('aaa', aaa)
c. import :
import aaa from code.js
Vue.component('aaa', aaa)
- 知識點:
new Vue({
el: "#app",
store,
router,
components: {
App,
Post,
},
這里面store和router運用了ES6新語法,
store和router是vue的兩個屬性坏平,當(dāng)屬性名和對象名是一樣的時候拢操,可以省略寫成一個,說白了就是:
store:store
router:router
這種格式的簡寫舶替。
-- 組件之間的通訊
父組件 -> 子組件 [props]
父組件data中有一個變量:name
在子組件需要用props屬性引用:
export default {
props:['name'] //數(shù)組中嵌入變量名
}
在引用子組件的HTML標(biāo)簽中加入令境,例如hello標(biāo)簽:<hello :name="name">
要點:要引用父組件變量name,子組件props中要添加name顾瞪,模板中用{{name}}舔庶,引用標(biāo)簽要增加:name = "name"
當(dāng)然,以上四處地方也并非只能使用name這個變量名陈醒,例如在子組件中用myName代替:
父組件還是name變量惕橙,
子組件props中可寫為: props:['myName']
模板中寫為: {{myName}}
標(biāo)簽中寫為: :myName = "name"
效果一樣。
除了模板之外钉跷,在子組件任何地方都可以用this來訪問這個變量弥鹦,例如在methods中:
methods: {
aaa:function() {
console.log(this.myName)
}
},props的驗證:
export default {
props: {
myName: {
type: String, //必須是String類型
defalut: 'Hello'
}
}
myName必須是String,默認值是Hello
-- 反向傳值: 子組件到父組件:
第1步: 在子組件中$emit()通知父組件 爷辙,例如:
當(dāng)完成某個操作后彬坏,通知父組件并傳值朦促,有點類似回調(diào)函數(shù)
this.$emit('ok', this.myName) // 設(shè)置一個通知函數(shù)ok, 傳回變量myName
第2步:在引用子組件的標(biāo)簽中標(biāo)明這個函數(shù),例如:
<hello :name="name" @ok='代碼'>
這里的"代碼"栓始,既可以是一個函數(shù)务冕,也可以直接就是一個變量名,也可以是一行代碼混滔。
---------擴展閱讀---------------在使用elment-ui的diaglog對話窗中洒疚,如果子組件是對話窗,在關(guān)閉的時候?qū)alse傳回給父組件坯屿,
vue報錯:void mutating a prop directly since the value will be overwritten whenever the parent component re-renders.
Instead, use a data or computed property based on the prop's value. Prop being mutated:
按上面的“正規(guī)”操作油湖,會報這個警告,盡管不影響使用领跛,但很煩人乏德,解決方案:
http://www.manongjc.com/detail/11-tfljzfuejzpgadt.html
父組件中設(shè)置要點:
data() {
return {
profileShow: false, //彈窗總開關(guān)
};標(biāo)簽: <profile :isShow="profileShow" @profileClose="profileShow=$event"></profile>
子組件中設(shè)置要點:
標(biāo)簽:
<el-dialog
:visible.sync="currentIsShow"
@close="handleClose()">data() {
return {
currentIsShow: this.isShow,
}props: ['isShow'],
關(guān)窗事件:
methods: {
handleClose: function () {
this.$emit('profileClose', this.currentIsShow);
},