uniapp actionsheet custom component

The actionsheet that comes with uniapp itself is too ugly and not beautiful enough. Idle is also idle, I implemented a similar selector.

Supported functions:

1. Align left

2. Align right

3. Centered

4. Icons can be added

The usage tutorial is posted below:

<template>
    <view>
        <action-sheet alignment="left" :showSheetView="showSheetView" :displayCheckedIcon="true" :optionsList="deseaseList" titleKey="name" iconKey="cover" @ onSelected="onSelected"></action-sheet>
    </view>
</template>
<script>
    import actionSheet from '@/components/zxp-uniActionSheet.vue'

    export default
    {
        data() {
            return {
                deseaseList: [],
                showSheetView:false
            };
        },
        components:{
            actionSheet
        },
        methods:{
            onSelected(row){
                /*The value must be set to false here, otherwise the next pop-up display cannot be evoked*/
                this.showSheetView = false
            }
        }
    }
</script>

Component implementation code: Create a component file named zxp-uniActionSheet.vue in the appropriate directory of your project. It is generally located in the components directory of the project. Pay attention to the reference location in the directory and page!

Or introduce it directly into your project through hbuilderx!

actionsheet custom component – DCloud plug-in market

<template>
<view class="view-modal" v-if="showSheetView" :class="[modalAnimation?'ani_start':'ani_end']">
<view class="sheet-view" :class="[modalAnimation?'ani-top':'ani-btm']">
<view class="head-view">
<view class="cancel-view" @click="cancelAction">
<text>Cancel</text>
</view>
<view class="title-view">
<text>{<!-- -->{sheetTitle}}</text>
</view>
<view class="ok-view" @click="okAction">
<text>OK</text>
</view>
</view>
<scroll-view scroll-y="true" class="scroll-view">
<view class="cell-row"
:class="[alignment==='left'?'align-left':alignment==='right'?'align-right':'']"
v-for="(item,index) in dataList" :key="index" @click.stop="didSelectedRow(index)">
<image v-if="item[`${iconKey}`]" class="cell-icon" :src="item[`${iconKey}`]"></image>
<text class="cell-label"
:class="[index===selectIndex?'hilight-label':'',item[`${iconKey}`]?'':'cell-lb-pad'] ">{<!-- -->{item[`${titleKey}`]}}</text>
<image v-if="displayCheckedIcon & amp; & amp; index===selectIndex" class="cell-check-icon"
:src="'data:image/png;base64,' + checkIconData"></image>
</view>
</scroll-view>
</view>
</view>
</template>

<script>
export default {
data() {
return {
viewTitle: null,
selectIndex: 0,
dataList: [],
modalAnimation: false,
checkIconData: ''
};
},
props: {
showSheetView: {
type: Boolean,
default: false
},
optionsList: {
type: Array,
default: []
},
titleKey: {
type: String,
default: ""
},
iconKey: {
type: String,
default: ""
},
defaultIndex: {
type: Number,
default: 0
},
sheetTitle: {
type: String,
default: "Please select"
},
alignment: {
type: String,
default: "center"
},
displayCheckedIcon: {
type: Boolean,
default: false
},
autoConfirm: {
type: Boolean,
default: true
},
},
created() {
this.viewTitle = this.sheetTitle
this.selectIndex = this.defaultIndex
this.dataList = this.optionsList
\t\t\t
let icon = 'iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAAXNSR0IArs4c6QAAAchJREFUeF7tmUFywjAMReXQi + QkDceCLgqLwrHgJrkIE3fClA5DE5AcyZJrsXZivecvOwkBKv + FyvnBBXgCKjfgLVB5AHwT9Bbw FqjcgLdA5QHwU8BbwFugcgP/ogWar34HAT4jwHkVYH/ZtGfsuhYvIBz6UwDo7oGHbYvmQg/EGs05bgp + nL8JsMamoFgBc/BVCHgGDxH2w0e7wyaxuARwwo + SihLADV + UAAn4YgRIwRchQBKeLODt2 HfY8xW7Cz8bJw2PFjCCDxFOv8USj5oUGTng0QImixGUkAseLaA59HFyFQUk5ITHC/h525KWkBseLeA6cOKti3NPkL7/3D5EehKUKlLqvpjNlyRAIgma8KQWuLfJVTTXfTArzdICnBIswCcn4CYiFSL1uiUrzZ 6AVAmW4BcngCrBGjybAMzpEAO8P3695XyOSG0P8jGY/PY2d6HA4zRFBquAl0l4rEwZnrUF0EfkbaABeDEBL5NgBF5UwKwEQ/DiAv5IMAafRcA4yfWT2gAd5R8byk6 + ZCz7KbCkGI1rXYCGdUtzegIsrYZGL Z4ADeuW5vQEWFoNjVo8ARrWLc3pCbC0Ghq1eAI0rFuas/oEfAN/0AhQ3IEvrwAAAABJRU5ErkJggg=='
\t\t\t
this.checkIconData = icon.replace(/[\r\\
]/g, "");
},
computed: {
},
watch: {
showSheetView: {
handler: function(flag) {
this.modalAnimation = flag
this.dataList = this.optionsList
},
immediate: true
}
},
methods: {
cancelAction: function() {
this.modalAnimation = false
let self = this
setTimeout(() => {
// self.showSheetView = false
self.$emit('onSelected', {
'cancel': true
})
}, 350);
},
okAction: function() {
this.modalAnimation = false
let data = this.dataList[this.selectIndex]
let self = this
setTimeout(() => {
// self.showSheetView = false
self.$emit('onSelected', {
data: data,
'cancel': false,
'confirm': true
})
}, 350);
},
didSelectedRow(row) {
this.selectIndex = row
if (this.autoConfirm)
{
this.okAction()
}
}
}
}
</script>

<style lang="scss" scoped>
.scroll-view {
width: 100%;
height: 540upx;

display: flex;
flex-direction: column;
justify-content: flex-start;
align-items: center;
}

.cell-row {
width: 100%;
height: 88upx;
border-bottom: 1px solid #eee;
padding: 0upx 20upx;

display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
}

.cell-icon {
width: 40upx;
height: 40upx;
}
\t
.cell-check-icon
{
position: absolute;
right: 30upx;
width: 40upx;
height: 40upx;
}

.cell-label {
padding:0upx 50upx 0upx 20upx;
font-size: 14px;
color: #333333;
\t\t
display: inline-block;
overflow: hidden !important;
text-overflow: ellipsis !important;
white-space: nowrap !important;
line-clamp: 1 !important;
}
\t
.cell-lb-pad
{
padding:0upx 50upx;
}

.hilight-label {
color: #0286df;
}

.align-left {
justify-content: flex-start;
}

.align-right {
justify-content: flex-end;
}

.ani_start {
animation: animationShow 0.4s;
}

.ani_end {
animation: animationHide 0.4s;
}

@keyframes animationShow {
from {
background-color: rgba(0, 0, 0, 0);
opacity: 0;
}

to {
background-color: rgba(0, 0, 0, 0.2);
opacity: 1;
}
}

@keyframes animationHide {
from {
background-color: rgba(0, 0, 0, 0.2);
opacity: 1;
}

to {
background-color: rgba(0, 0, 0, 0);
opacity: 0;
}
}
\t
@keyframes slideBottom {
0% {
transform: translateY(100%)
}
\t
100% {
transform: translateY(0)
}
}
\t

.view-modal {
position: fixed;
top: calc(var(--status-bar-height) + 44px);
// bottom: 0;
height: calc(100% - var(--status-bar-height) - 44px);
width: 100%;
z-index: 1;

display: flex;
flex-direction: column;
justify-content: flex-start;
align-items: center;
background-color: rgba(0, 0, 0, 0.2);
}

.ani-btm {
transform: translateY(640upx);
}

.ani-top {
animation: slideBottom 0.4s;
}


.sheet-view {
position: absolute;
bottom: 0upx;
height: 640upx;
width: 100%;
transition: all 0.25s;
background-color: white;

display: flex;
flex-direction: column;
justify-content: flex-start;
align-items: center;
}

.head-view {
position: relative;
width: calc(100% - 70upx);
height: 100upx;

display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
}

.cancel-view {
position: relative;
width: 124upx;
height: 100%;

display: flex;
flex-direction: column;
justify-content: center;
align-items: center;

text {
position: relative;
width: 100%;
font-size: 32upx;
color: #333333;

text-align: left;
}
}

.title-view {
position: relative;
height: 100%;

display: flex;
flex-direction: column;
justify-content: center;
align-items: center;

text {
position: relative;
width: 100%;
font-size: 30upx;
color: #999999;

text-align: left;
}
}

.ok-view {
position: relative;
width: 124upx;
height: 100%;

display: flex;
flex-direction: column;
justify-content: center;
align-items: center;

text {
position: relative;
width: 100%;
font-size: 32upx;
color: #2197FF;

text-align: right;
}
}

.mid-view {
position: relative;
width: 100%;
height: 106upx;

border-bottom: 1upx solid rgb(235, 235, 235);
border-top: 1upx solid rgb(235, 235, 235);
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
}

.btn-view {
position: relative;
width: 50%;
height: 100%;

display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
}

.tt-view {
position: relative;
width: 100%;
height: 100%;

display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}

.normal-text {
position: relative;
width: 100%;
font-size: 32upx;
color: #555555;
text-align: center;
}

.hili-text {
position: relative;
width: 100%;
font-size: 32upx;
color: #2197FF;
text-align: center;
}

.active {
background-color: white;
}

.non-active {
background-color: rgb(245, 245, 245);
}
</style>

The knowledge points of the article match the official knowledge files, and you can further learn relevant knowledge. Mini program skill treeOther componentsuni-app built-in components 7860 people are learning the system