一、使用vue腳手架初始化一個項目
使用vue created Tianm,建立一個名為Tianm的項目。
按照自己的習慣設定腳手架風格,這裡不多做介紹。
腳手架搭建完畢後,将App.vue檔案下的自帶内容清理一下,為後續開發做準備。
二、如何封裝,注冊和使用一個元件
在componet下建立一個button.vue的檔案,放置button元件代碼。建立一個組建的button元件,,并且指定name為oneButton。
<template>
<button class="one-button">
按鈕元件
</button>
</template>
<script>
export default {
name: 'oneButton'
}
</script>
<style lang="scss">
</style>
建立元件完成後,不能在項目中直接使用,需要到main.js中注冊才可以使用。
import Vue from 'vue'
import App from './App.vue'
// 第一步:導入button元件
import OneButton from './components/button.vue'
Vue.config.productionTip = false
// 第二步:注冊元件,設定(元件名,元件)
Vue.component(OneButton.name, OneButton)
new Vue({
render: h => h(App)
}).$mount('#app')
注冊完成後,元件就可以在項目中使用了。
<template>
<div>
<one-button></one-button>
</div>
</template>
元件最簡單的封裝,注冊和使用方法就是這樣一個流程。
三、封裝一個element-ui風格的按鈕
需要使用到的知識:
元件通訊
元件插槽
props校驗
參數支援:
參數名 參數描述 參數類型 預設值
type 按鈕類型(primary/success/warning/danger/info) string default
plain 是否是樸素按鈕 boolean false
round 是否是圓角按鈕 boolean false
circle 是否是圓形按鈕 boolean false
disabled 是否禁用按鈕 boolean false
icon 圖示類名 string 無
事件支援:
事件名 事件描述
click 點選事件
使用插槽:
簡單來說,凡是希望元件中内容可以靈活設定的地方,都需要用到slot插槽來自定義内容。
使用slot來定義按鈕上的文本内容:
<template>
<button class="one-button">
<span><slot></slot></span>
</button>
</template>
在使用時就可以直接輸入文本,定義按鈕文本内容了:
<template>
<div>
<one-button>登入</one-button>
<one-button>删除</one-button>
<one-button>取消</one-button>
</div>
</template>
button元件基礎樣式:
<style lang="scss">
.one-button{
display: inline-block;
line-height: 1;
white-space: nowrap;
cursor: pointer;
background: #ffffff;
border: 1px solid #dcdfe6;
color: #606266;
-webkit-appearance: none;
text-align: center;
box-sizing: border-box;
outline: none;
margin: 0;
transition: 0.1s;
font-weight: 500;
//禁止元素的文字被選中
-moz-user-select: none;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
padding: 12px 20px;
font-size: 14px;
border-radius: 4px;
&:hover,
&:hover{
color: #409eff;
border-color: #c6e2ff;
background-color: #ecf5ff;
}
}
</style>
3.1button元件的type屬性
讓按鈕支援type屬性,使得按鈕支援不同樣式:
第一步:父元件元件傳遞type屬性
<template>
<div id="app">
<div class="row">
<one-button>按鈕</one-button>
<one-button type="primary">primary按鈕</one-button>
<one-button type="success">success按鈕</one-button>
<one-button type="info">info按鈕</one-button>
<one-button type="danger">danger按鈕</one-button>
<one-button type="warning">warning按鈕</one-button>
</div>
</div>
</template>
第二步:子元件接收負元件傳遞的資料
export default {
name: 'oneButton',
// 此時對props進行校驗,值接收string類型的type值
props: {
type:{
type: String,
// 設定預設值:如果不傳值,那麼使用default
default: 'default'
}
},
created () {
console.log(this.type)//defalut primary success info danger warning
}
}
此時對type進行校驗,如果傳遞了非String類型的值(這裡我傳遞了123),将會報錯。
第三步:通過綁定類名的方法動态控制樣式
<template>
<button class="one-button" :class="`one-button-${type}`">
<span><slot></slot></span>
</button>
</template>
第四步:設定不同類型的樣式
.one-button-primary{
color:#fff;
background-color: #409eff;
border-color: #409eff;
&:hover,
&:focus{
background: #66b1ff;
background-color: #66b1ff;
color: #fff;
}
}
.one-button-success{
color:#fff;
background-color: #67c23a;
border-color: #67c23a;
&:hover,
&:focus{
background: #85ce61;
background-color: #85ce61;
color: #fff;
}
}
.one-button-info{
color:#fff;
background-color: #909399;
border-color: #909399;
&:hover,
&:focus{
background: #a6a9ad;
background-color: #a6a9ad;
color: #fff;
}
}
.one-button-warning{
color:#fff;
background-color: #e6a23c;
border-color: #e6a23c;
&:hover,
&:focus{
background: #ebb563;
background-color: #ebb563;
color: #fff;
}
}
.one-button-danger{
color:#fff;
background-color: #f56c6c;
border-color: #f56c6c;
&:hover,
&:focus{
background: #f78989;
background-color: #f78989;
color: #fff;
}
}
3.2button元件的plain屬性
和type類型相同,我們隻要将樣式先設定好,然後通過父元件傳遞過來的值進行判斷,就可以設定plain屬性了。
第一步:父元件元件傳遞plain值
<template>
<div id="app">
<div class="row">
<one-button plain>按鈕</one-button>
<one-button plain type="primary">primary按鈕</one-button>
<one-button plain type="success">success按鈕</one-button>
<one-button plain type="info">info按鈕</one-button>
<one-button plain type="danger">danger按鈕</one-button>
<one-button plain type="warning">warning按鈕</one-button>
</div>
</div>
</template>
第二步:子元件接收負元件傳遞的資料,同樣進行props校驗,并且設定預設值為false
props: {
plain: {
type: Boolean,
default: false
}
}
第三步:通過綁定類名的方法動态控制樣式,由于plain類型是布爾值,是以在類型中我們使用對象的形式來控制樣式
<template>
<button class="one-button" :class="[`one-button-${type}`,{
'is-plain':plain
}]">
<span><slot></slot></span>
</button>
</template>
第四步:設定不同類型的樣式,由于plain類型是以對象的形式在類中定義的,是以使用擷取屬性的方法定義樣式
// 樸素按鈕樣式
.one-button.is-plain{
&:hover,
&:focus{
background: #fff;
border-color: #489eff;
color: #409eff;
}
}
.one-button-primary.is-plain{
color: #409eff;
background: #ecf5ff;
&:hover,
&:focus{
background: #409eff;
border-color: #409eff;
color: #fff;
}
}
.one-button-success.is-plain{
color: #67c23a;
background: #c2e7b0;
&:hover,
&:focus{
background: #67c23a;
border-color: #67c23a;
color: #fff;
}
}
.one-button-info.is-plain{
color: #909399;
background: #d3d4d6;
&:hover,
&:focus{
background: #909399;
border-color: #909399;
color: #fff;
}
}
.one-button-warning.is-plain{
color: #e6a23c;
background: #f5dab1;
&:hover,
&:focus{
background: #e6a23c;
border-color: #e6a23c;
color: #fff;
}
}
.one-button-danger.is-plain{
color: #f56c6c;
background: #fbc4c4;
&:hover,
&:focus{
background: #f56c6c;
border-color: #f56c6c;
color: #fff;
}
}
3.3button元件的round屬性
設定round屬性和之前的相似,隻要在元件中定義好了樣式,動态擷取屬性值即可。
擷取屬性值:
round: {
type: Boolean,
default: false
}
round樣式:
.one-button.is-round{
border-radius: 20px;
padding: 12px 23px;
}
3.4button元件的circle屬性
circle同樣是上面的方法,樣式為:
.one-button.is-circle{
border-radius: 50%;
padding: 12px;
}
3.5button元件中使用字型圖示
在項目中使用字型圖示,首先需要有字型圖示,我們可以去阿裡巴巴矢量圖示庫下載下傳。
下載下傳完成後,在asset目錄下建立一個fonts目錄,存放我們下載下傳到的字型圖示。
做完準備工作後,我們就可以開始把字型圖示運用到項目中了。
第一步:在main.js中引入字型圖示
第二步:将下載下傳的字型圖示css檔案中的類名做修改,我将icon全部改為了one-icon,并且将初始的iconfont類改為了[class*=‘one-icon’],當類名中有one-icon時使用,如下
[class*='one-icon'] {
font-family: "iconfont" !important;
font-size: 16px;
font-style: normal;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
.one-icon-bluetoothoff:before {
content: "\e697";
}
第三步:父元件傳遞圖示名,子元件接收并且放到圖示中
父元件傳值:
<div class="row">
<one-button icon="bluetoothon"></one-button>
<one-button type="primary" icon="camera">照相機</one-button>
<one-button type="success" icon="course"></one-button>
<one-button type="info" icon="bluetooth_link"></one-button>
<one-button type="danger" icon="addto"></one-button>
<one-button type="warning" icon="audio"></one-button>
</div>
子元件接收:
icon: {
type: String,
default: ''
}
使用接收到的字型圖示。在沒有傳入icon時隐藏标簽,在slot插槽沒有傳入值時,不顯示标簽
<template>
<button class="one-button" :class="[`one-button-${type}`,{
'is-plain':plain,
'is-round':round,
'is-circle':circle,
}]">
<i v-if="icon" :class="`one-icon-${icon}`"></i>
<!-- 如果沒傳入文本插槽,則不顯示span内容 -->
<span v-if="$slots.default"><slot></slot></span>
</button>
</template>
第四步:設定icon配套樣式,使圖示和文字之間有一定間隔
.one-button [class*=one-icon-]+span{
margin-left: 5px;
}
3.6button元件中的點選事件
我們在使用元件時,直接給元件定義事件是不會被觸發的。我們需要在元件中定義一個點選事件,這個點選事件不進行其他操作,隻出發父元件中的點選事件。
元件中的定義點選事件:
<template>
<button class="one-button" :class="[`one-button-${type}`,{
'is-plain':plain,
'is-round':round,
'is-circle':circle,
}]"
@click="handleClick"
>
<i v-if="icon" :class="`one-icon-${icon}`"></i>
<!-- 如果沒傳入文本插槽,則不顯示span内容 -->
<span v-if="$slots.default"><slot></slot></span>
</button>
</template>
定義一個點選事件,這個點選事件的作用是調用父元件中的點選事件,并且回調
methods: {
handleClick (e) {
this.$emit('click', e)
}
}
父元件在使用時定義自己的點選事件,其本質是子元件中的點選事件觸發父元件中的點選事件。
<div class="row">
<one-button @click="getInfo">按鈕</one-button>
</div>
methods: {
getInfo () {
console.log('擷取資訊!!')//擷取資訊!!
}
}
3.7button元件中的disabled屬性
和之前相似,隻要父子元件傳值并且動态擷取這個值并且賦給disabled屬性,并且設定一個disabled樣式即可。
<div class="row">
<one-button @click="getInfo" disabled>按鈕</one-button>
</div>
<template>
<button class="one-button" :class="[`one-button-${type}`,{
'is-plain':plain,
'is-round':round,
'is-circle':circle,
'is-disabled':disabled
}]"
@click="handleClick"
:disabled="disabled"
>
<i v-if="icon" :class="`one-icon-${icon}`"></i>
<span v-if="$slots.default"><slot></slot></span>
</button>
</template>
disabled: {
type: Boolean,
default: false
}
disabled樣式:
.one-button.is-disabled{
cursor: no-drop;
}
附元件代碼:
<template>
<button class="one-button" :class="[`one-button-${type}`,{
'is-plain':plain,
'is-round':round,
'is-circle':circle,
'is-disabled':disabled
}]"
@click="handleClick"
:disabled="disabled"
>
<i v-if="icon" :class="`one-icon-${icon}`"></i>
<!-- 如果沒傳入文本插槽,則不顯示span内容 -->
<span v-if="$slots.default"><slot></slot></span>
</button>
</template>
<script>
export default {
name: 'oneButton',
// 此時對props進行校驗,值接收string類型的type值
props: {
type: {
type: String,
// 設定預設值:如果不傳值,那麼使用default
default: 'defalut'
},
plain: {
type: Boolean,
default: false
},
round: {
type: Boolean,
default: false
},
circle: {
type: Boolean,
default: false
},
icon: {
type: String,
default: ''
},
disabled: {
type: Boolean,
default: false
}
},
created () {
// 顯示所有插槽
// console.log(this.$slots)
},
methods: {
// 定義一個點選事件,這個點選事件的作用是調用父元件中的點選事件,并且回調
handleClick (e) {
this.$emit('click', e)
}
}
}
</script>
<style lang="scss" scoped>
.one-button{
display: inline-block;
line-height: 1;
white-space: nowrap;
cursor: pointer;
background: #ffffff;
border: 1px solid #dcdfe6;
color: #606266;
-webkit-appearance: none;
text-align: center;
box-sizing: border-box;
outline: none;
margin: 0;
transition: 0.1s;
font-weight: 500;
//禁止元素的文字被選中
-moz-user-select: none;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
padding: 12px 20px;
font-size: 14px;
border-radius: 4px;
&:hover,
&:focus{
color: #409eff;
border-color: #c6e2ff;
background-color: #ecf5ff;
}
}
.one-button-primary{
color:#fff;
background-color: #409eff;
border-color: #409eff;
&:hover,
&:focus{
background: #66b1ff;
background-color: #66b1ff;
color: #fff;
}
}
.one-button-success{
color:#fff;
background-color: #67c23a;
border-color: #67c23a;
&:hover,
&:focus{
background: #85ce61;
background-color: #85ce61;
color: #fff;
}
}
.one-button-info{
color:#fff;
background-color: #909399;
border-color: #909399;
&:hover,
&:focus{
background: #a6a9ad;
background-color: #a6a9ad;
color: #fff;
}
}
.one-button-warning{
color:#fff;
background-color: #e6a23c;
border-color: #e6a23c;
&:hover,
&:focus{
background: #ebb563;
background-color: #ebb563;
color: #fff;
}
}
.one-button-danger{
color:#fff;
background-color: #f56c6c;
border-color: #f56c6c;
&:hover,
&:focus{
background: #f78989;
background-color: #f78989;
color: #fff;
}
}
// 樸素按鈕樣式
.one-button.is-plain{
&:hover,
&:focus{
background: #fff;
border-color: #489eff;
color: #409eff;
}
}
.one-button-primary.is-plain{
color: #409eff;
background: #ecf5ff;
&:hover,
&:focus{
background: #409eff;
border-color: #409eff;
color: #fff;
}
}
.one-button-success.is-plain{
color: #67c23a;
background: #c2e7b0;
&:hover,
&:focus{
background: #67c23a;
border-color: #67c23a;
color: #fff;
}
}
.one-button-info.is-plain{
color: #909399;
background: #d3d4d6;
&:hover,
&:focus{
background: #909399;
border-color: #909399;
color: #fff;
}
}
.one-button-warning.is-plain{
color: #e6a23c;
background: #f5dab1;
&:hover,
&:focus{
background: #e6a23c;
border-color: #e6a23c;
color: #fff;
}
}
.one-button-danger.is-plain{
color: #f56c6c;
background: #fbc4c4;
&:hover,
&:focus{
background: #f56c6c;
border-color: #f56c6c;
color: #fff;
}
}
// round屬性
.one-button.is-round{
border-radius: 20px;
padding: 12px 23px;
}
// circle屬性
.one-button.is-circle{
border-radius: 50%;
padding: 12px;
}
// icon配套樣式
.one-button [class*=one-icon-]+span{
margin-left: 5px;
}
// disabled屬性
.one-button.is-disabled{
cursor: no-drop;
}
</style>