一、uni-app自定義元件的實作流程概括
(1)在根目錄下建立components的目錄檔案(後續自定義的控件都可以放在這個目錄下)
(2)右鍵components目錄,點選【建立元件】(記得勾選上建立同名目錄)
(3)在新建立的vue檔案中可以實作自己想做的控件。(自定義控件需要實作的細節以及注意的地方可以在下面的代碼示例中檢視)
(4)在pages.json檔案中添加 "globalStyle": {"autoscan":true},即可在外部頁面調用自定義控件(這樣比較友善,還有其他方式調用,頁面注冊、挂載到App.vue中等都行,自行百度)
二、uni-app自定義元件的實作代碼
自定義元件代碼:
<!-- 自定義元件需要定義name,最好是和檔案名一緻 -->
<!-- 本控件為簡單的上圖下文字的控件 -->
<template name="image-text">
<!-- 測試使用的自定義元件 -->
<!-- 本元件為上圖下字的最常用圖示,并添加點選事件 -->
<!-- 外部框的大小、圖檔大小、文字大小,都是根據外部傳入的Size等比例放大和縮小的 -->
<view class="image-text"
:style="{width:baseSize*16 + 'rpx',
height:baseSize*16 + 'rpx'}"
@click="onClick">
<!-- 上面的圖檔 ,width:topImageSize,height:topImageSize-->
<image
:src="imageSrc"
:style="{width:baseSize*8 + 'rpx',height:baseSize*8 + 'rpx'}" class="topImage" ></image>
<!-- 下面的文字 ,fontSize:fontSize,這邊需要注意的是,font-size需要轉換為fontSize-->
<text class="bottomText" :style="{color:textColor,fontSize:baseSize*2 + 'rpx'}">{{textValue}}</text>
<!-- 對于文字也可以使用插值,但是我覺得不好,就沒用,直接定義屬性的方式公開出去了 -->
</view>
</template>
<script>
export default {
/* 元件名字定義 */
name:"image-text",
/* 這邊的設計的話,外面隻需要傳入圖檔的大小即可,文字的大小會自動随着圖檔的變化而變化 */
/* 元件屬性定義,外部可以調用的屬性 */
props:{
imageSrc:{//元件屬性名,外部傳入屬性參數的時候就是用的這個名稱
type:String,//元件屬性的類型
default:""//元件屬性預設值
},
baseSize:{
type:Number,
default:16
},
textColor:
{
type:String,
default:'#000',
},
textValue:
{
type:String,
default:'露露'
}
},
/* 以下是元件的生命周期回調函數 具體的細節,可以百度*/
/* el 被新建立的 vm.$el 替換,并挂載到執行個體上去之後調用該鈎子。如果 root 執行個體挂載了一個文檔内元素,當 mounted 被調用時 vm.$el 也在文檔内。*/
mounted() {
//這邊可以擷取到外面傳入的屬性值,可以對傳入的屬性值做一些操作,我這邊沒有需要,就沒有做
},
//在執行個體初始化之後,資料觀測 (data observer) 和 event/watcher 事件配置之前被調用。
beforeCreate() {
},
//在執行個體建立完成後被立即調用。在這一步,執行個體已完成以下的配置:資料觀測 (data observer),屬性和方法的運算,watch/event 事件回調。然而,挂載階段還沒開始,$el 屬性目前不可見。
created() {
//屬性還不可見,也就是擷取不到屬性值
},
//Vue 執行個體銷毀後調用
destroyed() {
},
data() {
return {
}
},
methods:{
onClick(){
/* 點選了目前的自定義控件 */
//goto即是外部調用事件的名稱 @goto,第二個參數為,可以傳遞的參數
this.$emit('goto','');
}
}
}
</script>
<style>
.image-text{
width: 256rpx;
height: 256rpx;
border: 1rpx solid #007AFF;
display: flex;
flex-direction:column;
flex-wrap: nowrap;
justify-content: center;
align-content: center;
align-items: center;
}
.topImage{
border: 1px solid #000000;
width: 128rpx;
height: 128rpx;
}
.bottomText{
border: 1px solid #000000;
font-size: 32rpx;
}
</style>
外部調用代碼:
<template>
<view>
<image-text
@goto="test" :imageSrc="img"
textValue="Hello World" textColor='#0000ff' :baseSize="mSize" ></image-text>
</view>
</template>
<script>
export default {
data() {
return {
mSize:16,
img:'../../static/logo.png'
}
},
methods: {
}
}
</script>
<style>
</style>
三、自定元件實作過程中遇到的問題
(1)之前以為,每次都要在頁面注冊,覺得有點麻煩,後面發現簡單的方式:
1、挂載到main.js中(import pageHead from './components/page-head.vue';Vue.component('page-head',pageHead))
2、隻要是按照以上流程的自定義控件,隻要在pages.json檔案中添加 "globalStyle": {"autoscan":true}後,即可當做正常控件的方式使用。
(2)在自定義控件的時候,需要動态的去改變字型大小的時候,我這邊使用style,然後每次寫font-style都會顯示錯誤,倒騰很久,才發現,需要改成fontSize。比較弱雞,也可能是因為我還是對前端不夠熟悉導緻的。
(3)傳圖檔參數的位址的時候,可以使用相對路徑。
(4)外部傳入的屬性參數,隻有在mounted() { },這個元件的生命周期回調中拿到。