//移动端使用的是 @pax/pax-ui
npm install @pax/pax-ui
1. 如果使用 UI框架中的actionsheet 上拉菜单
在main.js 中:
//Mobile
import PAXUI from '@pax/pax-ui'
import '@pax/pax-ui/dist/paxui.rem.css'
//全局使用 dialog
import { Confirm, Alert, Toast, Notify, Loading } from '@pax/pax-ui/dist/lib.rem/dialog'
import '@pax/pax-ui/dist/paxui.base.css' //注意:按需引入单个组件,另需导入重置基础样式
Vue.prototype.$dialog = {
confirm: Confirm,
alert: Alert,
toast: Toast,
notify: Notify,
loading: Loading
};
/* ===调用=== */
// this.$dialog.confirm({ /* 参数 */});
// this.$dialog.alert({/* 参数 */});
// this.$dialog.toast({ /* 参数 */ });
// this.$dialog.notify({ /* 参数 */ });
// this.$dialog.loading({ /* 参数 */ });
API示例:
<pax-button-group>
<pax-button @click.native="show1 = true" size="large">带取消</pax-button>
<pax-button @click.native="show2 = true" size="large" type="warning">不带取消</pax-button>
</pax-button-group>
<pax-actionsheet :items="myItems1" v-model="show1" cancel="取消"></pax-actionsheet>
<pax-actionsheet :items="myItems2" v-model="show2"></pax-actionsheet>
export default {
data(){
return {
show1: false,
show2: false,
myItems1: [
{
label: '拍照',
callback: ()=> {
this.$dialog.toast({mes: 'this is a toast', timeout: 1000});
//注意: callback: function (){} 和 callback(){} 这样是无法正常使用当前this的
}
},
{
label: '从相册中偷取',
callback: () => {
this.$dialog.toast({mes:'this is a toast', timeout: 1000});
}
}
],
myItems2: [
{
label: '示例菜单一 - 我是不会关闭的',
callback: () => {
this.$dialog.toast({mes: 'Say: 我是不会关闭的!', timeout: 1000});
},
stay: true // 不关闭
},
{
label: '示例菜单二 - 自动关闭',
callback: () => {
this.$dialog.toast({mes: 'Say: 我关闭啦啦啦!', timeout: 1000});
}
},
{label: '示例菜单三 - 自动关闭'},
{label: '示例菜单四 - 自动关闭'}
]
}
}
}
API:
pax-actionsheet 一共3个参数:
items: [{ //类型: Array
label: String, //菜单项的文本
callback: Function, //点击该菜单项的回调函数
stay: Boolean, //是否关闭 actionsheet (默认false, 直接关闭)
}],
cancel: 取消按钮的文本,为空则不显示取消按钮 //类型: String
masker-opacity: 遮罩层透明度 //类型: Number 默认值:0.5
2. 在 order_details_tabs.vue 组件中调用:
2.1 (第一种)如果把参数写死
<template>
<!-- 快捷支付 -->
<!-- 通过点击事件 @click.native="show2=true" 去调取 actionsheet 上拉菜单 -->
<pax-cell-item @click.native="show2=true"
arrow
type="div"
href="javascript:;">
<span slot="left">付款方式</span>
<span slot="right">
<i>1</i>
中国银行(2762)
</span>
</pax-cell-item>
<div>
<!-- 上拉菜单 - 选择银行 -->
<pax-actionsheet :items="myBankItems" v-model="show2"></pax-actionsheet>
</div>
</template>
export default {
data(){
return {
show2: false, //显示上拉菜单
myBankItems: [
{
label: '示例菜单一 - 我是不会关闭的',
callback: () => {
this.$dialog.toast({mes: 'Say: 我是不会关闭的!', timeout: 1000});
},
stay: true //不关闭
},
{
label: '示例菜单二 - 自动关闭',
callback: () => {
this.$dialog.toast({mes: 'Say: 我关闭了!', timeout: 1000});
}
},
{label: '示例菜单三 - 自动关闭'},
{label: '添加银行卡'}
]
}
}
}
2.2 (第二种)如果调用 Vuex 中的公共状态, 使用 computed
<template>
<div>
<!-- 上拉菜单 - 选择银行 -->
<pax-actionsheet :items="actionsheetData1"
:cancel="actionsheetCancel1"
v-model="show2">
</pax-actionsheet>
</div>
</template>
computed: {
//得到Vuex中的公共状态
...mapState(['tradesCurrentObj', 'tradesBanksObj']),
actionsheetData1(){ //对actionsheetData1变量进行计算
let arr1 = [
{
label: '请选择银行卡',
callback: () => {
alert('点击了选择银行卡')
}
}
];
//对tradesBanksObj 数组的筛选,进行筛选
//只能使用 for in 来遍历 this.tradesBanksObj 这个数组了
for(let v in this.tradesBanksObj) {
console.log(this.tradesBanksObj[v])
arr1.push({
label: this.tradesBanksObj[v],
callback: () => {
alert(this.tradesBanksObj[v])
}
})
}
let str1 = '666';
function str2(){
return 777
}
arr1.push({
label: `添加银行卡${str1}, ${str2()}`,
callback: () => {
alert('点击了添加银行卡')
}
})
return arr1
},
actionsheetCancel1(){
return '关闭'
}
},
3. 如果不用组件,自己封装一个 actionsheet 全局插件
由于 @pax/pax-ui 这个mobile UI框架的 actionsheet 上拉菜单, 不能放置图标,所以想着自己封装一个 actionsheet 全局插件。
在 src/components 目录,新建 actionsheet/actionsheet.vue 目录及组件。
actionsheet.vue:
<template>
<div>
<transition name="fade">
<div class="actionsheet_wrapper" v-show="open">
<div class="actionsheet">
<div class="_header">
<span class="arrow" @click="cancelFunc">
<img src="/images/arrow.png" />
</span>
<span class="cart">请选择银行卡</span>
<span class="clear" @click="cancelFunc">关闭</span>
</div>
<div class="_content">
<p class="item" v-for="(item, index) in tradesBanksData">
<span class="item_icon">
<img :src="('/images/bank-logo-map/' + item + '.png')" alt="" >
</span>
<span class="item_name"> {{item}} 中国建设银行(2766) </span>
</p>
<p class="item">
<span class="item_icon">
<img src="/images/bank-logo-map/CCB.png" alt="" >
</span>
<span class="item_name">中国银行(6783)</span>
</p>
<!-- 添加银行卡 -->
<p class="item">
<span class="item_icon">
<img src="/images/add-bank.png" alt="" />
</span>
<span class="item_name">添加银行卡</span>
</p>
<!-- <p class="cancel" @click="cancelFunc">取消</p> -->
<p class="cancel"></p>
</div>
</div>
</div>
</transition>
<div class="actionsheet_mask" v-show="open" @click="cancelFunc"></div>
</div>
</template>
<script>
export default {
name: "actionsheet.vue",
data(){
return {}
},
props: {
open: false, //接收从父组件传过来的控制是否显示的属性
tradesBanksData: {} //接收从父组件传过来的, Vuex中的公共状态, 数据(先在父组件中通过mapState获得,然后通过 v-bind:tradesBanksData="tradesBanksObj" 传给自组件)
},
methods: {
//在组件的模板中,给关闭按钮和取消按钮绑定了click事件,
//功能为关闭操作表, 通过 this.$emit 发射该事件到父组件,
//(第一个参数为父组件接收的方法属性名,如果想传递参数
//也可以在后面加上第二个参数)
cancelFunc(){
this.$emit('show');
}
}
}
</script>
<style scoped lang="less">
* {
box-sizing: border-box;
}
.actionsheet_wrapper {
position: fixed;
bottom:0;
left: 0;
width: 100%;
z-index: 1501;
.actionsheet {
background-color:#fff;
._header{
display:flex;
width: 100%;
height: 49px;
padding: 0 8px;
align-items: center;
flex-direction: row;
border-bottom: 1px solid #E6E6E6;
//flex: 0 0 20% 表示占其中的 1/5, 其余的auto
.arrow, .clear{
flex: 0 0 20%!important;
}
.arrow {
text-align:left;
img {
width: 18px;
height: 18px;
position: relative;
top: 2px;
}
}
// flex: 0 0 60%important; 表示占比 60%
.cart {
flex: 0 0 60%!important;
text-align:center;
margin-right:auto;
font-size: 14px;
color:#1111;
}
.clear {
text-align:right;
color: #0894ec;
}
}
._content {
.cancel {
/* background-color: #39678c; */
color:#fff;
height: 49px;
line-height: 49px;
box-sizing: border-box;
/* padding-bottom: 105px; */
}
.item {
height: 49px;
/* border-bottom: 1px solid #e6e6e6; */
display: flex;
align-items: center;
/* justify-content: center; */
padding: 0 8px;
.item_icon {
flex:0 0 10%!important;
margin-right: 6px;
img {
width: 18px;
height: 18px;
position: relative;
top:1px;
}
}
.item_name {
flex: 0 0 90%!important;
text-align: left;
display: inline-block;
height: 49px;
line-height: 49px;
border-bottom: 1px solid #e6e6e6;
}
}
}
}
}
//过渡效果transition使用
//定义transition的name属性值为 fade, 定义从底部向上淡入的滑入和滑出,
//使用 translate3d,在移动端会开启硬件加速器,效果很流畅,接近原生效果
.fade-enter-active, .fade-leave-active {
transition: all .4s ease;
}
.fade-enter, .fade-leave-to {
transform: translate3d(0, 100%, 0);
opacity: 0;
}
//遮罩
.actionsheet_mask {
position: fixed;
bottom:0;
right:0;
left:0;
top:0;
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
-webkit-box-pack: center;
-webkit-justify-content: center;
-ms-flex-pack: center;
justify-content: center;
-webkit-box-align: center;
-webkit-align-items: center;
-ms-flex-align: center;
align-items: center;
pointer-events: none;
-webkit-transition: opacity .2s ease-in;
transition: opacity .2s ease-in;
opacity: 0;
z-index: 1500;
background-color: rgb(0,0,0);
opacity: 0.5;
pointer-events: auto;
}
</style>
在 components/vue-component.js 中进行 install
vue-component.js:
import VNavbar from './navbar/navbar.vue'
import VActionsheet from './actionsheet/actionsheet.vue'
export default {
install(Vue) {
Vue.component('VNavbar', VNavbar),
Vue.component('VActionsheet', VActionsheet)
}
}
4. 在组件中使用 actionsheet 全局插件
在组件中使用:
order_details_tabs.vue:
<button @click="toggleActionSheet">点击</button>
<VActionsheet :open="openActionsheet" v-on:show="func($event)"
:tradesBanksData="tradesBanksObj"></VActionsheet>
export default {
data(){
return {
openActionsheet: false
},
computed: {
//得到Vuex中的公共状态
...mapState(['tradesCurrentObj', 'tradesBanksObj']),
},
methods: {
//调用actions中的方法
...mapActions([
types.DO_GET_TRADES_CURRENT,
types.DO_GET_TRADES_BANKS
]),
//该方法为按钮的点击事件, 把是否显示操作表的变量取反
toggleActionSheet(){
this.openActionsheet = !this.openActionsheet
},
//该方法为actionsheet组件通过 this.$emit 发射过来事件,
//用于控制操作表显隐
func(e) {
this.openActionsheet = !this.openActionsheet;
console.log(e);
}
}
}
}