Vue組件之全局組件與局部組件的使用詳解
組件 (Component) 是 Vue.js 最強(qiáng)大的功能之一。組件可以擴(kuò)展 HTML 元素,封裝可重用的代碼。在較高層面上,組件是自定義元素,Vue.js 的編譯器為它添加特殊功能。在有些情況下,組件也可以是原生 HTML 元素的形式,以is特性擴(kuò)展。個(gè)人認(rèn)為就是一個(gè)可以重復(fù)利用的結(jié)構(gòu)層代碼片段。
全局組件注冊(cè)方式:Vue.component(組件名,{方法})
eg:
<body>
<div id="app">
<my-component></my-component>
</div>
<div id="app1">
<my-component></my-component>
</div>
<script>
Vue.component("my-component",{
template:"<h1>我是全局組件</h1>"
});
new Vue({
el:"#app"
});
new Vue({
el:"#app1"
})
</script>
</body>
渲染結(jié)果:
<div id="app"> <h1>我是全局組件</h1> </div> <div id="app1"> <h1>我是全局組件</h1> </div>
這里需要注意:
1.全局組件必須寫在Vue實(shí)例創(chuàng)建之前,才在該根元素下面生效;
eg:
<body>
<div id="app">
<my-component></my-component>
</div>
<div id="app1">
<my-component></my-component>
</div>
<script>
new Vue({
el: "#app"
});
Vue.component("my-component", {
template: "<h1>我是全局組件</h1>"
});
new Vue({
el: "#app1"
})
</script>
</body>
這樣只會(huì)渲染app1根元素下面的,并不會(huì)渲染app根元素下面的,并且會(huì)報(bào)錯(cuò)。
2.模板里面第一級(jí)只能有一個(gè)標(biāo)簽,不能并行;
<body>
<div id="app">
<my-component></my-component>
</div>
<script>
new Vue({
el: "#app"
});
Vue.component("my-component", {
template: "<h1>我是全局組件</h1>" +
"<p>我是全局組件內(nèi)標(biāo)簽</p>"
});
new Vue({
el: "#app1"
})
</script>
</body>
這樣子會(huì)報(bào)錯(cuò),并且只會(huì)渲染第一個(gè)標(biāo)簽h1;我們應(yīng)該這樣子寫:
<body>
<div id="app">
<my-component></my-component>
</div>
<script>
new Vue({
el: "#app"
});
Vue.component("my-component", {
template: "<h1>我是全局組件<p>" +
"我是全局組件內(nèi)標(biāo)簽</p></h1>"
});
new Vue({
el: "#app1"
})
</script>
</body>
局部組件注冊(cè)方式,直接在Vue實(shí)例里面注冊(cè)
eg:
<body>
<div id="app1">
<child-component></child-component>
</div>
<script>
new Vue({
el: "#app1",
components:{
"child-component":{
template:"<h1>我是局部組件</h1>"
}
}
});
</script>
局部組件需要注意:
1.屬性名為components,s千萬別忘了;
2.套路比較深,所以建議模板定義在一個(gè)全局變量里,代碼看起來容易一點(diǎn),如下:(模板標(biāo)簽比較多的時(shí)候,這樣子寫更加簡潔規(guī)整)
<body>
<div id="app1">
<child-component></child-component>
</div>
<script>
var child={
template:"<h1>我是局部組件</h1>"
};
new Vue({
el: "#app1",
components:{
"child-component":child
}
});
</script>
</body>
關(guān)于組件中的其他屬性,可以和實(shí)例中的一樣,但是data屬性必須是一個(gè)函數(shù):
eg:
<body>
<div id="app1">
<child-component></child-component>
</div>
<script>
var child={
template:"<button @click='add2'>我是局部組件:{{m2}}</button>",
data:function(){
return {m2:1}
},
methods:{
add2:function(){
this.m2++
}
}
};
new Vue({
el: "#app1",
components:{
"child-component":child
}
})
</script>
</body>
顯示結(jié)果:

全局組件和局部組件一樣,data也必須是一個(gè)函數(shù):
<body>
<div id="app1">
<my-component></my-component>
</div>
<script>
Vue.component("my-component",{
template:"<button @click='add1'>全局組件:{{m1}}</button>",
data:function(){
return {
m1:10
}
},
methods:{
add1:function(){
this.m1++
}
}
});
new Vue({
el:"#app1"
})
</script>
</body>
顯示結(jié)果:

當(dāng)使用 DOM 作為模板時(shí) (例如,將el選項(xiàng)掛載到一個(gè)已存在的元素上),你會(huì)受到 HTML 的一些限制,因?yàn)?Vue 只有在瀏覽器解析和標(biāo)準(zhǔn)化 HTML 后才能獲取模板內(nèi)容。尤其像這些元素<ul>,<ol>,<table>,<select>限制了能被它包裹的元素,而一些像<option>這樣的元素只能出現(xiàn)在某些其它元素內(nèi)部。
自定義組件<my-row>被認(rèn)為是無效的內(nèi)容,因此在渲染的時(shí)候會(huì)導(dǎo)致錯(cuò)誤。變通的方案是使用特殊的is屬性:
eg:
<body>
<div id="app1">
<ul>
<li is="my-component"></li>
</ul>
</div>
<script>
Vue.component("my-component",{
template:"<h1>{{message}}</h1>",
data:function(){
return {
message:"hello world"
}
}
});
new Vue({
el:"#app1"
})
</script>
</body>
渲染結(jié)果為:

對(duì)于全局與局部的作用域問題,我們可以這樣理解,只要變量是在組件內(nèi)部用的,這些變量必須是組件內(nèi)部的,而在外部html結(jié)構(gòu)中引用的變量,都引用的是該掛載下的實(shí)例里面的變量
eg:
<body>
<div id="app1">
<my-component></my-component>
</div>
<script>
Vue.component("my-component",{
template:"<button @click='add3'>" +
"{{message}}</button>",
data:function(){
return {
message:"hello world"
}
},
methods:{
add3:function(){
alert("我是局部")
}
}
});
new Vue({
el:"#app1",
methods:{
add3:function(){
alert("我是全局")
}
}
})
</script>
</body>
彈出框顯示:我是局部
Vue中所謂的全局指的是該掛載下的區(qū)域;
下面這種做法是錯(cuò)誤的,按我的想法覺得應(yīng)該會(huì)彈出:我是全局,但是卻報(bào)錯(cuò),也就是說組件處于全局下不可以添加默認(rèn)事件,要用全局的事件函數(shù),必須父子通信
<body>
<div id="app1">
<my-component @click="add3"></my-component>
</div>
<script>
Vue.component("my-component",{
template:"<button @click='add3'>" +
"{{message}}</button>",
data:function(){
return {
message:"hello world"
}
}
});
new Vue({
el:"#app1",
methods:{
add3:function(){
alert("我是全局")
}
}
})
</script>
</body>
額外話題:
1.函數(shù)return后面必須跟返回的內(nèi)容,不能換行寫
eg:

下面這種寫法不會(huì)返值回來:

2.Vue和小程序等一樣,采用es6的函數(shù)寫法,this指向是不一樣的
<body>
<div id="app1">
<button @click="f">ES5</button>
<button @click="f1">ES6</button>
</div>
<script>
new Vue({
el:"#app1",
methods:{
f:function(){
console.log(this)
},
f1:()=>{
console.log(this)
}
}
})
</script>
</body>
結(jié)果:
第一個(gè)this指的是Vue實(shí)例
第二個(gè)this指的是Window

由于它和小程序不一樣,我發(fā)現(xiàn)在data里面this指的是window,在methods里面this才是Vue實(shí)例
所以建議大家用es5寫吧
new Vue({
el:"#app1",
data:{that:this},
})

以上就是本文的全部內(nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
vue中使用vue-pdf組件實(shí)現(xiàn)文件預(yù)覽及相應(yīng)報(bào)錯(cuò)解決
在需求中,經(jīng)常遇見pdf的在線預(yù)覽效果,很多pdf插件不支持vue3,或者是沒有集成翻頁放大縮小功能,比如vue-pdf,下面這篇文章主要給大家介紹了關(guān)于vue中使用vue-pdf組件實(shí)現(xiàn)文件預(yù)覽及相應(yīng)報(bào)錯(cuò)解決的相關(guān)資料,需要的朋友可以參考下2022-09-09
vue cli如何配置開發(fā)環(huán)境下的sourcemap
這篇文章主要介紹了vue cli如何配置開發(fā)環(huán)境下的sourcemap問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-06-06
vue自定義移動(dòng)端touch事件之點(diǎn)擊、滑動(dòng)、長按事件
這篇文章主要介紹了vue自定義移動(dòng)端touch事件之點(diǎn)擊、滑動(dòng)、長按事件的實(shí)例代碼,需要的朋友可以參考下2018-07-07
Vue中的Token過期驗(yàn)證與動(dòng)態(tài)路由重定向詳解
這篇文章主要為大家詳細(xì)介紹了如何在 Vue 項(xiàng)目中實(shí)現(xiàn) Token 過期驗(yàn)證,并根據(jù) Token 的有效期動(dòng)態(tài)重定向用戶到首頁或登錄頁,感興趣的小伙伴可以了解下2025-03-03
Vue3全局掛載使用Axios學(xué)習(xí)實(shí)戰(zhàn)
這篇文章主要為大家介紹了Vue3全局掛載使用Axios學(xué)習(xí)實(shí)戰(zhàn)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-06-06
VUE搭建分布式醫(yī)療掛號(hào)系統(tǒng)后臺(tái)管理頁面示例步驟
這篇文章主要為大家介紹了分布式醫(yī)療掛號(hào)系統(tǒng)之搭建后臺(tái)管理系統(tǒng)頁面,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-04-04
Vue2?中自定義圖片懶加載指令?v-lazy實(shí)例詳解
這篇文章主要為大家介紹了Vue2?中自定義圖片懶加載指令?v-lazy實(shí)例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-09-09

