組件的分類
- 全局組件 : 可以聲明一次在任何地方使用(一般寫插件的時候全局使用的多一點)
- 局部組件: 必須告訴這個組件屬于誰(一般用局部比較好)
props是只讀的,vue底層會檢測你對props的修改,如果進行了修改,控制臺會報錯,必須修改,就復制一份到data中,通過data去修改數據。
我們在data里面重新定義一個變量去接收props屬性。這個變量最好不要重名,重名的話,優先獲取props屬性值,優先級props>data。
全局組件(component)
全局注冊的組件可以在隨后創建的 app 實例模板中使用,也包括根實例組件樹中的所有子組件的模板中
<script src="https://unpkg.com/vue@next"></script>
<div id="app">
<runoob></runoob>
<!-- 組件間數據相互獨立 -->
<button-counter></button-counter>
<button-counter></button-counter>
<button-counter></button-counter>
</div>
<script>
// 創建一個Vue 應用
const app = Vue.createApp({})
// 定義一個名為 runoob的新全局組件
app.component('runoob', {
template: '<h1>自定義組件!</h1>'
})
// 定義一個名為 button-counter的新全局組件
app.component('button-counter', {
data() {
return {
count: 0
}
},
template: `
<button @click="count++">
點了 {{ count }} 次!
</button>`
})
app.component('runoob', {
template: '<h1>自定義組件!</h1>'
})
app.mount('#app')
</script>
瀏覽器渲染
局部組件(components)
//對象
const ComponentA = {
/* ... */
}
const ComponentB = {
/* ... */
}
//使用
const app = Vue.createApp({
components: {
'component-a': ComponentA,
'component-b': ComponentB
}
})
對于 components 對象中的每個屬性來說,其屬性名就是自定義元素的名字(component-a、component-b),其屬性值就是這個組件的選項對象(ComponentA、ComponentB)。
我們也可以在實例選項中注冊局部組件,這樣組件只能在這個實例中使用:
定義兩個局部組件
<script src="https://unpkg.com/vue@next"></script>
<div id="app">
<runoob-a></runoob-a>
<runoob-b></runoob-b>
</div>
<script>
var runoobA = {
template: '<h1>自定義組件A!</h1>'
}
var runoobB = {
template: '<h1>自定義組件B!</h1>'
}
const app = Vue.createApp({
components: {
'runoob-a': runoobA,
'runoob-b': runoobB,
}
})
app.mount('#app')
</script>
瀏覽器渲染結果:
Prop
prop 是子組件用來接受父組件傳遞過來的數據的一個自定義屬性。
父組件的數據需要通過 props 把數據傳給子組件,子組件需要顯式地用 props 選項聲明 "prop":
一個組件默認可以擁有任意數量的 prop,任何值都可以傳遞給任何 prop。
<script src="https://unpkg.com/vue@next"></script>
<div id="app">
<site-name name="Muze" mail="1@1.com"></site-name>
</div>
<script>
const app = Vue.createApp({})
app.component('site-name', {
props: ['name', 'mail'],
template: `<h2>昵稱:{{ name }}<br />郵箱:{{ mail }}</h2>`
})
app.mount('#app')
</script>
瀏覽器渲染結果
動態 Prop
類似于用 v-bind 綁定 HTML 特性到一個表達式,也可以用 v-bind 動態綁定 props 的值到父組件的數據中。每當父組件的數據變化時,該變化也會傳導給子組件:
<div id="app">
<site-info v-for="site in sites" :id="site.id" :title="site.title"></site-info>
</div>
<script>
const Site = {
data() {
return {
sites: [
{ id: 1, title: 'Google' },
{ id: 2, title: 'Runoob' },
{ id: 3, title: 'Taobao' }
]
}
}
}
const app = Vue.createApp(Site)
app.component('site-info', {
props: ['id', 'title'],
template: `<h4>{{ id }} - {{ title }}</h4>`
})
app.mount('#app')
</script>
瀏覽器演示效果
限制
- 類型屬性:type:xx
- 必傳屬性:required:true
- 默認屬性:default:xx
Prop 驗證
組件可以為 props 指定驗證要求。
為了定制 prop 的驗證方式,你可以為 props 中的值提供一個帶有驗證需求的對象,而不是一個字符串數組。例如:
Vue.component('my-component', {
props: {
// 基礎的類型檢查 (`null` 和 `undefined` 會通過任何類型驗證)
propA: Number,
// 多個可能的類型
propB: [String, Number],
// 必填的字符串
propC: {
type: String,
required: true
},
// 帶有默認值的數字
propD: {
type: Number,
default: 100
},
// 帶有默認值的對象
propE: {
type: Object,
// 對象或數組默認值必須從一個工廠函數獲取
default: function () {
return { message: 'hello' }
}
},
// 自定義驗證函數
propF: {
validator: function (value) {
// 這個值必須匹配下列字符串中的一個
return ['success', 'warning', 'danger'].indexOf(value) !== -1
}
}
}
})
當 prop 驗證失敗的時候,(開發環境構建版本的) Vue 將會產生一個控制臺的警告。
type 可以是下面原生構造器:
String
Number
Boolean
Array
Object
Date
Function
Symbol
type 也可以是一個自定義構造器,使用 instanceof 檢測。
例子
<script src="https://unpkg.com/vue@next"></script>
<div id="app">
<site-name name="Muze" mail="1@1.com" age="18"></site-name>
</div>
<script>
const app = Vue.createApp({})
app.component('site-name', {
props: {
//昵稱
"name": {
type: String, //類型屬性
required: true, //必傳屬性
default: "外星人", //默認值
},
//郵箱
"mail": {
type: String,
required: false,
default: "myemail@email.com",
},
//年齡
"age": {
type: Number,
required: true,
default: "未知",
}
},
template: `<h2>
昵稱:{{ name }}<br />
郵箱:{{ mail }}<br />
年齡:{{ age }}</h2>`
})
app.mount('#app')
</script>
瀏覽器渲染
組件接收外部傳來數據的三種方式:
(1)只接收:props: ['name','age','sex']
(2)接收并限制類型:props: { "name":Number }
(3)限制類型、限制必要性指定默認值:
props:{
"name":{
type:String,
required:true
},
"age":{
type:Number,
default:18
},
"sex":{
type:String,
default:'男'
},
},
年齡+1歲
<site-name name="Muze" mail="1@1.com" :age="18"></site-name>
年齡:{{ age+1 }}</h2>
做個按鈕,年齡點擊變99歲
待完善
實戰代碼
<script src="https://unpkg.com/vue@next"></script>
<div id="app">
<h1>{{ msg }}</h1>
<button @click="add">計數器:{{counte}}</button>
<site-name></site-name>
</div>
<script>
//父組件
const appRoot = {
data() {
return {
msg: "個人基本信息",
counte: 1,
}
},
methods: {
add() {
this.counte += 1;
}
},
}
app = Vue.createApp(appRoot);
//子組件
app.component('site-name', {
props: {
//年齡
"age": {
type: Number,
required: true,
default: "18",
}
},
template: `<h2>年齡:{{ age }}</h2>`,
})
app.mount('#app');
</script>
瀏覽器渲染