mirror of
https://github.com/pure-admin/vue-pure-admin.git
synced 2025-12-09 14:40:27 +08:00
Merge branch 'main' into gitee
This commit is contained in:
@@ -1,11 +1,20 @@
|
||||
.pure-segmented {
|
||||
--pure-control-padding-horizontal: 12px;
|
||||
--pure-control-padding-horizontal-sm: 8px;
|
||||
--pure-segmented-track-padding: 2px;
|
||||
--pure-segmented-line-width: 1px;
|
||||
|
||||
--pure-segmented-border-radius-small: 4px;
|
||||
--pure-segmented-border-radius-base: 6px;
|
||||
--pure-segmented-border-radius-large: 8px;
|
||||
|
||||
box-sizing: border-box;
|
||||
display: inline-block;
|
||||
padding: 2px;
|
||||
font-size: 14px;
|
||||
padding: var(--pure-segmented-track-padding);
|
||||
font-size: var(--el-font-size-base);
|
||||
color: rgba(0, 0, 0, 0.65);
|
||||
background-color: rgb(0 0 0 / 4%);
|
||||
border-radius: 2px;
|
||||
border-radius: var(--pure-segmented-border-radius-base);
|
||||
}
|
||||
|
||||
.pure-segmented-block {
|
||||
@@ -23,6 +32,75 @@
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
/* small */
|
||||
.pure-segmented.pure-segmented--small {
|
||||
border-radius: var(--pure-segmented-border-radius-small);
|
||||
}
|
||||
.pure-segmented.pure-segmented--small .pure-segmented-item {
|
||||
border-radius: var(--el-border-radius-small);
|
||||
}
|
||||
.pure-segmented.pure-segmented--small .pure-segmented-item > div {
|
||||
min-height: calc(
|
||||
var(--el-component-size-small) - var(--pure-segmented-track-padding) * 2
|
||||
);
|
||||
line-height: calc(
|
||||
var(--el-component-size-small) - var(--pure-segmented-track-padding) * 2
|
||||
);
|
||||
padding: 0
|
||||
calc(
|
||||
var(--pure-control-padding-horizontal-sm) -
|
||||
var(--pure-segmented-line-width)
|
||||
);
|
||||
}
|
||||
|
||||
/* large */
|
||||
.pure-segmented.pure-segmented--large {
|
||||
border-radius: var(--pure-segmented-border-radius-large);
|
||||
}
|
||||
.pure-segmented.pure-segmented--large .pure-segmented-item {
|
||||
border-radius: calc(
|
||||
var(--el-border-radius-base) + var(--el-border-radius-small)
|
||||
);
|
||||
}
|
||||
.pure-segmented.pure-segmented--large .pure-segmented-item > div {
|
||||
min-height: calc(
|
||||
var(--el-component-size-large) - var(--pure-segmented-track-padding) * 2
|
||||
);
|
||||
line-height: calc(
|
||||
var(--el-component-size-large) - var(--pure-segmented-track-padding) * 2
|
||||
);
|
||||
padding: 0
|
||||
calc(
|
||||
var(--pure-control-padding-horizontal) - var(--pure-segmented-line-width)
|
||||
);
|
||||
font-size: var(--el-font-size-medium);
|
||||
}
|
||||
|
||||
/* default */
|
||||
.pure-segmented-item {
|
||||
position: relative;
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
border-radius: var(--el-border-radius-base);
|
||||
transition: all 0.1s cubic-bezier(0.645, 0.045, 0.355, 1);
|
||||
}
|
||||
.pure-segmented .pure-segmented-item > div {
|
||||
min-height: calc(
|
||||
var(--el-component-size) - var(--pure-segmented-track-padding) * 2
|
||||
);
|
||||
line-height: calc(
|
||||
var(--el-component-size) - var(--pure-segmented-track-padding) * 2
|
||||
);
|
||||
padding: 0
|
||||
calc(
|
||||
var(--pure-control-padding-horizontal) - var(--pure-segmented-line-width)
|
||||
);
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
transition: 0.1s;
|
||||
}
|
||||
|
||||
.pure-segmented-group {
|
||||
position: relative;
|
||||
display: flex;
|
||||
@@ -52,23 +130,6 @@
|
||||
will-change: transform, width;
|
||||
}
|
||||
|
||||
.pure-segmented-item {
|
||||
position: relative;
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
border-radius: 4px;
|
||||
transition: all 0.1s cubic-bezier(0.645, 0.045, 0.355, 1);
|
||||
}
|
||||
|
||||
.pure-segmented-item > div {
|
||||
min-height: 28px;
|
||||
line-height: 28px;
|
||||
padding: 0 11px;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.pure-segmented-item > input {
|
||||
position: absolute;
|
||||
inset-block-start: 0;
|
||||
|
||||
@@ -1,5 +1,14 @@
|
||||
import "./index.css";
|
||||
import type { OptionsType } from "./type";
|
||||
import { useRenderIcon } from "@/components/ReIcon/src/hooks";
|
||||
import {
|
||||
useDark,
|
||||
isNumber,
|
||||
isFunction,
|
||||
useResizeObserver
|
||||
} from "@pureadmin/utils";
|
||||
import {
|
||||
type PropType,
|
||||
h,
|
||||
ref,
|
||||
toRef,
|
||||
@@ -8,14 +17,6 @@ import {
|
||||
defineComponent,
|
||||
getCurrentInstance
|
||||
} from "vue";
|
||||
import type { OptionsType } from "./type";
|
||||
import { useRenderIcon } from "@/components/ReIcon/src/hooks";
|
||||
import {
|
||||
isFunction,
|
||||
isNumber,
|
||||
useDark,
|
||||
useResizeObserver
|
||||
} from "@pureadmin/utils";
|
||||
|
||||
const props = {
|
||||
options: {
|
||||
@@ -32,6 +33,10 @@ const props = {
|
||||
block: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
/** 控件尺寸 */
|
||||
size: {
|
||||
type: String as PropType<"small" | "default" | "large">
|
||||
}
|
||||
};
|
||||
|
||||
@@ -81,13 +86,14 @@ export default defineComponent({
|
||||
function handleInit(index = curIndex.value) {
|
||||
nextTick(() => {
|
||||
const curLabelRef = instance?.proxy?.$refs[`labelRef${index}`] as ElRef;
|
||||
if (!curLabelRef) return;
|
||||
width.value = curLabelRef.clientWidth;
|
||||
translateX.value = curLabelRef.offsetLeft;
|
||||
initStatus.value = true;
|
||||
});
|
||||
}
|
||||
|
||||
if (props.block) {
|
||||
function handleResizeInit() {
|
||||
useResizeObserver(".pure-segmented", () => {
|
||||
nextTick(() => {
|
||||
handleInit(curIndex.value);
|
||||
@@ -95,6 +101,8 @@ export default defineComponent({
|
||||
});
|
||||
}
|
||||
|
||||
props.block && handleResizeInit();
|
||||
|
||||
watch(
|
||||
() => curIndex.value,
|
||||
index => {
|
||||
@@ -103,11 +111,12 @@ export default defineComponent({
|
||||
});
|
||||
},
|
||||
{
|
||||
deep: true,
|
||||
immediate: true
|
||||
}
|
||||
);
|
||||
|
||||
watch(() => props.size, handleResizeInit);
|
||||
|
||||
const rendLabel = () => {
|
||||
return props.options.map((option, index) => {
|
||||
return (
|
||||
@@ -167,7 +176,12 @@ export default defineComponent({
|
||||
|
||||
return () => (
|
||||
<div
|
||||
class={["pure-segmented", props.block ? "pure-segmented-block" : ""]}
|
||||
class={{
|
||||
"pure-segmented": true,
|
||||
"pure-segmented-block": props.block,
|
||||
"pure-segmented--large": props.size === "large",
|
||||
"pure-segmented--small": props.size === "small"
|
||||
}}
|
||||
>
|
||||
<div class="pure-segmented-group">
|
||||
<div
|
||||
|
||||
@@ -10,13 +10,21 @@ export default {
|
||||
rank: able
|
||||
},
|
||||
children: [
|
||||
{
|
||||
path: "/components/mqtt-client",
|
||||
name: "MqttClient",
|
||||
component: () => import("@/views/able/mqtt-client.vue"),
|
||||
meta: {
|
||||
title: $t("menus.hsMqtt"),
|
||||
extraIcon: "IF-pure-iconfont-new svg"
|
||||
}
|
||||
},
|
||||
{
|
||||
path: "/able/verify",
|
||||
name: "Verify",
|
||||
component: () => import("@/views/able/verify.vue"),
|
||||
meta: {
|
||||
title: $t("menus.hsVerify"),
|
||||
extraIcon: "IF-pure-iconfont-new svg"
|
||||
title: $t("menus.hsVerify")
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -56,8 +64,7 @@ export default {
|
||||
name: "Ripple",
|
||||
component: () => import("@/views/able/ripple.vue"),
|
||||
meta: {
|
||||
title: $t("menus.hsRipple"),
|
||||
extraIcon: "IF-pure-iconfont-new svg"
|
||||
title: $t("menus.hsRipple")
|
||||
}
|
||||
},
|
||||
{
|
||||
|
||||
392
src/views/able/mqtt-client.vue
Normal file
392
src/views/able/mqtt-client.vue
Normal file
@@ -0,0 +1,392 @@
|
||||
<script setup lang="ts">
|
||||
// vue 3 + vite use MQTT.js refer to https://github.com/mqttjs/MQTT.js/issues/1269
|
||||
import mqtt from "mqtt";
|
||||
import { reactive, ref, onUnmounted } from "vue";
|
||||
|
||||
const protocol = location.protocol === "https:" ? "wss" : "ws";
|
||||
const port = protocol === "wss" ? 8084 : 8083;
|
||||
|
||||
// https://github.com/mqttjs/MQTT.js#qos
|
||||
const qosList = [0, 1, 2];
|
||||
|
||||
const connection = reactive({
|
||||
protocol,
|
||||
host: "broker.emqx.io",
|
||||
port,
|
||||
clientId: "emqx_vue3_" + Math.random().toString(16).substring(2, 8),
|
||||
username: "emqx_test",
|
||||
password: "emqx_test",
|
||||
clean: true,
|
||||
connectTimeout: 30 * 1000, // ms
|
||||
reconnectPeriod: 4000 // ms
|
||||
// for more options and details, please refer to https://github.com/mqttjs/MQTT.js#mqttclientstreambuilder-options
|
||||
});
|
||||
|
||||
// 订阅 topic/mqttx 主题
|
||||
const subscription = ref({
|
||||
topic: "topic/mqttx",
|
||||
qos: 0 as any
|
||||
});
|
||||
|
||||
// 发布 topic/browser 主题
|
||||
const publish = ref({
|
||||
topic: "topic/browser",
|
||||
qos: 0 as any,
|
||||
payload: '{ "msg": "Hello, I am browser." }'
|
||||
});
|
||||
|
||||
let client = ref({
|
||||
connected: false
|
||||
} as mqtt.MqttClient);
|
||||
|
||||
const receivedMessages = ref("");
|
||||
const subscribedSuccess = ref(false);
|
||||
const btnLoadingType = ref("");
|
||||
const retryTimes = ref(0);
|
||||
|
||||
const initData = () => {
|
||||
client.value = {
|
||||
connected: false
|
||||
} as mqtt.MqttClient;
|
||||
retryTimes.value = 0;
|
||||
btnLoadingType.value = "";
|
||||
subscribedSuccess.value = false;
|
||||
};
|
||||
|
||||
const handleOnReConnect = () => {
|
||||
retryTimes.value += 1;
|
||||
if (retryTimes.value > 5) {
|
||||
try {
|
||||
client.value.end();
|
||||
initData();
|
||||
console.log("connection maxReconnectTimes limit, stop retry");
|
||||
} catch (error) {
|
||||
console.log("handleOnReConnect catch error:", error);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const createConnection = () => {
|
||||
try {
|
||||
btnLoadingType.value = "connect";
|
||||
const { protocol, host, port, ...options } = connection;
|
||||
const connectUrl = `${protocol}://${host}:${port}/mqtt`;
|
||||
// 连接MQTT 服务器
|
||||
client.value = mqtt.connect(connectUrl, options);
|
||||
|
||||
if (client.value.on) {
|
||||
// https://github.com/mqttjs/MQTT.js#event-connect
|
||||
client.value.on("connect", () => {
|
||||
btnLoadingType.value = "";
|
||||
console.log("connection successful");
|
||||
});
|
||||
|
||||
// https://github.com/mqttjs/MQTT.js#event-reconnect
|
||||
client.value.on("reconnect", handleOnReConnect);
|
||||
|
||||
// https://github.com/mqttjs/MQTT.js#event-error
|
||||
client.value.on("error", error => {
|
||||
console.log("connection error:", error);
|
||||
});
|
||||
|
||||
// https://github.com/mqttjs/MQTT.js#event-message
|
||||
client.value.on("message", (topic: string, message) => {
|
||||
receivedMessages.value = receivedMessages.value.concat(
|
||||
message.toString()
|
||||
);
|
||||
console.log(`received message: ${message} from topic: ${topic}`);
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
btnLoadingType.value = "";
|
||||
console.log("mqtt.connect error:", error);
|
||||
}
|
||||
};
|
||||
|
||||
// subscribe topic
|
||||
// https://github.com/mqttjs/MQTT.js#mqttclientsubscribetopictopic-arraytopic-object-options-callback
|
||||
const doSubscribe = () => {
|
||||
btnLoadingType.value = "subscribe";
|
||||
const { topic, qos } = subscription.value;
|
||||
client.value.subscribe(
|
||||
topic,
|
||||
{ qos },
|
||||
(error: Error, granted: mqtt.ISubscriptionGrant[]) => {
|
||||
btnLoadingType.value = "";
|
||||
if (error) {
|
||||
console.log("subscribe error:", error);
|
||||
return;
|
||||
}
|
||||
subscribedSuccess.value = true;
|
||||
console.log("subscribe successfully:", granted);
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
// unsubscribe topic
|
||||
// https://github.com/mqttjs/MQTT.js#mqttclientunsubscribetopictopic-array-options-callback
|
||||
const doUnSubscribe = () => {
|
||||
btnLoadingType.value = "unsubscribe";
|
||||
const { topic, qos } = subscription.value;
|
||||
client.value.unsubscribe(topic, { qos }, error => {
|
||||
btnLoadingType.value = "";
|
||||
subscribedSuccess.value = false;
|
||||
if (error) {
|
||||
console.log("unsubscribe error:", error);
|
||||
return;
|
||||
}
|
||||
console.log(`unsubscribed topic: ${topic}`);
|
||||
});
|
||||
};
|
||||
|
||||
// publish message
|
||||
// https://github.com/mqttjs/MQTT.js#mqttclientpublishtopic-message-options-callback
|
||||
const doPublish = () => {
|
||||
btnLoadingType.value = "publish";
|
||||
const { topic, qos, payload } = publish.value;
|
||||
client.value.publish(topic, payload, { qos }, error => {
|
||||
btnLoadingType.value = "";
|
||||
if (error) {
|
||||
console.log("publish error:", error);
|
||||
return;
|
||||
}
|
||||
console.log(`published message: ${payload}`);
|
||||
});
|
||||
};
|
||||
|
||||
// disconnect
|
||||
// https://github.com/mqttjs/MQTT.js#mqttclientendforce-options-callback
|
||||
const destroyConnection = () => {
|
||||
if (client.value.connected) {
|
||||
btnLoadingType.value = "disconnect";
|
||||
try {
|
||||
client.value.end(false, () => {
|
||||
initData();
|
||||
console.log("disconnected successfully");
|
||||
});
|
||||
} catch (error) {
|
||||
btnLoadingType.value = "";
|
||||
console.log("disconnect error:", error);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const handleProtocolChange = (value: string) => {
|
||||
connection.port = value === "wss" ? 8084 : 8083;
|
||||
};
|
||||
|
||||
onUnmounted(() => {
|
||||
try {
|
||||
if (client.value.end) {
|
||||
client.value.end();
|
||||
console.log("disconnected successfully");
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<el-card shadow="never" :body-style="{ padding: '20px' }">
|
||||
<template #header>
|
||||
基于
|
||||
<el-link
|
||||
type="primary"
|
||||
:underline="false"
|
||||
href="https://github.com/mqttjs/MQTT.js"
|
||||
target="_blank"
|
||||
>
|
||||
MQTT.js
|
||||
</el-link>
|
||||
和 免费的公共MQTT代理
|
||||
<el-link
|
||||
type="primary"
|
||||
:underline="false"
|
||||
href="broker.emqx.io"
|
||||
target="_blank"
|
||||
>
|
||||
EMQX
|
||||
</el-link>
|
||||
实现的一套 MQTT 客户端。
|
||||
</template>
|
||||
<template #default>
|
||||
<el-card shadow="never">
|
||||
<h1>设置</h1>
|
||||
<el-form label-position="top" :model="connection">
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="8">
|
||||
<el-form-item prop="protocol" label="协议">
|
||||
<el-select
|
||||
v-model="connection.protocol"
|
||||
@change="handleProtocolChange"
|
||||
>
|
||||
<el-option label="ws://" value="ws" />
|
||||
<el-option label="wss://" value="wss" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item prop="host" label="主机">
|
||||
<el-input v-model="connection.host" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item prop="port" label="端口">
|
||||
<el-input
|
||||
v-model.number="connection.port"
|
||||
type="number"
|
||||
placeholder="8083/8084"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item prop="clientId" label="客户端ID">
|
||||
<el-input v-model="connection.clientId" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item prop="username" label="用户名">
|
||||
<el-input v-model="connection.username" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item prop="password" label="密码">
|
||||
<el-input v-model="connection.password" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="24">
|
||||
<el-button
|
||||
type="primary"
|
||||
:disabled="client.connected"
|
||||
:loading="btnLoadingType === 'connect'"
|
||||
@click="createConnection"
|
||||
>
|
||||
{{ client.connected ? "已连接" : "连接" }}
|
||||
</el-button>
|
||||
|
||||
<el-button
|
||||
v-if="client.connected"
|
||||
type="danger"
|
||||
:loading="btnLoadingType === 'disconnect'"
|
||||
@click="destroyConnection"
|
||||
>
|
||||
断开连接
|
||||
</el-button>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
</el-card>
|
||||
<el-card shadow="never" class="mt-4">
|
||||
<h1>订阅</h1>
|
||||
<el-form label-position="top" :model="subscription">
|
||||
<el-row :gutter="20" :align="'middle'">
|
||||
<el-col :span="8">
|
||||
<el-form-item prop="topic" label="主题">
|
||||
<el-input
|
||||
v-model="subscription.topic"
|
||||
:disabled="subscribedSuccess"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item prop="qos" label="通信质量">
|
||||
<el-select
|
||||
v-model="subscription.qos"
|
||||
:disabled="subscribedSuccess"
|
||||
>
|
||||
<el-option
|
||||
v-for="qos in qosList"
|
||||
:key="qos"
|
||||
:label="qos"
|
||||
:value="qos"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row>
|
||||
<el-col>
|
||||
<el-button
|
||||
type="primary"
|
||||
class="sub-btn"
|
||||
:loading="btnLoadingType === 'subscribe'"
|
||||
:disabled="!client.connected || subscribedSuccess"
|
||||
@click="doSubscribe"
|
||||
>
|
||||
{{ subscribedSuccess ? "已订阅" : "订阅" }}
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="subscribedSuccess"
|
||||
type="primary"
|
||||
class="sub-btn"
|
||||
:loading="btnLoadingType === 'unsubscribe'"
|
||||
:disabled="!client.connected"
|
||||
@click="doUnSubscribe"
|
||||
>
|
||||
取消订阅
|
||||
</el-button>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
</el-card>
|
||||
<el-card shadow="never" class="mt-4">
|
||||
<h1>发布</h1>
|
||||
<el-form label-position="top" :model="publish">
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="8">
|
||||
<el-form-item prop="topic">
|
||||
<template #label>
|
||||
<span>主题</span>
|
||||
<el-text type="info" size="small">
|
||||
可将订阅主题设置为topic/browser,测试MQTT的自发自收。
|
||||
</el-text>
|
||||
</template>
|
||||
<el-input v-model="publish.topic" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item prop="payload" label="有效载荷">
|
||||
<el-input v-model="publish.payload" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item prop="qos" label="通信质量">
|
||||
<el-select v-model="publish.qos">
|
||||
<el-option
|
||||
v-for="qos in qosList"
|
||||
:key="qos"
|
||||
:label="qos"
|
||||
:value="qos"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
<el-col :span="24">
|
||||
<el-button
|
||||
type="primary"
|
||||
:loading="btnLoadingType === 'publish'"
|
||||
:disabled="!client.connected"
|
||||
@click="doPublish"
|
||||
>
|
||||
发布
|
||||
</el-button>
|
||||
</el-col>
|
||||
</el-card>
|
||||
<el-card shadow="never" class="mt-4">
|
||||
<h1>接收</h1>
|
||||
<el-col :span="24">
|
||||
<el-input
|
||||
v-model="receivedMessages"
|
||||
type="textarea"
|
||||
:rows="3"
|
||||
readonly
|
||||
/>
|
||||
</el-col>
|
||||
</el-card>
|
||||
</template>
|
||||
</el-card>
|
||||
</template>
|
||||
@@ -1,5 +1,5 @@
|
||||
<script setup lang="tsx">
|
||||
import { h, ref } from "vue";
|
||||
import { h, ref, watch } from "vue";
|
||||
import { message } from "@/utils/message";
|
||||
import HomeFilled from "@iconify-icons/ep/home-filled";
|
||||
import { useRenderIcon } from "@/components/ReIcon/src/hooks";
|
||||
@@ -11,6 +11,8 @@ defineOptions({
|
||||
|
||||
/** 基础用法 */
|
||||
const value = ref(4); // 必须为number类型
|
||||
const size = ref("default");
|
||||
const dynamicSize = ref();
|
||||
|
||||
const optionsBasis: Array<OptionsType> = [
|
||||
{
|
||||
@@ -192,13 +194,22 @@ function onChange({ index, option }) {
|
||||
type: "success"
|
||||
});
|
||||
}
|
||||
|
||||
watch(size, val => (dynamicSize.value = size.value));
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<el-card shadow="never">
|
||||
<template #header>
|
||||
<div class="card-header">
|
||||
<span class="font-medium">分段控制器</span>
|
||||
<el-space wrap :size="40">
|
||||
<span style="font-size: 16px; font-weight: 800"> 分段控制器 </span>
|
||||
<el-radio-group v-model="size" size="small">
|
||||
<el-radio value="large">大尺寸</el-radio>
|
||||
<el-radio value="default">默认尺寸</el-radio>
|
||||
<el-radio value="small">小尺寸</el-radio>
|
||||
</el-radio-group>
|
||||
</el-space>
|
||||
</div>
|
||||
</template>
|
||||
<el-scrollbar>
|
||||
@@ -207,28 +218,32 @@ function onChange({ index, option }) {
|
||||
{{ optionsBasis[value].label }}
|
||||
</span>
|
||||
</p>
|
||||
<Segmented v-model="value" :options="optionsBasis" />
|
||||
<Segmented v-model="value" :options="optionsBasis" :size="dynamicSize" />
|
||||
<el-divider />
|
||||
<p class="mb-2">tooltip 提示</p>
|
||||
<Segmented :options="optionsTooltip" />
|
||||
<Segmented :options="optionsTooltip" :size="dynamicSize" />
|
||||
<el-divider />
|
||||
<p class="mb-2">change 事件</p>
|
||||
<Segmented :options="optionsChange" @change="onChange" />
|
||||
<Segmented
|
||||
:options="optionsChange"
|
||||
:size="dynamicSize"
|
||||
@change="onChange"
|
||||
/>
|
||||
<el-divider />
|
||||
<p class="mb-2">禁用</p>
|
||||
<Segmented :options="optionsDisabled" />
|
||||
<Segmented :options="optionsDisabled" :size="dynamicSize" />
|
||||
<el-divider />
|
||||
<p class="mb-2">block 属性(将宽度调整为父元素宽度)</p>
|
||||
<Segmented :options="optionsBlock" block />
|
||||
<Segmented :options="optionsBlock" block :size="dynamicSize" />
|
||||
<el-divider />
|
||||
<p class="mb-2">可设置图标</p>
|
||||
<Segmented :options="optionsIcon" />
|
||||
<Segmented :options="optionsIcon" :size="dynamicSize" />
|
||||
<el-divider />
|
||||
<p class="mb-2">只设置图标</p>
|
||||
<Segmented :options="optionsOnlyIcon" />
|
||||
<Segmented :options="optionsOnlyIcon" :size="dynamicSize" />
|
||||
<el-divider />
|
||||
<p class="mb-2">自定义渲染</p>
|
||||
<Segmented :options="optionsLabel" />
|
||||
<Segmented :options="optionsLabel" :size="dynamicSize" />
|
||||
</el-scrollbar>
|
||||
</el-card>
|
||||
</template>
|
||||
|
||||
Reference in New Issue
Block a user