本文原創為CSDN博主:安之ccy,博客首頁地址:https://blog.csdn.net/qq_43523725
轉載請注明出處,謝謝支持和鼓勵
先來張柯基的圖,給自己點鼓勵💕

初識組件應用
實體化多個vue物件
全域組件
定義與使用
data是一個函式
區域組件
父向子傳值/傳參考:props
靜態傳值
動態傳值:v-bind
子向父:事件傳值$emit
使用腳手架創建專案并運用組件and傳值
初識組件應用
實體化多個vue物件
用new創建多個vue物件并命名,可以通過變數相互訪問
例子:物件2修改物件1的name變數
<!-- 第一個根元素 -->
<div id="vue-app-one">這里是:{{name}}</div>
<!-- 第二個根元素 -->
<div id="vue-app-two">
<p>這里是:{{name}}</p><br>
<button @click="changeName">change-one-name</button>
<!-- 點擊后修改vue-app-one的name值-->
</div>
// 第一個vue物件
var one = new Vue({
el:"#vue-app-one",
data:{
"name":"ccy1"
}
})
// 第二個vue物件
var two = new Vue({
el:"#vue-app-two",
data:{
"name":"ccy2"
},
methods:{
// 修改vue-app-one的name為'ccy333'
changeName:function(){
one.name = 'ccy333'
}
}
})
效果:點擊后修改”ccy1“為”ccy333“

全域組件
定義與使用
- 定義全域組件,需給組件一個名字,呼叫時,將組件名當作標簽名使用;相當于自定義標簽,該標簽下可以包含很多子html標簽;
- 這些子html標簽定義在組件的template屬性中,每次呼叫該組件,都渲染template里的標簽
- template里必須只有一個根元素
- 在組件中,data是函式,將資料return回去
- 依然可以用this來呼叫data中定義的資料
例子:
定義組件:
① 定義一個組件,命名為my-component
② 其中包含資料:name和方法:changeName
③ 渲染出的html效果有一個p標簽,包含一個按鈕,點擊按鈕時,修改name
④ 命名規范:camelCase (駝峰命名法) 與kebab-case (短橫線分隔命名)
- 當寫成標簽時,遇到有大寫字母的命名,需要改成小寫并用橫桿鏈接前后兩個部分,如定義組件時命名為myComponent,寫成標簽時應寫成<my-component>;
- 組件定義時也可以用橫桿法命名;
- 如果定義時用myComponent,標簽用<my-component>是OK的,系統自動識別
// 自定義的全域組件my-component
// template中只有一個根元素p標簽,里面包含一個button按鈕
Vue.component('my-component',{
template:`<p>
我的名字是:{{name}}
<button @click='changeName()'>btn</button>
</p>`,
data(){
return {
name:'ccy'
}
},
methods:{
changeName:function(){
this.name = '安之'
}
}
})
// vue物件1
new Vue({
el:"#vue-app-one",
})
// vue物件2
new Vue({
el:"#vue-app-two",
})
使用組件:
① 在vue物件對應的根元素(el指定標簽)下使用
② 由于定義的是全域組件,所以可以在任意的vue物件下使用
③ 組件可復用,在一個vue物件下可以使用多次,且組件間互相獨立
<div id="vue-app-one">
<my-component></my-component>
<my-component></my-component>
</div>
<div id="vue-app-two">
<my-component></my-component>
</div>
效果:

data是一個函式
在vue物件中,data屬性值是一個物件,比如這樣的:

但是在全域組件中,同一份data可能被多個vue物件使用,每個物件不單獨維護一份data時,如果某一個vue物件修改了data中的一個變數,其他vue物件獲取data時就會被影響;
如果用上面的例子做案例,若組件中的data是物件(參考),其他地方均不改變,兩個vue物件便共享同一個name變數;當我通過其中一個vue物件改變name資料時(即點擊任一個btn按鈕),另一個物件獲得的name也發生了改變(其他按鈕處的’ccy’也都被改成了’安之’)
因此,為保證資料的獨立性,即每個實體可以維護一份被回傳物件的獨立的拷貝,data為每個實體都return一份新創建的資料,不同的vue物件獲取的data均互不影響
在vscode中不允許組件中的data是物件,會報錯:
[Vue warn]: The “data” option should be a function that returns a per-instance value in component definitions.
區域組件
- 區域組件注冊在某個vue物件中,
- 只有注冊過該區域組件的vue物件才能使用這個區域組件
例子:
區域組件定義:
// template僅一個根元素:ul
var msgComponent = {
// 資料是自身提供的 (hobbies)
template:`<ul><li v-for='hobby in hobbies' v-bind:key='hobby.id'>{{hobby}}</li></ul>`,
data(){
return {
hobbies:['看劇','看動漫','吃好吃的']
}
}
}
注冊區域組件:
// 僅由注冊過該區域組件的vue物件才能使用,此處為div#vue-app-one
// 注意命名規范,components中物件的key將會被作為標簽名,多個單詞拼接的命名需使用橫桿法
// 可以寫成msg-component,此處直接簡化了命名為msg,
new Vue({
el:"#vue-app-one",
components:{
"msg": msgComponent
}
})
html檔案中使用<msg></msg>:
<div id="vue-app-one">
<p>這里是vue-app-one</p>
<mycomponent></mycomponent>
<mycomponent></mycomponent>
<p>我的愛好:</p>
<msg></msg> <!--使用區域組件-->
</div>
效果: 紅框圈出的部分就是區域組件渲染出來的

父向子傳值/傳參考:prop
靜態傳值
創建子組件:
var titleComponent = {
props:["title"],
template:`<p>{{title}}</p>`
// 所需要的資料title由父組件提供
}
在父組件的components屬性中注冊子組件:
new Vue({
el:"#vue-app-one",
components:{
"msg": msgComponent,
"titleComponent":titleComponent
},
})
在父組件上使用子組件:
<!-- div#vue-app-one為父組件 -->
<div id="vue-app-one">
<p>這里是vue-app-one</p>
<mycomponent></mycomponent>
<mycomponent></mycomponent>
<!--使用子組件title-component,并傳值"我的愛好:"給子組件-->
<title-component title="我的愛好:"></title-component>
<msg></msg>
</div>
效果:紅框標記處就是父向子傳值并展示

動態傳值:v-bind
定義子組件:
var titleComponent = {
props:["title"],
template:`<p>{{title}}</p>`
}
在父組件的components屬性中注冊子組件:
new Vue({
el:"#vue-app-one",
components:{
"msg": msgComponent,
"titleComponent":titleComponent
},
data(){
return {
title:"my hobbies are ",
}
}
})
使用子組件,通過系結父組件data中的變數title來實作動態傳值:
<!-- div#vue-app-one為父組件 -->
<div id="vue-app-one">
<p>這里是vue-app-one</p>
<mycomponent></mycomponent>
<mycomponent></mycomponent>
<!-- 動態系結title -->
<title-component v-bind:title="title"></title-component>
<msg></msg>
</div>
效果:紅框處就是動態系結獲取資料的展示

傳遞陣列等復雜資料時,也可以使用v-bind來動態傳值,如:
需要向子級傳遞hobbies陣列,在vue實體物件(父)中創建資料hobbies:
new Vue({
el:"#vue-app-one",
components:{
"msg": msgComponent,
"titleComponent":titleComponent
},
data:{
title:"my hobbies are ",
hobbies:['看劇','看動漫','吃好吃的'], //需要向子組件傳遞的資料
}
})
定義子組件:
var msgComponent = {
template:`
<p>{{hobby}}</p>
`,
props:["hobby"],
data(){
return {
}
}
}
使用子組件:
<!-- div#vue-app-one為父組件 -->
<div id="vue-app-one">
<p>這里是vue-app-one</p>
<mycomponent name="ccy"></mycomponent>
<mycomponent name="ccy"></mycomponent>
<title-component v-bind:title="title"></title-component>
<!-- 動態傳值:hobbies -->
<msg v-for="hobby in hobbies" v-bind:hobby="hobby" v-bind:key="hobby.id"></msg>
</div>
效果:

跳回“一點想法”處
子向父:事件傳值$emit
子組件不能通過prop向父組件傳遞資料,需要使用事件向父組件拋出一個值,告知父組件我需要實作一個功能,由父組件處理這個事件
例子:點擊按鈕,改變名稱chinesename
(由于data變數名不支持chinese-name形式,花括號里不支持chineseName形式,所以這里我都用了小寫,此處記錄一下,日后學到了新知再來填坑)
先在父組件的data中定義chinesename的初始值:
new Vue({
el:"#vue-app-one",
data:{
chinesename:"anzhi" // chinesename初始值
}
})
創建子組件,并注冊事件change-name(就像click事件一樣,需要讓系統能夠辨認這是一個事件并監聽,當事件被觸發時,執行某項約定好的操作):
Vue.component('blog-post', {
props: ['chinesename'],
template: `
<div class="blog-post">
<h3>{{ chinesename }}</h3>
<button v-on:click='$emit("change-name","ruosu")'>
修改名字
</button>
</div>
`
// blog-post組件包含一個h3,顯示chinesename,和一個按鈕
// 點擊這個按鈕,觸發change-name事件,將"ruosu"作為引數傳遞給指定的處理函式onChangeName
})
在父組件中使用子組件,定義change-name的處理函式為onChangeName:
<div id="vue-app-one">
<p>這里是vue-app-one</p>
<!-- v-bind:通過prop給子組件傳遞chinesename的初始值 -->
<!-- v-on:子組件通過$emit給父組件傳遞新的chinesename的值 -->
<div id="blog-posts-events-demo">
<blog-post
v-bind:chinesename='chinesename'
v-on:change-name = "onChangeName"
></blog-post>
</div>
</div>
在父組件處定義事件處理函式onChangeName:
new Vue({
el:"#vue-app-one",
data:{
chinesename:"anzhi"
},
methods:{
onChangeName:function(value){
// 將chinesename換成傳遞過來的資料
this.chinesename=value
}
}
})
效果:

一點想法
關于父子組件的區分,在此寫一點總結,還是日后學了新知識再來填坑 ┗|`O′|┛ 嗷~~
官網中沒有很明確指明兩者的定義和區別,在網上搜了一圈,覺得比較多人認可并且好理解的是:
- el指定的根元素為父組件(使用之處為父組件)
- vue實體物件也可看做組件
在前面這些父子傳值的例子中,我們可以看到,對于區域組件,我們會在某個html根元素中注冊并使用,所以此時el指定的根元素在html檔案中是這個區域組件的父組件,區域組件在html使用時便是這個父組件的一份子,承擔資料傳輸的責任
跳轉到父向子動態傳值案例


再用繞口令說一波,即:title-component組件定義處與使用處,兩者身份是不一樣的,在定義處,它是區域組件,也是子組件,需注冊才能使用;在使用處,它是根元素的包含一部分,根元素為父組件,而“它”,承擔著父組件與子組件資料溝通的重任
這個總結在全域組件情況下也適用,使用該全域組件的根元素是父組件,如上面的子向父傳值的案例,div#vue-app-one是父組件,<blog-post></blog-post>作為父子組件溝通的橋梁,全域組件blog-post為子組件
跳轉到子向父案例
圖示:

如果是子組件又嵌套了子組件,被嵌套的組件是子子組件,以此類推
使用腳手架創建專案并運用組件and傳值
CLI腳手架安裝步驟可以看我的這篇文章,使用CLI腳手架創建專案,簡單快捷,特別的是,頁面內容和資料傳遞需要寫在.vue檔案里,每個vue檔案為一個模塊,
我們通過合理組裝各模塊(組件)來完成某項具體的功能,組件之間的配合以及父子傳值的作用在此處體現得更明顯一些,每一個vue檔案都可看作一個組件,我們可以把頁面按照需求劃分成若干個部分,如導航欄,中間內容和底部三個部分,每個部分的實作分散到各子組件中完成,包括頁面的展示和資料的獲取,
如自定義博客頁面:
主頁面由vue-app主組件構成,包含導航欄、中間部分、底部欄三部分
導航欄由vue-header子組件完成
中間內容按照功能劃分
- 添加博客:addBlob子組件
- 顯示博客:showBlob子組件
- 修改博客:modifyBlob子組件
- 點擊顯示單篇博客內容:singleBlob子組件
底部資訊欄由vue-footer完成
除了主頁面,其他子部分和組件均根據功能劃分,輔助主頁面展示
個人博客父向子傳值的示意圖如下:
- 各個子功能由不同組件構成,拼成一個大一些的功能組件
- 點擊展示單篇博客和修改博客兩個組件均需要從主頁面獲取博客id,才能進行相應展示和操作,這便是典型的父向子傳值

好啦,本次分享就到這里啦,歡迎點贊、評論、收藏,謝謝支持~

轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/286339.html
標籤:其他
