組件其實就是一個擁有樣式、動畫、js邏輯、HTML結構的綜合塊。前端組件化確實讓大的前端團隊更高效的開發前端項目。而作為前端比較流行的框架之一,Vue的組件和也做的非常徹底,而且有自己的特色。尤其是她單文件組件開發的方式更是非常方便,而且第三方工具支持也非常豐富,社區也非常活躍,第三方組件也呈井噴之勢。當然學習和使用Vue的組件也是我們的最重要的目標。
6.1. 全局擴展方法Vue.extend
Vue提供了一個全局的API,Vue.extend
可以幫助我們對Vue實例進行擴展,擴展完了之后,就可以用此擴展對象創建新的Vue實例了。 類似於繼承的方式。
語法:Vue.extend( options )
參數:
{Object} options
用法:
使用基礎 Vue 構造器,創建一個“子類”。參數是一個包含組件選項的對象[后面會細講]。
data 選項是特例,需要注意 - 在 Vue.extend() 中它必須是函數
下面是一個官網demo:
<div id="mount-point"></div>
<script>
// 創建構造器
var Profile = Vue.extend({
// 新的對象的模板,所有子實例都會擁有此模板
template: '<p>{{firstName}} {{lastName}} aka {{alias}}</p>',
data: function () { // 創建的Vue實例時,data可以是Object 也可以是Function,但是在擴展
return { // 的時候,data必須是一個函數,而且要返回值奧。
firstName: 'Walter',
lastName: 'White',
alias: 'Heisenberg'
}
}
})
</script>
// 創建 Profile 實例,並掛載到一個元素上。
new Profile().$mount('#mount-point')
// .$mount() 方法跟設置 el屬性效果是一致的。
結果如下:
<p>Walter White aka Heisenberg</p>
綜合案例代碼:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Vue入門之extend全局方法</title>
<script src="https://unpkg.com/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
</div>
<script>
var myVue = Vue.extend({
template: '<div>{{ name }} - {{ age }} - {{ mail }}</div>',
data: function () {
return {
name: 'malun',
age: '19',
mail: 'flydragonml@gmail.com'
};
}
});
var app = new myVue({
el: '#app'
});
</script>
</body>
</html>
6.2. 創建組件和注冊組件
當然上面的方式只是能讓我們繼承Vue實例做一些擴展的動作。看Vue中如何創建一個組件並注冊使用。
Vue提供了一個全局注冊組件的方法:Vue.component。
語法: Vue.component( id, [definition] )
參數:
{string} id 組件的名字,可以當HTML標簽用,注意組件的名字都是小寫,而且最好有橫線和字母組合。
{Function | Object} [definition] 組件的設置
用法:
注冊或獲取全局組件。注冊還會自動使用給定的id設置組件的名稱
// 注冊組件,傳入一個擴展過的構造器
Vue.component('my-component', Vue.extend({ /* ... */ }))
// 注冊組件,傳入一個選項對象(自動調用 Vue.extend)
Vue.component('my-component', { /* ... */ })
// 獲取注冊的組件(始終返回構造器)
var MyComponent = Vue.component('my-component')
簡單demo:
<div id="example">
<!--組件直接跟普通的標簽一樣的使用。-->
<my-component></my-component>
</div>
// 注冊一個組件
Vue.component('my-component', {
// 模板選項設置當前組件,最終輸出的html模板。注意:有且只有一個根元素。
template: '<div>A custom component!</div>'
})
// 創建根實例
new Vue({
el: '#example'
})
那么我們注冊一個組件自動幫我生成 label和radiobutton組合。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Vue入門之extend全局方法</title>
<script src="https://unpkg.com/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<!--組件名直接可以當標簽使用。-->
<radio-tag rid="rBas" txt="籃球" val="1"></radio-tag>
<!--組件的屬性也可以使用Vue的綁定的語法,下面是動態綁定數據給子組件-->
<radio-tag :rid="demoId" :txt="demoText" :val="demoVal"></radio-tag>
</div>
<script>
// 定義組件模板,模板必須有且只有一個根元素。
var temp = '<div><label v-bind:for="rid">{{ txt }}</label><input :id="rid" type="radio" v-bind:value="val"></div>';
// 注冊一個全局的組件
Vue.component('radio-tag', { // 組件的名字不能有大寫字母,跟React的曲別啊。另外組件名最好是小寫字母加橫線組合。
template: temp,
props: ['rid', 'txt', 'val'], // 設置組件的屬性有哪些,定義標簽的屬性一致。
data: function () { // 注意屬性名都得是小寫,不然會不認的。
return { // 在組件的定義中data必須是函數,而且必須有返回值。
age: 19, // 此地方的 age 和 emial都是演示,並么有有到。
email: 'flydragonml@gmail.com'
}
}
});
// 初始化一個Vue實例
var app = new Vue({
el: '#app',
data: {
demoId: 'ft',
demoText: '足球',
demoVal: 2
}
});
</script>
</body>
</html>
注意結果點
- 組件的名字都必須是小寫【其實是非必須,但是為了不麻煩就強制吧】!!!而且建議是小寫字母和橫線的組合比如: my-radiobtn
- 注冊組件的時候,可以傳入一個選項對象進行配置。其中
props
是設置當前組件的屬性,屬性也都必須小寫。屬性是連接父容器和子組件的橋梁。 - 注意:屬性名和組件的名字都要小寫啊,不然vue不會認的。
- 編寫組件代碼最好配合Vue的chrome插件:vue-devtool
- 組件可以返還自己的數據,但是必須是函數。data必須是Function
6.3. 局部注冊組件
全局注冊組件就是使用全局API
Vue.componet(id, {....})
就行了,當然我們有時候需要注冊一個局部模塊的自己用的組件。那么就可以用下面的方式了。
var Child = {
template: '<div>A custom component!</div>'
}
new Vue({
// ...
components: {
// <my-component> 將只在父模板可用
'my-component': Child
}
})
6.4. 組件的slot
使用組件的時候,經常需要在父組件中為子組件中插入一些標簽等。當然其實可以通過屬性等操作,但是比較麻煩,直接寫標簽還是方便很多。 那么Vue提供了slot協助子組件對父容器寫入的標簽進行管理。
當父容器寫了額外的內容時, 如果子組件恰好有一個slot標簽,那邊子容器的slot標簽會被父容器寫入的內容替換掉。
比如下面的例子:
<!DOCTYPE html>
<<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Vue入門之extend全局方法</title>
<script src="https://unpkg.com/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<!--父容器輸入標簽-->
<my-slot>
<h3>這里是父容器寫入的</h3>
</my-slot>
<!--父容器綁定數據到子容器的slot,這里的作用域是父容器的啊。-->
<my-slot>{{ email }}</my-slot>
<!--父容器什么都不傳內容-->
<my-slot></my-slot>
</div>
<script>
// 反引號:可以定義多行字符串。
var temp = `
<div>
<h1>這里是子組件</h1>
<hr>
<slot>slot標簽會被父容器寫的額外的內容替換掉,如果父容器沒有寫入任何東西,此標簽將保留!</slot>
</div>
`;
Vue.component('MySlot', { // 如果定義的組件為MySlot,那么用組件的時候:<my-slot></my-slot>
template: temp,
});
// 初始化一個Vue實例
var app = new Vue({
el: '#app',
data: {
email: 'flydragon@gmail.com'
}
});
</script>
</body>
</html>
最終結果:
<div id="app">
<div>
<h1>這里是子組件</h1>
<hr>
<h3>這里是父容器寫入的</h3>
</div>
<div>
<h1>這里是子組件</h1>
<hr> flydragon@gmail.com
</div>
<div>
<h1>這里是子組件</h1>
<hr> slot標簽會被父容器寫的額外的內容替換掉,如果父容器沒有寫入任何東西,此標簽將刪除!
</div>
</div>
6.5. 單文件組件的使用方式介紹
通過上面我們定義組件的方式,就已經感覺很不爽了,尤其是模板的定義,而且樣式怎么處理也沒有很好的進行規整。 Vue可以通過Webpack等第三方工具實現單文件的開發的方式。當然這里會牽扯到很多es6的語法、第三方工具實現前端模塊化等很多知識, 我們大概看一眼指導Vue的組件可以直接寫一個文件中,其他地方就可以直接導入這個模塊了。后面做項目的時候我還會再講一下怎么用。
<template>
<div>
<nav class="navbar navbar-dark navbar-fixed-top">
</nav>
<div class="col-md-3 sidebar">
<ul>
<li v-for="item in list" >
<router-link :to="{ path: item.url }">{{ item.name }}</router-link>
</li>
</ul>
</div>
<div class="container-fluid content">
<router-view></router-view>
</div>
</div>
</div>
</template>
<script>
// 這里怎么回事
import Axios from 'axios'
export default {
name: 'app',
components: {
},
data: function () {
return {
list: []
}
},
mounted: function () { // 掛在完成后
this.$nextTick(function () {
Axios.get('/api/menulist', {
params: {
}
}).then(function (res) {
this.list = res.data
}.bind(this))
})
}
}
</script>
<style>
ul, li {
list-style: none;
}
.router-link-active {
background-color: #f6f6f6;
}
.navbar {
height: 50px;
background-color: #303030;
}
.content {
margin-top: 50px;
padding-left: 210px;
}
.sidebar {
background-color: #f5f5f5;
border-right: 1px solid #eee;
width: 200px;
}
@media (min-width: 768px) {
.sidebar {
position: fixed;
top: 51px;
bottom: 0;
left: 0;
z-index: 1000;
display: block;
padding: 20px;
overflow-x: hidden;
overflow-y: auto; /* Scrollable contents if viewport is shorter than content. */
background-color: #f5f5f5;
border-right: 1px solid #eee;
}
}
</style>
單文件書寫組件的方式必須要配合webpack之類的工具才行,所以這里暫時不講解如何做,后面到項目階段的時候再詳細講解。 不過你可以參考:Vue官網單文件組件
6.6. 組件總結
Vue的組件化還是做的比較徹底的。不像Angular1.0中的模塊那么雞肋。組件化確實讓前端模塊化開發更加容易實現, Vue的單文件開發組件的方式也是Vue的一大創新,也發非常好用。
聯系老馬
對應視頻地址:https://chuanke.baidu.com/s5508922.html
老馬qq: 515154084
老馬微信:請掃碼
