Vue整合
依赖环境
- nodejs 版本 >=
18
- 安装
element plus
npm install element-plus
- 安装
mqtt
npm install mqtt
初始化Vue项目
- 使用
vite
创建项目
- 执行命令
npm create vite@latest
- 输入项目名称
vue-mqtt-demo
MQTT连接
连接组件代码
components/MqttDemo.vue
<script setup>
import { ref } from "vue";
import mqtt from "mqtt";
// 消息质量取值数组
const qosList = [0, 1, 2];
/* -------建立和关闭连接-------*/
// 定义链接信息对象
const connectionInfo = ref({
protocol: 'ws',
host: "192.168.40.128",
port: 8083,
clientId: "mqtt_vue_" + Math.random().toString(16).substring(2, 8),
username: "admin",
password: "admin123456",
clean: true,
connectTimeout: 10 * 1000, // 单位:ms
reconnectPeriod: 4000, // 单位:ms
})
// 创建链接对象
const client = ref({})
// 链接初始化相关数据
const clientInitData = ref({
connnected: false
})
// 建立连接事件处理函数
const createConnection = () => {
const { protocol, host, port , ...options } = connectionInfo.value;
const connectUrl = `${protocol}://${host}:${port}/mqtt`;
console.log(connectUrl)
// 建立连接
client.value = mqtt.connect(connectUrl , options);
clientInitData.value.connnected = true ;
console.info("create connection successful...")
}
// 关闭连接
const closeConnection = () => {
// 如果设置为true:立即关闭套接字,不发送MQTT DISCONNECT包。
// 如果设置为false(默认值):先发送MQTT DISCONNECT包给代理,然后关闭套接字
client.value.end(false , () => {
clientInitData.value.connnected = false;
console.info("close connection successful...")
})
}
</script>
<template>
<div class="mqtt-demo">
<el-card>
<h1>配置信息</h1>
<el-form label-position="top">
<el-row :gutter="20">
<el-col :span="8">
<el-form-item prop="protocol" label="选择协议">
<el-select v-model="connectionInfo.protocol">
<el-option label="ws://" value="ws"></el-option>
<el-option label="wss://" value="wss"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item prop="host" label="主机地址">
<el-input v-model="connectionInfo.host"></el-input>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item prop="port" label="端口号">
<el-input type="number" placeholder="8083/8084" v-model="connectionInfo.port"></el-input>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item prop="clientId" label="客户端ID">
<el-input v-model="connectionInfo.clientId"> </el-input>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item prop="username" label="用户名">
<el-input v-model="connectionInfo.username"></el-input>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item prop="password" label="密码">
<el-input v-model="connectionInfo.password"></el-input>
</el-form-item>
</el-col>
<el-col :span="24">
<el-button type="primary" @click="createConnection" v-bind:disabled="clientInitData.connnected">建立连接</el-button>
<el-button type="danger" @click="closeConnection" v-bind:disabled="!clientInitData.connnected">断开连接</el-button>
</el-col>
</el-row>
</el-form>
</el-card>
</div>
</template>
<style>
.mqtt-demo {
max-width: 1200px;
margin: 32px auto 0 auto;
}
h1 {
font-size: 16px;
margin-top: 0;
}
.el-card {
margin-bottom: 32px;
}
.el-card__body {
padding: 24px;
}
.el-select {
width: 100%;
}
.text-right {
text-align: right;
}
.sub-btn {
margin-top: 30px;
}
</style>
首页引入连接组件
App.vue
<template>
<MqttDemo />
</template>
<script setup>
import MqttDemo from "./components/MqttDemo.vue";
</script>
<style></style>
运行项目
npm run dev
访问页面
http://localhost:5173/
建立连接
断开连接
MQTT订阅
订阅相关代码
components/MqttDemo.vue
- JS 代码
// 消息质量取值数组
const qosList = [0, 1, 2];
/* -----订阅和取消订阅------ */
const receivedMessages = ref(null);
const subscriptionInfo = ref({
// 订阅参数数据模型
topic: "",
qos: 0,
});
const subscriptionInitData = ref({
// 订阅初始化数据
subscription: false,
});
// 订阅主题的事件处理函数
const subscriptionTopicHandler = () => {
const { topic, qos } = subscriptionInfo.value;
console.info(qos);
client.value.subscribe(topic, { qos }, (error, res) => {
if (error) {
console.info("subscribe topic error:", error);
return;
}
subscriptionInitData.value.subscription = true;
console.info("subscribe topic successful.... ");
// 订阅成功以后,监听发送消息事件
client.value.on("message", (topic, message) => {
console.info("topic -----> " + topic + ", message -----> " + message);
receivedMessages.value =
"topic -----> " + topic + ", message -----> " + message;
});
});
};
// 取消订阅的事件处理函数
const unSubscriptionTopicHandler = () => {
const { topic, qos } = subscriptionInfo.value;
client.value.unsubscribe(topic, { qos }, (error, res) => {
if (error) {
console.info("unSubscriptionTopic Error:", error);
return;
}
subscriptionInitData.value.subscription = false;
console.info("unSubscriptionTopic successful.... ");
});
};
- HTML 页面
<el-card>
<h1>订阅主题</h1>
<el-form label-position="top">
<el-row :gutter="20">
<el-col :span="8">
<el-form-item prop="topic" label="Topic">
<el-input v-model="subscriptionInfo.topic"></el-input>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item prop="qos" label="QoS">
<el-select v-model="subscriptionInfo.qos">
<el-option
v-for="qos in qosList"
:key="qos"
:label="qos"
:value="qos"
></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="8">
<el-button type="primary" class="sub-btn" @click="subscriptionTopicHandler"
v-bind:disabled="subscriptionInitData.subscription">订阅主题</el-button>
<el-button type="primary" class="sub-btn" @click="unSubscriptionTopicHandler"
v-bind:disabled="!subscriptionInitData.subscription">取消订阅</el-button>
</el-col>
</el-row>
</el-form>
</el-card>
<el-card>
<h1>接收到的消息</h1>
<el-col :span="24">
<el-input type="textarea" :rows="3" readonly v-model="receivedMessages"></el-input>
</el-col>
</el-card>
运行访问
订阅主题
取消订阅
MQTT 发布
发布相关代码
- JS 代码
/* ----- 发布消息 ----- */
// 定义发布消息对象
const publishInfo = ref({
topic: '' ,
qos: 0,
payLoad: ''
})
// 发布消息的事件处理函数
const publishMsg = () => {
const {topic , payLoad , qos } = publishInfo.value ;
client.value.publish(topic , payLoad , { qos } , (error , res) => {
if(error) {
console.info("publish msg info error...." , error)
return ;
}
console.info("publish msg info successful....")
}) ;
}
- HTML 代码
<el-card>
<h1>发布消息</h1>
<el-form label-position="top">
<el-row :gutter="20">
<el-col :span="8">
<el-form-item prop="topic" label="Topic">
<el-input v-model="publishInfo.topic"></el-input>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item prop="payload" label="Payload">
<el-input v-model="publishInfo.payLoad"></el-input>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item prop="qos" label="QoS">
<el-select v-model="publishInfo.qos">
<el-option
v-for="qos in qosList"
:key="qos"
:label="qos"
:value="qos"
></el-option>
</el-select>
</el-form-item>
</el-col>
</el-row>
</el-form>
<el-col :span="24" class="text-right">
<el-button type="primary" @click="publishMsg">发布消息</el-button>
</el-col>
</el-card>
运行访问
订阅主题 test
发送接收消息
点击发送后,接收消息框立马收到发布的消息