使用Vue 3与.NET 8.0通过SignalR实现实时通信,并结合JWT身份验证
实时通信是一个非常重要的功能。SignalR是一个强大的库,能够帮助我们轻松实现客户端和服务器之间的实时数据传输。本文将结合你的代码示例,向你展示如何使用Vue 3作为前端框架,ASP.NET Core作为后端框架,通过SignalR实现实时消息通信,并结合JWT(JSON Web Token)进行身份验证。
结合我上篇文章JWT校验,接下来简单描述一下,使用JWT进行SignalR身份验证,业务背景:比如网站登录成功后才能发送实时聊天信息等业务。
目标
- 用户登录后获取JWT令牌。
- 使用JWT令牌建立安全的SignalR连接。
- 实现客户端发送消息到服务器,服务器广播消息到所有客户端。
技术栈
- 前端:Vue 3 + @microsoft/signalr
- 后端:ASP.NET Core 8.0 + SignalR + JWT身份验证
- 数据传输协议:WebSocket(SignalR默认协议)
对Vue.js和ASP.NET Core有一定的了解。
安装了Node.js和Visual Studio或者VS Code等开发环境。
后端Program.cs中添加依赖注入等服务
// 注册身份验证服务。
builder.Services.AddAuthentication(opt =>
{
// DefaultAuthenticateScheme 和 DefaultChallengeScheme:设置默认的身份验证方案为JwtBearer。opt.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;opt.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(opt =>
{var jwtSetting = builder.Configuration.GetSection("JWTSettingOption").Get<JWTSetting>();opt.TokenValidationParameters = new TokenValidationParameters{ValidateIssuer = false,ValidateAudience = false,ValidateLifetime = true,ValidateIssuerSigningKey = true,IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(jwtSetting.SecretKey))};opt.Events = new JwtBearerEvents{// SignalR 当接收到消息时触发。 在SignalR场景下,JWT令牌通常通过查询字符串传递(因为WebSocket协议不支持HTTP头传递令牌)。//检查请求路径是否为/SignalRHub/MyHub,如果是,则从查询字符串中提取access_token并赋值给context.Token。OnMessageReceived = context =>{if (context.Request.Path.StartsWithSegments("/SignalRHub/MyHub")){var accessToken = context.Request.Query["access_token"];if (!string.IsNullOrEmpty(accessToken)){context.Token = accessToken;}}return Task.CompletedTask;}};
});
builder.Services.AddSignalR(); // 注册SignalR服务,net8.0不需下载SignalR包
// CORS的作用:
// CORS(Cross-Origin Resource Sharing)用于解决跨域问题。
// 默认情况下,浏览器会阻止跨域请求。通过配置CORS策略,我们可以允许特定的前端地址访问后端API。
// 配置策略:
// WithOrigins:指定允许的前端地址(例如http://localhost:5173)。
// AllowAnyHeader 和 AllowAnyMethod:允许所有请求头和方法。
// AllowCredentials:允许传递凭据(如cookies或JWT令牌)。
builder.Services.AddCors(options =>
{options.AddPolicy("AddCors", policy =>{policy.WithOrigins("http://localhost:5173") // 指定允许的前端地址 .AllowAnyHeader().AllowAnyMethod().AllowCredentials(); // 允许凭证传递(如 cookies)});
});var app = builder.Build();app.UseCors("AddCors"); // 必须在其他中间件之前调用,以确保跨域请求能够正确处理。
app.UseAuthentication(); // 启用身份验证中间件,检查传入的请求是否包含有效的JWT令牌
app.UseAuthorization(); // 启用授权中间件,确保用户具有访问特定资源的权限。
SignalR 的核心概念
Hub:
Hub 是 SignalR 的核心组件,它充当服务器和客户端之间的通信桥梁。
客户端可以调用 Hub 上的方法,Hub 也可以向客户端发送消息。
客户端-服务器交互:
客户端通过 SignalR JavaScript 库(或其他支持的客户端库)与服务器建立连接。
服务器可以通过 Hub 向所有客户端、特定客户端或分组广播消息。
传输方式:
SignalR 自动选择最佳的传输协议(WebSocket、Server-Sent Events 或长轮询)。
依赖注入:
在 .NET Core 和 .NET 8.0 中,SignalR 与依赖注入系统深度集成,方便扩展和管理。
示例代码
创建一个 MyHub 类,继承自 Hub:
using Microsoft.AspNetCore.SignalR;// 标记该Hub需要身份验证(通过JWT令牌)。
[Authorize]
public class MyHub : Hub
{// 广播消息给所有客户端public async Task SendMessage(string message){await Clients.All.SendAsync("ReceiveMessage", user, message);}// 向调用者发送消息public async Task SendToCaller(string message){await Clients.Caller.SendAsync("ReceiveMessage", "System", message);}// 向特定用户发送消息public async Task SendToUser(string userId, string message){await Clients.User(userId).SendAsync("ReceiveMessage", "Private", message);}
}
vue3 示例代码
// 首先需要准备
npm install @microsoft/signalr
npm install axios
(1) 模板部分 (template)
功能说明:
输入框:用户可以在这里输入消息,按下回车键后会触发sendMessageOnEnter方法。
登录表单:用户输入用户名和密码,点击“登录”按钮后调用login方法。
消息列表:显示从服务器接收到的所有消息。
<div><h1>SignalR 实时消息</h1><div><inputtype="text"v-model="state.userMessage"@keypress="sendMessageOnEnter":disabled="!state.isConnected"placeholder="等待连接..."/></div><div><table><tr><td>登录:</td><td><input type="text" v-model="state.userName"/></td></tr><tr><td>密码:</td><td><input type="password" v-model="state.password"/></td></tr><tr><td><button v-on:click="login">登录</button></td></tr></table></div><ul><li v-for="(msg, index) in state.messages" :key="index">{{ msg }}</li></ul>
</div>
(2) 脚本部分 (script)
数据模型 (reactive)
这里定义了应用的状态管理对象state,用于存储用户输入、连接状态、消息列表等信息。
const state = reactive({userMessage: '', // 用户输入的消息messages: [], // 接收到的消息列表isConnected: false, // 是否已连接到SignalR服务器userName: '', // 用户名password: '', // 密码token: '', // JWT令牌
});
登录逻辑 (login)
功能说明:
检查用户名和密码是否为空。
发送登录请求到后端API。
如果登录成功,保存JWT令牌并调用startSignalRConnection方法启动SignalR连接
const login = async () => {if (!state.userName.trim() || !state.password.trim()) {alert("用户名和密码不能为空!");return;}try {const param = {username: state.userName,password: state.password,};await axios.post('https://localhost:7182/api/JWTTest/Login', param).then((response) => {if (response.data.code === 200) {alert("登录成功");state.token = response.data.token; // 存储JWT令牌startSignalRConnection(); // 开始SignalR连接} else {alert("登录失败");}});} catch (error) {alert("登录失败");console.error("登录失败:", error);}
};
SignalR连接初始化 (startSignalRConnection)
功能说明:
配置SignalR连接选项,包括跳过协商、使用WebSocket协议以及通过accessTokenFactory提供JWT令牌。
定义事件监听器,处理连接状态变化(如重连、断开)。
监听ReceiveMessage事件,接收服务器广播的消息。
const startSignalRConnection = async () => {try {const options = {skipNegotiation: true,transport: signalR.HttpTransportType.WebSockets,accessTokenFactory: () => state.token, // 使用JWT令牌进行身份验证};connection = new signalR.HubConnectionBuilder().withUrl('https://localhost:7182/SignalRHub/MyHub', options).withAutomaticReconnect().build();connection.onreconnecting(() => {console.log("SignalR 正在尝试重新连接...");state.isConnected = false;});connection.onreconnected(() => {console.log("SignalR 重新连接成功");state.isConnected = true;});connection.onclose(() => {console.error("SignalR 连接关闭");state.isConnected = false;});connection.on('ReceiveMessage', (message) => {state.messages.push(message); // 接收到服务器推送的消息});await connection.start();console.log("SignalR 连接成功");state.isConnected = true;} catch (err) {console.error("SignalR 连接失败:", err);}
};
发送消息 (sendMessageOnEnter)
功能说明:
检查是否按下了回车键以及输入框内容是否为空。
调用SignalR的invoke方法,将消息发送到服务器的SendMessage方法。
const sendMessageOnEnter = async (e) => {if (e.key !== 'Enter') return;if (!state.userMessage.trim()) return;if (!state.isConnected) {alert("SignalR 连接未就绪,请稍后再试!");return;}try {await connection.invoke('SendMessage', state.userMessage); // 调用服务器方法state.userMessage = ''; // 清空输入框} catch (err) {console.error("发送消息失败:", err);}
}
相关文章:
使用Vue 3与.NET 8.0通过SignalR实现实时通信,并结合JWT身份验证
实时通信是一个非常重要的功能。SignalR是一个强大的库,能够帮助我们轻松实现客户端和服务器之间的实时数据传输。本文将结合你的代码示例,向你展示如何使用Vue 3作为前端框架,ASP.NET Core作为后端框架,通过SignalR实现实时消息通…...
Harmonyos-Navigation路由跳转
Harmonyos-Navigation路由跳转 概述Navigation路由跳转模块内页面路由系统路由表测试页代码创建并配置路由表文件配置创建好的路由表文件跳转页面 自定义路由表 跨模块路由封装库模块路由跳转工具类 概述 Navigation是路由容器组件,一般作为首页的根容器࿰…...
《人工智能应用创新》5天出审稿意见!
期刊简介 《人工智能应用创新(Innovative Applications of AI)》 (ISSN:3078-2147)是由香港修墨信息工程研究院举办,经国际同行评审后收录的学术期刊。本刊共分三个栏目:综述分析、应用示范、前…...
Excel数据自动填充到Word自定义表格
上一份工作在一家国企做软件测试,需求变来变去(3天一小改,5天换版面),xmind要先整理一遍测试用例(版本迭代,该废的废,该加的加),完了细节在禅道里补充&#x…...
Spring Boot一次接口请求涉及的完整执行链路
Spring Boot一次接口请求涉及的完整执行链路 🔁 Spring 项目请求执行链路(简化视图) 客户端请求(浏览器、Postman)↓ Tomcat(Servlet 容器)↓ 【Listener 监听器】↓ 【Filter 过滤器】&#x…...
mapbox基础,加载视频到地图
👨⚕️ 主页: gis分享者 👨⚕️ 感谢各位大佬 点赞👍 收藏⭐ 留言📝 加关注✅! 👨⚕️ 收录于专栏:mapbox 从入门到精通 文章目录 一、🍀前言1.1 ☘️mapboxgl.Map 地图对象1.2 ☘️mapboxgl.Map style属性1.3 ☘️raster 栅格图层 api二、🍀加载视频到…...
Android动态化技术优化
Android动态化技术优化 一、WebView优化基础 1.1 WebView性能瓶颈 初始化耗时内存占用高页面加载慢白屏问题 1.2 WebView基本配置 class OptimizedWebView : WebView {init {// 开启硬件加速setLayerType(LAYER_TYPE_HARDWARE, null)// 配置WebSettingssettings.apply {//…...
Spring Boot 自定义定时任务组件深度解析:Quartz 集成与设计模式实战
一、组件设计目标 解决痛点: 简化 Quartz 原生 API 的复杂性统一任务调度管理(增删改查、日志、重试)与 Spring Boot 生态无缝整合 二、实现步骤详解 1. 组件初始化配置 1.1 初始化 Quartz 表结构 下载 SQL 脚本 🔗 官方表…...
Java Bean演进历程:从POJO到Spring Boot配置绑定
一、早期阶段:手动编写Java Bean 基本结构 私有属性:所有字段均为private,保证封装性。 公共构造方法:提供无参构造(JavaBean规范)或有参构造(POJO常见)。 Setter/Getter方法&…...
信息科技伦理与道德0:课程安排
1 课程安排 分组讨论的议题如下: 1.1 生成对抗网络(GAN) (1)GAN生成伪造人脸与身份冒用风险 算法原理: GAN通过生成器(Generator)和判别器(Discriminator)…...
STM32F103C8T6-基于FreeRTOS系统实现步进电机控制
引言 上一篇文章讲述了如何使用蓝牙连接stm32进行数据收发控制步进电机,这篇在之前的基础上通过移植操作系统(FreeRTOS或者其他的也可以,原理操作都类似)实现步进电机控制。 上篇博客指路:STM32蓝牙连接Android实现云…...
数字资产和交易解决方案
数字资产和交易解决方案 一、背景 (一)数字经济的蓬勃发展 随着信息技术的飞速发展,数字经济已成为全球经济增长的新引擎。数字资产作为数字经济的重要组成部分,其价值逐渐被人们所认识和重视。数字资产包括但不限于数字货币、…...
计算机网络 实验四 静态路由的配置与应用
一、实验目的 熟悉路由器的工作原理;熟悉静态路由的原理;熟悉华为网络模拟器的使用方法;掌握网络拓扑图的绘制;掌握路由器的配置。 二、实验设备 PC、华为模拟器ENSP。 三、实验步骤 知识准备:路由器和静态路由的…...
二进制求和 - 简单
************* C topic: 67. 二进制求和 - 力扣(LeetCode) ************* Give the topic an inspection. Too many works these days. And no spare time for code learning. However here I am gagin. This topic is an easy one and I want to pra…...
【C++】 —— 笔试刷题day_18
一、压缩字符串(一) 题目解析 题目给定一个字符str,让我们将这个字符串进行压缩; **压缩规则:**出现多次的字符压缩成字符数字;例如aaa压缩成a3。如果字符值出现一次,1不用写。 算法思路 这道题总的来说就非常简单了…...
LeetCode 热题 100_最长递增子序列(87_300_中等_C++)(动态规划)
LeetCode 热题 100_最长递增子序列(87_300) 题目描述:输入输出样例:题解:解题思路:思路一(动态规划): 代码实现代码实现(思路一(动态规划…...
asp-for等常用的HTML辅助标记?
在ASP.NET Core Razor Pages 和 MVC 中,除了asp-for之外,还有许多常用的 HTML 辅助标记,下面为你详细介绍: 表单与路由相关 asp-action 和 asp-controller 用途:这两个标记用于生成表单或链接的 URL,指定…...
map用法介绍
在 C 里,map是标准库提供的一种关联容器,它以键 - 值对的形式存储元素,并且按键的升序排列。下面为你展示如何在 C 用map。 如果没有用万能头的时候,需要加入#include 用法介绍: 映射[需要注意map的映射是1对1的不能出…...
AIGC-十款知识付费类智能体完整指令直接用(DeepSeek,豆包,千问,Kimi,GPT)
Unity3D特效百例案例项目实战源码Android-Unity实战问题汇总游戏脚本-辅助自动化Android控件全解手册再战Android系列Scratch编程案例软考全系列Unity3D学习专栏蓝桥系列AIGC(GPT、DeepSeek、豆包、千问、Kimi)👉关于作者 专注于Android/Unity和各种游戏开发技巧,以及各种资…...
一页概览:桌面虚拟化方案
2010年左右手绘的,用的是公司的信纸,马克笔。当时在买VMware和Citrix的桌面虚拟化方案,以及Wyse的瘦客户端。...
通过导入 Excel 的方式复制文件或文件夹
在进行文件或文件夹的批量整理时,许多人都会遇到需要将大量文件或文件夹复制到另一个文件夹中的问题。传统的手动复制粘贴方法不仅繁琐,而且效率低下。今天给大家介绍一种方法,可以实现将多个不同文件夹中的文件复制到一个或者多个文件夹&…...
Python单例设计模式深度解析
目录 一、什么是单例设计模式 核心特点 二、为什么需要单例模式 典型应用场景 优势对比 三、Python实现单例的三种方式 1. 使用__new__方法(经典实现) 2. 使用装饰器实现 3. 使用模块实现(Python特有) 四、深入理解__new…...
WPF 图标原地旋转
如何使元素原地旋转 - WPF .NET Framework | Microsoft Learn <ButtonRenderTransformOrigin"0.5,0.5"HorizontalAlignment"Left">Hello,World<Button.RenderTransform><RotateTransform x:Name"MyAnimatedTransform" Angle"…...
深入解析Java日志框架Logback:从原理到最佳实践
Logback作为Java领域最主流的日志框架之一,由Log4j创始人Ceki Glc设计开发,凭借其卓越的性能、灵活的配置以及与SLF4J的无缝集成,成为企业级应用开发的首选日志组件。本文将从架构设计、核心机制、配置优化等维度全面剖析Logback的技术细节。…...
【设计模式——装饰器模式】
在 Unity 游戏开发中,装饰模式是一种非常灵活的设计模式,用于在运行时动态地为对象添加功能。以下是装饰模式的设计思路和实现步骤,以角色的装备系统为例进行说明。 设计思路 装饰模式的核心思想是通过创建一个装饰器类来包装原有的对象&am…...
在 macOS 上切换默认 Java 版本
下载javasdk 打开android studio -> setting -> build.execution,dep -> build tools -> gradle -> Gradle JDK -> download JDK… 点击下载,就下载到了 ~/Library/Java/JavaVirtualMachines/ 安装 jenv brew install jenv将 jenv 集成到 Shell …...
【Linux网络与网络编程】11.数据链路层mac帧协议ARP协议
前面在介绍网络层时我们提出来过一个问题:主机是怎么把数据交给路由器的?那里我们说这是由数据链路层来做的。 网络上的报文在物理结构上是以mac帧的形式流动的,但在逻辑上是以IP流动的,IP的流动是需要mac帧支持的。 数据链路层解…...
158页PPT | 某大型研发制造集团信息化IT规划整体方案
该文档是某大型研发制造集团信息化IT规划整体方案,涵盖项目过程回顾、信息平台分析、现状评估、规划及治理建议和下阶段工作计划。项目旨在理解集团战略目标,评估信息化应用现状,制定可扩展的蓝图,明确未来3年管理与IT建设子项目&…...
ON DUPLICATE KEY UPDATE 更底层解释它的优势
从更底层来看,ON DUPLICATE KEY UPDATE 的优势主要源于以下几个方面: 1. 减少网络往返次数 先查询再更新:这种方式需要客户端和数据库服务器之间进行多次网络通信。首先,客户端发送一个 SELECT 查询请求,然后等待服务…...
Python 赋能区块链金融——从零构建智能交易系统
Python 赋能区块链金融——从零构建智能交易系统 引言:区块链金融系统的崛起 区块链技术正在颠覆传统金融体系,带来去中心化、透明化和高效的交易模式。从 DeFi(去中心化金融)到 NFT 市场,区块链金融系统已成为 Web 3.0 生态的重要支柱。如何用 Python 构建一个区块链金…...
基础(测试用例设计方法:流程图法,等价类划分法,边界值分析法,判定表法,正交分析法,错误推测法,其他方法,案例)
目录 流程图法(场景法) 业务流程 流程图 流程图法设计测试用例 案例-退款泳道图 案例-刷视频流程 等价类划分法 等价类 等价类设计测试用例 案例1-验证电话号码 案例2-验证邮箱格式 边界值分析法 测试数据的选取 边界值法设计测试用例 案例…...
QT —— 信号和槽(槽函数)
QT —— 信号和槽 信号和槽信号(Signal)槽(Slot)声明方式工作原理连接方式1. 传统连接方式(Qt4风格)2. 新式连接方式(Qt5风格) 区分槽函数和信号通过QtCreator生成信号槽代码自动生成槽函数显式连接的优势命名约定自动连接的局限性最佳实践建议结论 我们之前对QT,有…...
ROS2模块库概览
一、核心通信与基础库(最常用) 客户端库 rclcpp (ROS Client Library for C) 核心API:create_node(), create_publisher(), create_subscription()高级特性: 生命周期节点:通过rclcpp_lifecycle实现configure/activate…...
HADOOP——序列化
1.创建一个data目录在主目录下,并且在data目录下新建log.txt文件 2.新建flow软件包,在example软件包下 FlowBean package com.example.flow;import org.apache.hadoop.io.Writable;import java.io.DataInput; import java.io.DataOutput; import java.i…...
第五章 5.2ESP32物联网应用:HTTP与Web服务器详细教学
本文将详细讲解如何在ESP32上搭建Web服务器,通过HTTP协议实现远程控制LED灯。每行代码均有详细注释,适合零基础学习。 一、HTTP协议基础 HTTP是客户端(浏览器)和服务器之间的通信协议,常用请求方法: GET&a…...
c++11 绑定器bind
文章目录 std::bind 使用总结(C11)1. 绑定普通函数2. 使用占位符 _1, _2,调用时传参数3. 绑定类的成员函数(类外)4. 绑定类的成员函数(类内)5. 占位符结合成员函数小结 std::bind 使用总结&…...
实现时间最优轨迹生成/轨迹规划方法(TOTG),不使用moveit,可用于ROS驱动机械臂FollowJointTrajectoryGoal()
前言 在我的这篇文章:https://blog.csdn.net/weixin_45702459/article/details/139293391?spm1011.2415.3001.5331中,写了不使用moveit来ros驱动机械臂的方法,也就是用FollowJointTrajectoryGoal()来进行一系列点的关节运动,其实…...
2025年推荐使用的开源大语言模型top20:核心特性、选择指标和开源优势
李升伟 编译 随着人工智能技术的持续发展,开源大型语言模型(LLMs)正变得愈发强大,使最先进的AI能力得以普及。到2025年,开源生态系统中涌现出多个关键模型,它们在各类应用场景中展现出独特优势。 大型语言…...
高并发多级缓存架构实现思路
目录 1.整体架构 3.安装环境 1.1 使用docket安装redis 1.2 配置redis缓存链接: 1.3 使用redisTemplate实现 1.4 缓存注解优化 1.4.1 常用缓存注解简绍 1.4.2 EnableCaching注解的使用 1.4.3使用Cacheable 1.4.4CachePut注解的使用 1.4.5 优化 2.安装Ngin…...
Qt 的 事件队列
Qt 的 事件队列 是其核心事件处理机制之一,用于管理和分发系统与用户生成的事件(如鼠标点击、键盘输入、定时器、信号槽中的队列连接等)。理解 Qt 的事件队列对多线程、界面响应以及异步处理尤为关键。 一、Qt 的事件处理模型概览 Qt 是基于…...
html-css样式
1. 所有类型为文本的 元素的样式 指定所有类型为文本的 元素的样式 /* 文本框的样式 */ input[type"text"] { font-size: 25px;width: 80px; /* 文本框的宽度 */ padding: 25px; } font-size:字体大小 width:文本框宽度 padding&#…...
Qemu-STM32(十五):STM32F103加入Flash控制器
概述 本文主要描述了在Qemu平台中,如何添加STM32F103的Flash控制器模拟代码。 参考资料 STM32F1XX TRM手册,手册编号:RM0008 添加步骤 1、在hw/arm/Kconfig文件中添加STM32F1XX_FLASH,如下所示: 号部分为新增加内容 diff -…...
设计模式(责任链模式)
责任链模式 模板模式、策略模式和责任链模式,这三种模式具有相同的作用:复用和扩展,在实际的项目开发中比较常用,特别是框架开发中,我们可以利用它们来提供框架的扩展点,能够让框架的使用者在不修改框架源…...
【Mac-ML-DL】深度学习使用MPS出现内存泄露(leaked semaphore)以及张量转换错误
MPS加速修改总结 先说设备:MacBook Pro M4 24GB 事情的起因是我在进行深度学习的时候想尝试用苹果自带的MPS进行训练加速,修改设备后准备开始训练,但是出现如下报错: UserWarning: resource_tracker: There appear to be 1 leak…...
Hadoop集群部署教程-P5
Hadoop集群部署教程-P5 Hadoop集群部署教程(续) 第十七章:安全增强配置 17.1 认证与授权 Kerberos认证集成: # 生成keytab文件 kadmin -q "addprinc -randkey hdfs/masterEXAMPLE.COM" kadmin -q "xst -k hdfs.…...
Github 2FA(Two-Factor Authentication/两因素认证)
Github 2FA认证 多因素用户认证(Multi-Factor Authentication),基本上各个大互联网平台,尤其是云平台厂商(如:阿里云的MFA、华为云、腾讯云/QQ安全中心等)都有启用了,Github算是搞得比较晚些了。 双因素身…...
Spark大数据分析与实战笔记(第四章 Spark SQL结构化数据文件处理-05)
文章目录 每日一句正能量第4章 Spark SQL结构化数据文件处理章节概要4.5 Spark SQL操作数据源4.5.1 Spark SQL操作MySQL4.5.2 操作Hive数据集 每日一句正能量 努力学习,勤奋工作,让青春更加光彩。 第4章 Spark SQL结构化数据文件处理 章节概要 在很多情…...
使用 Azure AKS 保护 Kubernetes 部署的综合指南
企业不断寻求增强其软件开发和部署流程的方法。DevOps 一直是这一转型的基石,弥合了开发与运营之间的差距。然而,随着安全威胁日益复杂,将安全性集成到 DevOps 流水线(通常称为 DevSecOps)已变得势在必行。本指南深入探…...
遵守 Vue3 的单向数据流原则:父组件传递对象 + 子组件修改对象属性,安全地实现父子组件之间复杂对象的双向绑定示例代码及讲解
以下是针对 父组件传递对象 子组件修改对象属性 的完整示例代码,同时遵守 Vue3 的单向数据流原则: 1. 父组件代码 (ParentComponent.vue) vue <template><!-- 通过 v-model 传递整个对象 --><ChildComponent v-model"formData&qu…...
Unchained 内容全面上链,携手 Walrus 迈入去中心化媒体新时代
加密新闻媒体 Unchained — — 业内最受信赖的声音之一 — — 现已选择 Walrus 作为其去中心化存储解决方案,正式将其所有媒体内容(文章、播客和视频)上链存储。Walrus 将替代 Unchained 现有的中心化存储架构,接管其全部历史内容…...