介绍
可以左右滑动来展示操作按钮。
引入
js
import SwipeAction from 'sard-uniapp/components/swipe-action/swipe-action.vue'代码演示
基础使用
使用 left、right 插槽向左右两边添加操作按钮。
插槽接收 hide 方法来隐藏操作按钮。
vue
<template>
<sar-list card>
<sar-list-item style="padding: 1px 0 0 0">
<sar-swipe-action>
<sar-list-item title="右边插槽" value="内容" />
<template #right="{ hide }">
<sar-button
theme="danger"
square
inline
style="height: 100%"
@click="onClick('删除', hide)"
>
删除
</sar-button>
<sar-button
theme="primary"
square
inline
style="height: 100%"
@click="onClick('取消', hide)"
>
取消
</sar-button>
</template>
</sar-swipe-action>
</sar-list-item>
<sar-list-item style="padding: 1px 0 0">
<sar-swipe-action>
<sar-list-item title="左边插槽" value="内容" />
<template #left="{ hide }">
<sar-button
theme="danger"
square
inline
style="height: 100%"
@click="onClick('点赞', hide)"
>
点赞
</sar-button>
<sar-button
theme="primary"
square
inline
style="height: 100%"
@click="onClick('分享', hide)"
>
分享
</sar-button>
<sar-button
theme="warning"
square
inline
style="height: 100%"
@click="onClick('收藏', hide)"
>
收藏
</sar-button>
</template>
</sar-swipe-action>
</sar-list-item>
<sar-list-item style="padding: 1px 0 0">
<sar-swipe-action>
<sar-list-item title="两边插槽" value="内容" />
<template #left="{ hide }">
<sar-button
theme="danger"
square
inline
style="height: 100%"
@click="onClick('点赞', hide)"
>
点赞
</sar-button>
<sar-button
theme="primary"
square
inline
style="height: 100%"
@click="onClick('分享', hide)"
>
分享
</sar-button>
<sar-button
theme="warning"
square
inline
style="height: 100%"
@click="onClick('收藏', hide)"
>
收藏
</sar-button>
</template>
<template #right="{ hide }">
<sar-button
theme="danger"
square
inline
style="height: 100%"
@click="onClick('删除', hide)"
>
删除
</sar-button>
<sar-button
theme="primary"
square
inline
style="height: 100%"
@click="onClick('取消', hide)"
>
取消
</sar-button>
</template>
</sar-swipe-action>
</sar-list-item>
</sar-list>
</template>
<script setup lang="ts">
import { toast } from 'sard-uniapp'
const onClick = (content: string, hide: () => void) => {
toast(`点击了${content}`)
hide()
}
</script>vue
<template>
<sar-list card>
<sar-list-item style="padding: 1px 0 0 0">
<sar-swipe-action>
<sar-list-item title="右边插槽" value="内容" />
<template #right="{ hide }">
<sar-button
theme="danger"
square
inline
style="height: 100%"
@click="onClick('删除', hide)"
>
删除
</sar-button>
<sar-button
theme="primary"
square
inline
style="height: 100%"
@click="onClick('取消', hide)"
>
取消
</sar-button>
</template>
</sar-swipe-action>
</sar-list-item>
<sar-list-item style="padding: 1px 0 0">
<sar-swipe-action>
<sar-list-item title="左边插槽" value="内容" />
<template #left="{ hide }">
<sar-button
theme="danger"
square
inline
style="height: 100%"
@click="onClick('点赞', hide)"
>
点赞
</sar-button>
<sar-button
theme="primary"
square
inline
style="height: 100%"
@click="onClick('分享', hide)"
>
分享
</sar-button>
<sar-button
theme="warning"
square
inline
style="height: 100%"
@click="onClick('收藏', hide)"
>
收藏
</sar-button>
</template>
</sar-swipe-action>
</sar-list-item>
<sar-list-item style="padding: 1px 0 0">
<sar-swipe-action>
<sar-list-item title="两边插槽" value="内容" />
<template #left="{ hide }">
<sar-button
theme="danger"
square
inline
style="height: 100%"
@click="onClick('点赞', hide)"
>
点赞
</sar-button>
<sar-button
theme="primary"
square
inline
style="height: 100%"
@click="onClick('分享', hide)"
>
分享
</sar-button>
<sar-button
theme="warning"
square
inline
style="height: 100%"
@click="onClick('收藏', hide)"
>
收藏
</sar-button>
</template>
<template #right="{ hide }">
<sar-button
theme="danger"
square
inline
style="height: 100%"
@click="onClick('删除', hide)"
>
删除
</sar-button>
<sar-button
theme="primary"
square
inline
style="height: 100%"
@click="onClick('取消', hide)"
>
取消
</sar-button>
</template>
</sar-swipe-action>
</sar-list-item>
</sar-list>
</template>
<script setup lang="js">
import { toast } from "sard-uniapp";
const onClick = (content, hide) => {
toast(`\u70B9\u51FB\u4E86${content}`);
hide();
};
</script>控制显隐
使用 v-model:visible 属性控制显隐。
vue
<template>
<sar-list card>
<sar-list-item>
<sar-segmented v-model="visible" :options="options" />
</sar-list-item>
<sar-list-item style="padding: 1px 0 0 0">
<sar-swipe-action v-model:visible="visible">
<sar-list-item title="两边插槽" value="内容" />
<template #left="{ hide }">
<sar-button
theme="danger"
square
inline
style="height: 100%"
@click="onClick('点赞', hide)"
>
点赞
</sar-button>
<sar-button
theme="primary"
square
inline
style="height: 100%"
@click="onClick('分享', hide)"
>
分享
</sar-button>
<sar-button
theme="warning"
square
inline
style="height: 100%"
@click="onClick('收藏', hide)"
>
收藏
</sar-button>
</template>
<template #right="{ hide }">
<sar-button
theme="danger"
square
inline
style="height: 100%"
@click="onClick('删除', hide)"
>
删除
</sar-button>
<sar-button
theme="primary"
square
inline
style="height: 100%"
@click="onClick('取消', hide)"
>
取消
</sar-button>
</template>
</sar-swipe-action>
</sar-list-item>
</sar-list>
</template>
<script setup lang="ts">
import { type SwipeActionVisible, toast } from 'sard-uniapp'
import { ref } from 'vue'
const visible = ref<SwipeActionVisible>(false)
const options = [
{ label: 'left', value: 'left' },
{ label: 'false', value: false },
{ label: 'right', value: 'right' },
]
const onClick = (content: string, hide: () => void) => {
toast(`点击了${content}`)
hide()
}
</script>vue
<template>
<sar-list card>
<sar-list-item>
<sar-segmented v-model="visible" :options="options" />
</sar-list-item>
<sar-list-item style="padding: 1px 0 0 0">
<sar-swipe-action v-model:visible="visible">
<sar-list-item title="两边插槽" value="内容" />
<template #left="{ hide }">
<sar-button
theme="danger"
square
inline
style="height: 100%"
@click="onClick('点赞', hide)"
>
点赞
</sar-button>
<sar-button
theme="primary"
square
inline
style="height: 100%"
@click="onClick('分享', hide)"
>
分享
</sar-button>
<sar-button
theme="warning"
square
inline
style="height: 100%"
@click="onClick('收藏', hide)"
>
收藏
</sar-button>
</template>
<template #right="{ hide }">
<sar-button
theme="danger"
square
inline
style="height: 100%"
@click="onClick('删除', hide)"
>
删除
</sar-button>
<sar-button
theme="primary"
square
inline
style="height: 100%"
@click="onClick('取消', hide)"
>
取消
</sar-button>
</template>
</sar-swipe-action>
</sar-list-item>
</sar-list>
</template>
<script setup lang="js">
import { toast } from "sard-uniapp";
import { ref } from "vue";
const visible = ref(false);
const options = [
{ label: "left", value: "left" },
{ label: "false", value: false },
{ label: "right", value: "right" }
];
const onClick = (content, hide) => {
toast(`\u70B9\u51FB\u4E86${content}`);
hide();
};
</script>禁止滑动
使用 disabled 属性来禁用滑动,同时也会禁用点击内容区域隐藏。
vue
<template>
<sar-list card>
<sar-list-item>
<sar-segmented v-model="visible" :options="options" />
</sar-list-item>
<sar-list-item style="padding: 1px 0 0 0">
<sar-swipe-action v-model:visible="visible">
<sar-list-item title="两边插槽" value="内容" />
<template #left="{ hide }">
<sar-button
theme="danger"
square
inline
style="height: 100%"
@click="onClick('点赞', hide)"
>
点赞
</sar-button>
<sar-button
theme="primary"
square
inline
style="height: 100%"
@click="onClick('分享', hide)"
>
分享
</sar-button>
<sar-button
theme="warning"
square
inline
style="height: 100%"
@click="onClick('收藏', hide)"
>
收藏
</sar-button>
</template>
<template #right="{ hide }">
<sar-button
theme="danger"
square
inline
style="height: 100%"
@click="onClick('删除', hide)"
>
删除
</sar-button>
<sar-button
theme="primary"
square
inline
style="height: 100%"
@click="onClick('取消', hide)"
>
取消
</sar-button>
</template>
</sar-swipe-action>
</sar-list-item>
</sar-list>
</template>
<script setup lang="ts">
import { type SwipeActionVisible, toast } from 'sard-uniapp'
import { ref } from 'vue'
const visible = ref<SwipeActionVisible>(false)
const options = [
{ label: 'left', value: 'left' },
{ label: 'false', value: false },
{ label: 'right', value: 'right' },
]
const onClick = (content: string, hide: () => void) => {
toast(`点击了${content}`)
hide()
}
</script>vue
<template>
<sar-list card>
<sar-list-item>
<sar-segmented v-model="visible" :options="options" />
</sar-list-item>
<sar-list-item style="padding: 1px 0 0 0">
<sar-swipe-action v-model:visible="visible">
<sar-list-item title="两边插槽" value="内容" />
<template #left="{ hide }">
<sar-button
theme="danger"
square
inline
style="height: 100%"
@click="onClick('点赞', hide)"
>
点赞
</sar-button>
<sar-button
theme="primary"
square
inline
style="height: 100%"
@click="onClick('分享', hide)"
>
分享
</sar-button>
<sar-button
theme="warning"
square
inline
style="height: 100%"
@click="onClick('收藏', hide)"
>
收藏
</sar-button>
</template>
<template #right="{ hide }">
<sar-button
theme="danger"
square
inline
style="height: 100%"
@click="onClick('删除', hide)"
>
删除
</sar-button>
<sar-button
theme="primary"
square
inline
style="height: 100%"
@click="onClick('取消', hide)"
>
取消
</sar-button>
</template>
</sar-swipe-action>
</sar-list-item>
</sar-list>
</template>
<script setup lang="js">
import { toast } from "sard-uniapp";
import { ref } from "vue";
const visible = ref(false);
const options = [
{ label: "left", value: "left" },
{ label: "false", value: false },
{ label: "right", value: "right" }
];
const onClick = (content, hide) => {
toast(`\u70B9\u51FB\u4E86${content}`);
hide();
};
</script>异步关闭
插槽按钮可任意定制;利用好 hide 方法和 disabled 属性,可实现复杂的效果。
vue
<template>
<sar-list card>
<sar-list-item style="padding: 0">
<sar-swipe-action :disabled="loading">
<sar-list-item title="右边插槽" value="内容" />
<template #right="{ hide }">
<sar-button
theme="danger"
square
inline
:loading="loading"
style="height: 100%"
@click="onDelete(hide)"
>
删除
</sar-button>
<sar-button
theme="primary"
square
inline
style="height: 100%"
@click="hide"
>
取消
</sar-button>
</template>
</sar-swipe-action>
</sar-list-item>
</sar-list>
</template>
<script setup lang="ts">
import { dialog } from 'sard-uniapp'
import { ref } from 'vue'
const asyncFetch = () => {
return new Promise((resolve) => {
setTimeout(resolve, 1000)
})
}
const loading = ref(false)
const onDelete = (hide: () => void) => {
dialog.confirm('确定删除?', {
onConfirm() {
loading.value = true
asyncFetch()
.then(() => {
hide()
})
.finally(() => {
loading.value = false
})
},
})
}
</script>vue
<template>
<sar-list card>
<sar-list-item style="padding: 0">
<sar-swipe-action :disabled="loading">
<sar-list-item title="右边插槽" value="内容" />
<template #right="{ hide }">
<sar-button
theme="danger"
square
inline
:loading="loading"
style="height: 100%"
@click="onDelete(hide)"
>
删除
</sar-button>
<sar-button
theme="primary"
square
inline
style="height: 100%"
@click="hide"
>
取消
</sar-button>
</template>
</sar-swipe-action>
</sar-list-item>
</sar-list>
</template>
<script setup lang="js">
import { dialog } from "sard-uniapp";
import { ref } from "vue";
const asyncFetch = () => {
return new Promise((resolve) => {
setTimeout(resolve, 1e3);
});
};
const loading = ref(false);
const onDelete = (hide) => {
dialog.confirm("\u786E\u5B9A\u5220\u9664\uFF1F", {
onConfirm() {
loading.value = true;
asyncFetch().then(() => {
hide();
}).finally(() => {
loading.value = false;
});
}
});
};
</script>结合表单使用
下面演示了滑动操作组件如何与表单组件一起使用。
vue
<template>
<sar-form ref="formRef" :model="dynamicValidateForm" card>
<sar-form-item
v-for="(user, index) in dynamicValidateForm.users"
:key="user.id"
style="padding: 1px 0 0"
>
<sar-swipe-action>
<sar-form-item>
<sar-space align="center">
<sar-form-item
:name="['users', index, 'first']"
:rules="{
required: true,
message: 'Missing first name',
}"
inlaid
>
<sar-input inlaid v-model="user.first" placeholder="First Name" />
</sar-form-item>
<sar-form-item
:name="['users', index, 'last']"
:rules="{
required: true,
message: 'Missing last name',
}"
inlaid
>
<sar-input inlaid v-model="user.last" placeholder="Last Name" />
</sar-form-item>
</sar-space>
</sar-form-item>
<template #right>
<sar-button
theme="danger"
square
inline
style="height: 100%"
@click="removeUser(user)"
>
删除
</sar-button>
</template>
</sar-swipe-action>
</sar-form-item>
<sar-form-item>
<sar-button type="outline" icon="plus" @click="addUser()">
Add user
</sar-button>
</sar-form-item>
<sar-form-item>
<sar-button @click="onSubmit">Submit</sar-button>
</sar-form-item>
</sar-form>
</template>
<script setup lang="ts">
import { toRaw, reactive, ref } from 'vue'
import { toast, type FormExpose } from 'sard-uniapp'
interface User {
first: string
last: string
id: number
}
const formRef = ref<FormExpose>()
const dynamicValidateForm = reactive<{ users: User[] }>({
users: [
{
first: '',
last: '',
id: 1,
},
],
})
const removeUser = (item: User) => {
const index = dynamicValidateForm.users.indexOf(item)
if (index !== -1) {
dynamicValidateForm.users.splice(index, 1)
}
}
const addUser = () => {
dynamicValidateForm.users.push({
first: '',
last: '',
id: Date.now(),
})
}
const onSubmit = () => {
formRef.value
?.validate()
.then(() => {
toast('Success')
console.log('Received values of form:', toRaw(dynamicValidateForm))
})
.catch(() => {
console.log('fail')
})
}
</script>vue
<template>
<sar-form ref="formRef" :model="dynamicValidateForm" card>
<sar-form-item
v-for="(user, index) in dynamicValidateForm.users"
:key="user.id"
style="padding: 1px 0 0"
>
<sar-swipe-action>
<sar-form-item>
<sar-space align="center">
<sar-form-item
:name="['users', index, 'first']"
:rules="{
required: true,
message: 'Missing first name',
}"
inlaid
>
<sar-input inlaid v-model="user.first" placeholder="First Name" />
</sar-form-item>
<sar-form-item
:name="['users', index, 'last']"
:rules="{
required: true,
message: 'Missing last name',
}"
inlaid
>
<sar-input inlaid v-model="user.last" placeholder="Last Name" />
</sar-form-item>
</sar-space>
</sar-form-item>
<template #right>
<sar-button
theme="danger"
square
inline
style="height: 100%"
@click="removeUser(user)"
>
删除
</sar-button>
</template>
</sar-swipe-action>
</sar-form-item>
<sar-form-item>
<sar-button type="outline" icon="plus" @click="addUser()">
Add user
</sar-button>
</sar-form-item>
<sar-form-item>
<sar-button @click="onSubmit">Submit</sar-button>
</sar-form-item>
</sar-form>
</template>
<script setup lang="js">
import { toRaw, reactive, ref } from "vue";
import { toast } from "sard-uniapp";
const formRef = ref();
const dynamicValidateForm = reactive({
users: [
{
first: "",
last: "",
id: 1
}
]
});
const removeUser = (item) => {
const index = dynamicValidateForm.users.indexOf(item);
if (index !== -1) {
dynamicValidateForm.users.splice(index, 1);
}
};
const addUser = () => {
dynamicValidateForm.users.push({
first: "",
last: "",
id: Date.now()
});
};
const onSubmit = () => {
formRef.value?.validate().then(() => {
toast("Success");
console.log("Received values of form:", toRaw(dynamicValidateForm));
}).catch(() => {
console.log("fail");
});
};
</script>API
SwipeActionProps
| 属性 | 描述 | 类型 | 默认值 |
|---|---|---|---|
| root-class | 组件根元素类名 | string | - |
| root-style | 组件根元素样式 | StyleValue | - |
| disabled | 是否禁用滑动 | boolean | false |
| visible (v-model) | 控制显隐 | 'left' | 'right' | false | false |
SwipeActionSlots
| 插槽 | 描述 | 属性 |
|---|---|---|
| default | 自定义默认内容 | - |
| left | 自定义左边操作按钮 | { hide: () => void } |
| right | 自定义右边操作按钮 | { hide: () => void } |
SwipeActionEmits
| 事件 | 描述 | 类型 |
|---|---|---|
| update:visible | 操作按钮显隐时触发 | (visible: 'left' | 'right' | false) => void |
SwipeActionExpose
| 属性 | 描述 | 类型 |
|---|---|---|
| hide | 隐藏操作按钮 | () => void |