一、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() { },这个组件的生命周期回调中拿到。
对于本文不足之处,恳请大佬们留言指正,不胜感激!(Q443673422)