Unity之webgl端通过vue3接入腾讯云联络中心SDK
腾讯云联络中心SDK:云联络中心 Web-SDK 开发指南-文档中心-腾讯云 (tencent.com)
1 首先下载Demo
1.1 对其进行解压
1.2根据文档操作
查看README.md,根据说明设置server下的dev.js里的相关参数。
然后打开电脑终端,cd到项目的路径:
安装依赖
运行
1.3 运行demo
复制http://127.0.0.1:5173/在浏览器里输入,这时候会显示如下画面:
输入电话号码,点击拨打就会把电话打出去。
2 在Unity端的操作
2.1 创建Unity工程
新建一个Unity工程,在Assets/Plugins/WebGl下创建一个后缀为jslib的文件,记事本打开编写脚本如下:
mergeInto(LibraryManager.library, {ReportReady: function () {window.ReportReady()},TellPhone:function(typeName, phone){SendPhone(UTF8ToString(typeName), UTF8ToString(phone))}});
2.2 编写挂载对象UIPanel上的脚本
using System.Collections;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using UnityEngine;
using UnityEngine.UI;
using TMPro;public class UIPanel : MonoBehaviour
{ [DllImport("__Internal")]private static extern string ReportReady();[DllImport("__Internal")]private static extern string TellPhone(string type,string phone);public TextMeshProUGUI text;public TMP_InputField inputField;void Start(){ReportReady();//向vue报告脚本初始化完成}public void OpenPhone(){TellPhone("tellphone",inputField.text);}public void receiveMsgFromVue(string token) {text.text = token;Debug.Log("接受来自vue的消息 == " + token);}
}
2.3 Unity的UI界面
2.4最后打包webgl的包
放在tccc-demo-vue\src\路径下,如下图所示:
2.5改写index.html
打开index.html:
SendPhone是Unity发送给网页的方法,sendMsgToUnity方法是网页发送个Unity的方法。
index.html完整代码如下:
<!DOCTYPE html>
<html lang="en-us"><head><meta charset="utf-8"><meta http-equiv="Content-Type" content="text/html; charset=utf-8"><title>Unity WebGL Player | Web731</title><link rel="shortcut icon" href="TemplateData/favicon.ico"><link rel="stylesheet" href="TemplateData/style.css"></head><body><div id="unity-container" class="unity-desktop"><canvas id="unity-canvas" width=1920 height=1080></canvas><div id="unity-loading-bar"><div id="unity-logo"></div><div id="unity-progress-bar-empty"><div id="unity-progress-bar-full"></div></div></div><div id="unity-warning"> </div><div id="unity-footer"><div id="unity-webgl-logo"></div><div id="unity-fullscreen-button"></div><div id="unity-build-title">Web731</div></div></div><script>var container = document.querySelector("#unity-container");var canvas = document.querySelector("#unity-canvas");var loadingBar = document.querySelector("#unity-loading-bar");var progressBarFull = document.querySelector("#unity-progress-bar-full");var fullscreenButton = document.querySelector("#unity-fullscreen-button");var warningBanner = document.querySelector("#unity-warning");// Shows a temporary message banner/ribbon for a few seconds, or// a permanent error message on top of the canvas if type=='error'.// If type=='warning', a yellow highlight color is used.// Modify or remove this function to customize the visually presented// way that non-critical warnings and error messages are presented to the// user.function unityShowBanner(msg, type) {function updateBannerVisibility() {warningBanner.style.display = warningBanner.children.length ? 'block' : 'none';}var div = document.createElement('div');div.innerHTML = msg;warningBanner.appendChild(div);if (type == 'error') div.style = 'background: red; padding: 10px;';else {if (type == 'warning') div.style = 'background: yellow; padding: 10px;';setTimeout(function() {warningBanner.removeChild(div);updateBannerVisibility();}, 5000);}updateBannerVisibility();}var buildUrl = "Build";var loaderUrl = buildUrl + "/web0803.loader.js";var config = {dataUrl: buildUrl + "/web0803.data.unityweb",frameworkUrl: buildUrl + "/web0803.framework.js.unityweb",codeUrl: buildUrl + "/web0803.wasm.unityweb",streamingAssetsUrl: "StreamingAssets",companyName: "DefaultCompany",productName: "Web731",productVersion: "0.1",showBanner: unityShowBanner,};// By default Unity keeps WebGL canvas render target size matched with// the DOM size of the canvas element (scaled by window.devicePixelRatio)// Set this to false if you want to decouple this synchronization from// happening inside the engine, and you would instead like to size up// the canvas DOM size and WebGL render target sizes yourself.// config.matchWebGLToCanvasSize = false;if (/iPhone|iPad|iPod|Android/i.test(navigator.userAgent)) {container.className = "unity-mobile";// Avoid draining fillrate performance on mobile devices,// and default/override low DPI mode on mobile browsers.config.devicePixelRatio = 1;unityShowBanner('WebGL builds are not supported on mobile devices.');} else {canvas.style.width = "1920px";canvas.style.height = "1080px";}loadingBar.style.display = "block";var script = document.createElement("script");script.src = loaderUrl;script.onload = () => {createUnityInstance(canvas, config, (progress) => {progressBarFull.style.width = 100 * progress + "%";}).then((unityInstance) => {loadingBar.style.display = "none";fullscreenButton.onclick = () => {unityInstance.SetFullscreen(1);};unityInstanceV = unityInstance;}).catch((message) => {alert(message);});};document.body.appendChild(script);var unityInstanceV;function ReportReady() {window.parent.postMessage({guid:"",event:"ReportReady"}, "*");}function SendPhone(_type,_phone){// alert(s);if (_type == "tellphone"){window.parent.postMessage({guid:"",event:_type,phone:_phone}, "*");}else {window.parent.postMessage({guid:_type,event:"guid"}, "*");}}function sendMsgToUnity(obj) {unityInstanceV.SendMessage('UIPanel','receiveMsgFromVue',JSON.stringify(obj))}</script></body>
</html>
2.6 修改Container.vue脚本
增加和Unity交互的方法
把原先显示的界面代码删除掉<div class="container"> </div>
style 部分也删掉
对Vue不熟悉,我的理解是这样的(理解不对请留言指正)
其中
onMounted(()=>{window.addEventListener('message', unityWatch,true)})
是事件,对Unity发送来的消息进行监听。
function vueSendToUnity(){console.log(statusMap[status.value])unityIframe.value.contentWindow.sendMsgToUnity({userId:'****',状态:status.value|| '加载中...'})
}
是vue把消息发送到Unity端。
<template><div >
<iframe id="iframe" ref="unityIframe" src="/src/unity/index.html" style="width:100%;height:100vh" frameborder="0" scrolling="auto" /> </div>
</template>
是Unity部分进行显示(其中stytle的height:100% 不起作用,有知道的请留言,谢谢,所以我改为了height:100vh)。
Container.vue修改后代码如下:
<script setup>
import { ref, onMounted } from 'vue'
const wechatGroupImg = 'https://tccc.qcloud.com/assets/wechatGroup.png';
const arrowImg = 'https://tccc.qcloud.com/assets/arrow.png';const seat = ref('')
const status = ref('')
const number = ref('')
const loading = ref(false)
const isError = ref(false)
const errorField = ref('')const statusMap = {offline: '已下线',disconnect: '网络断开,重连中',free: '空闲中',busy: '忙碌中',rest: '小休中',countdown: '话后倒计时',arrange: '话后整理中',notReady: '示忙中',
}const errorFieldMap = {'InvalidParameterValue.InstanceNotExist': 'sdkAppId','InvalidParameterValue.AccountNotExist': 'userId','AuthFailure.SignatureFailure': 'secretKey或secretId','AuthFailure.SecretIdNotFound': 'secretId',
};const injectTCCC = ({ token, sdkAppId, userId, sdkUrl }) => {const scriptDom = document.createElement('script')scriptDom.setAttribute('crossorigin', 'anonymous')scriptDom.dataset.token = tokenscriptDom.dataset.sdkAppId = sdkAppIdscriptDom.dataset.userid = userIdscriptDom.src = sdkUrldocument.body.appendChild(scriptDom)scriptDom.addEventListener('load', () => {// ready事件必须监听,否则容易发生tccc不存在的错误,所有呼入呼出的逻辑必须在ready事件触发后才可以调用window.tccc.on('ready', () => {// 以下为Demo逻辑,非业务必须。业务代码主要实现都在这个部分const statusVal = window.tccc.Agent.getStatus()status.value = statusVal;seat.value = userId;})// 以下为Demo逻辑,非接入必须setInterval(() => {const statusVal = window.tccc.Agent.getStatus()status.value = statusVal;}, 200)})
}onMounted(() => {// 获取Token的方法必须在页面初始化时第一优先级调用fetch('/loginTCCC').then((res) => res.json()).then((res) => {// 以下为Demo逻辑,需要替换为业务逻辑if (res.code) {if (res.type) {isError.value = true;errorField.value = errorFieldMap[res.code]} else {isError.value = true;if (errorFieldMap[res.code]) {errorField.value = errorFieldMap[res.code]} else {alert(res.errMsg);}return;}}// 调用成功后才可以开始执行TCCC的注入injectTCCC({token: res.token,userId: res.userId,sdkUrl: res.sdkUrl,sdkAppId: res.sdkAppId,})}).catch((error) => {console.error(`获取Token失败:${error.message}`)})
})const handleCallout = async () => {if (loading.value) {return}loading.value = true// 调用呼出方法的核心代码try {await window.tccc.Call.startOutboundCall({ phoneNumber: number.value })} catch (error) {console.error(`呼出失败:${error.message}`)} finally {loading.value = false}
}onMounted(()=>{window.addEventListener('message', unityWatch,true)}) function unityWatch(e){console.log('unityWatch方法调用 e==' + e.data.guid + ' event=' + e.data.event)if(e.data.event=='tellphone'){handleCalloutByUnity(e.data.phone) vueSendToUnity() }
} //Unity端调用vue里的打电话功能
const handleCalloutByUnity = async (phone) => {if (loading.value) {return}loading.value = true// 调用呼出方法的核心代码try {await window.tccc.Call.startOutboundCall({ phoneNumber: phone })} catch (error) {console.error(`呼出失败:${error.message}`)} finally {loading.value = false}
}const unityIframe = ref('unityIframe')
function vueSendToUnity(){console.log(statusMap[status.value])unityIframe.value.contentWindow.sendMsgToUnity({userId:'****',状态:status.value|| '加载中...'})
}</script><template><div >
<iframe id="iframe" ref="unityIframe" src="/src/unity/index.html" style="width:100%;height:100vh" frameborder="0" scrolling="auto" /> </div>
</template>
2.7 测试运行
测试运行时得保证终端npm run dev在运行中
在Unity 的界面上输入手机号点击拨打,电话打了出去,同时Unity端收到了vue发送过来的消息。
2.8 网页内全屏
这时候如果需要Unity在网页内全屏,且不显示滚动条,需要打开Unity的index.html进行再次修改:
index.html的修改后如下:
<!DOCTYPE html>
<html lang="en-us"><head><meta charset="utf-8"><meta http-equiv="Content-Type" content="text/html; charset=utf-8"><title>Unity WebGL Player | Web731</title><link rel="shortcut icon" href="TemplateData/favicon.ico"><link rel="stylesheet" href="TemplateData/style.css"></head><body><div id="unity-container" style="width: 100%;height:100%"><canvas id="unity-canvas" width=auto height=auto></canvas><div id="unity-loading-bar"><div id="unity-logo"></div><div id="unity-progress-bar-empty"><div id="unity-progress-bar-full"></div></div></div><div id="unity-warning"> </div></div><script>var container = document.querySelector("#unity-container");var canvas = document.querySelector("#unity-canvas");var loadingBar = document.querySelector("#unity-loading-bar");var progressBarFull = document.querySelector("#unity-progress-bar-full");//var fullscreenButton = document.querySelector("#unity-fullscreen-button");var warningBanner = document.querySelector("#unity-warning");// Shows a temporary message banner/ribbon for a few seconds, or// a permanent error message on top of the canvas if type=='error'.// If type=='warning', a yellow highlight color is used.// Modify or remove this function to customize the visually presented// way that non-critical warnings and error messages are presented to the// user.function unityShowBanner(msg, type) {function updateBannerVisibility() {warningBanner.style.display = warningBanner.children.length ? 'block' : 'none';}var div = document.createElement('div');div.innerHTML = msg;warningBanner.appendChild(div);if (type == 'error') div.style = 'background: red; padding: 10px;';else {if (type == 'warning') div.style = 'background: yellow; padding: 10px;';setTimeout(function() {warningBanner.removeChild(div);updateBannerVisibility();}, 5000);}updateBannerVisibility();}var buildUrl = "Build";var loaderUrl = buildUrl + "/web0803.loader.js";var config = {dataUrl: buildUrl + "/web0803.data.unityweb",frameworkUrl: buildUrl + "/web0803.framework.js.unityweb",codeUrl: buildUrl + "/web0803.wasm.unityweb",streamingAssetsUrl: "StreamingAssets",companyName: "DefaultCompany",productName: "Web731",productVersion: "0.1",showBanner: unityShowBanner,};// By default Unity keeps WebGL canvas render target size matched with// the DOM size of the canvas element (scaled by window.devicePixelRatio)// Set this to false if you want to decouple this synchronization from// happening inside the engine, and you would instead like to size up// the canvas DOM size and WebGL render target sizes yourself.// config.matchWebGLToCanvasSize = false;if (/iPhone|iPad|iPod|Android/i.test(navigator.userAgent)) {var meta = document.createElement('meta');meta.name = 'viewport';meta.content = 'width=device-width, height=device-height, initial-scale=1.0, user-scalable=no, shrink-to-fit=yes';document.getElementsByTagName('head')[0].appendChild(meta);container.className = "unity-mobile";canvas.style.width = window.innerWidth + 'px';canvas.style.height = window.innerHeight + 'px';unityShowBanner('暂不支持移动端...');} else { canvas.style.height= document.documentElement.clientHeight+"px";canvas.style.width = document.documentElement.clientWidth+"px"; }loadingBar.style.display = "block";var script = document.createElement("script");script.src = loaderUrl;script.onload = () => {createUnityInstance(canvas, config, (progress) => {progressBarFull.style.width = 100 * progress + "%";}).then((unityInstance) => {loadingBar.style.display = "none";//fullscreenButton.onclick = () => {// unityInstance.SetFullscreen(1);//};unityInstanceV = unityInstance;}).catch((message) => {alert(message);});};document.body.appendChild(script);var unityInstanceV;function ReportReady() {window.parent.postMessage({guid:"",event:"ReportReady"}, "*");}function SendPhone(_type,_phone){// alert(s);if (_type == "tellphone"){window.parent.postMessage({guid:"",event:_type,phone:_phone}, "*");}else {window.parent.postMessage({guid:_type,event:"guid"}, "*");}}function sendMsgToUnity(obj) {unityInstanceV.SendMessage('UIPanel','receiveMsgFromVue',JSON.stringify(obj))}</script></body>
</html>
打开Unity\TemplateData路径下的style.css增加:
html,body{width:100%;height:100%;margin:0;padding:0;overflow:hidden;}
.webgl-content{width: 100%; height: 100%;}
.unityContainer{width: 100%; height: 100%;}
style.css完整脚本如下:
body { padding: 0; margin: 0 }
#unity-container { position: absolute }
#unity-container.unity-desktop { left: 50%; top: 50%; transform: translate(-50%, -50%) }
#unity-container.unity-mobile { width: 100%; height: 100% }
#unity-canvas { background: #231F20 }
.unity-mobile #unity-canvas { width: 100%; height: 100% }
#unity-loading-bar { position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); display: none }
#unity-logo { width: 154px; height: 130px; background: url('unity-logo-dark.png') no-repeat center }
#unity-progress-bar-empty { width: 141px; height: 18px; margin-top: 10px; background: url('progress-bar-empty-dark.png') no-repeat center }
#unity-progress-bar-full { width: 0%; height: 18px; margin-top: 10px; background: url('progress-bar-full-dark.png') no-repeat center }
#unity-footer { position: relative }
.unity-mobile #unity-footer { display: none }
#unity-webgl-logo { float:left; width: 204px; height: 38px; background: url('webgl-logo.png') no-repeat center }
#unity-build-title { float: right; margin-right: 10px; line-height: 38px; font-family: arial; font-size: 18px }
#unity-fullscreen-button { float: right; width: 38px; height: 38px; background: url('fullscreen-button.png') no-repeat center }
#unity-warning { position: absolute; left: 50%; top: 5%; transform: translate(-50%); background: white; padding: 10px; display: none }html,body{width:100%;height:100%;margin:0;padding:0;overflow:hidden;}
.webgl-content{width: 100%; height: 100%;}
.unityContainer{width: 100%; height: 100%;}
但是vue的这个右侧还是有滚动条,还没找到隐藏的方法,有知道的同学请留言,谢谢。
相关文章:

Unity之webgl端通过vue3接入腾讯云联络中心SDK
腾讯云联络中心SDK:云联络中心 Web-SDK 开发指南-文档中心-腾讯云 (tencent.com) 1 首先下载Demo 1.1 对其进行解压 1.2根据文档操作 查看README.md,根据说明设置server下的dev.js里的相关参数。 然后打开电脑终端,cd到项目的路径: 安装…...

《算法竞赛·快冲300题》每日一题:“连接草坪(II)”
《算法竞赛快冲300题》将于2024年出版,是《算法竞赛》的辅助练习册。 所有题目放在自建的OJ New Online Judge。 用C/C、Java、Python三种语言给出代码,以中低档题为主,适合入门、进阶。 文章目录 题目描述题解C代码Java代码Python代码 “ 连…...

LNMP及论坛搭建(第一个访问,单节点)
LNMP:目前成熟的一个企业网站的应用模式之一,指的是一套协同工作的系统和相关软件 能够提供静态页面服务,也可以提供动态web服务,LNMP是缩写 L:指的是Linux操作系统。 N:指的是nginx,nginx提…...

EXCEL,多条件查询数字/文本内容的4种方法
目录 1 问题:如何根据多条件查询到想要的内容 2 方法总结 2.1 方法1: sumif() 和sumifs() 适合查找符合条件的多个数值之和 2.2 方法2:使用lookup(1,0/((区域1条件1)*(区域2条件2)*....),结果查询区域) 2.3 方法3:使用 ind…...

全志D1-H (MQ-Pro)驱动 OV5640 摄像头
内核配置 运行 m kernel_menuconfig 勾选下列驱动 Device Drivers ---><*> Multimedia support --->[*] V4L platform devices ---><*> Video Multiplexer[*] SUNXI platform devices ---><*> sunxi video input (camera csi/mipi…...

2023下半年软考初级网络管理员报名入口-报名流程-备考方法
软考初级网络管理员2023下半年考试时间: 2023年下半年软考初级网络管理员的考试时间为11月4日、5日。考试时间在全国各地一致,建议考生提前备考。共分两科,第一科基础知识考试具体时间为9:00到11:30;第二科应用技术考试具体时间为…...
QEMU源码全解析29 —— QOM介绍(18)
接前一篇文章:QEMU源码全解析28 —— QOM介绍(17) 本文内容参考: 《趣谈Linux操作系统》 —— 刘超,极客时间 《QEMU/KVM》源码解析与应用 —— 李强,机械工业出版社 特此致谢! 前文讲解了类…...
从入门到精通——【初识网络】
文章目录 前言1.网络发展背景2.计算机网络分类3.通信协议4.协议分层5. TCP/IP协议6.网络协议支持7. 封装&分用8. 客户端&服务端 前言 计算机网络是指将地理位置不同的具有独立功能的多台计算机及其外部设备,通过通信线路连接起来,在网络操作系统…...
MySQL alter命令修改表详解
目录 ALTER TABLE 语法 ALTER TABLE 实例 添加一列 添加多列 重命名列 修改列定义 修改列名和定义 添加主键 删除列 重命名表 修改表的存储引擎 结论 在使用表的过程中,如果您需要对表进行修改,您可以使用 ALTER TABLE 语句。通过 ALTER TAB…...

Vulnhub: ColddWorld: Immersion靶机
kali:192.168.111.111 靶机:192.168.111.183 信息收集 端口扫描 nmap -A -sC -v -sV -T5 -p- --scripthttp-enum 192.168.111.183 查看login的源码发现提示:page和文件/var/carls.txt 漏洞利用 wfuzz探测account.php页面发现文件包含&am…...

Redis 总结【6.0版本的】
还差什么?【按照这个为基础,对照他的Redis路线图,冲冲冲】 Redis的常见操作和命令:Redis基本操作命令(图文详解)_redis 命令_进击小高的博客-CSDN博客 Redis的持久化,一致性:AOF&…...

状态模式(C++)
定义 允许一个对象在其内部状态改变时改变它的行为。从而使对象看起来似乎修改了其行为。 应用场景 在软件构建过程中,某些对象的状态如果改变,其行为也会随之,而发生变化,比如文档处于只读状态,其支持的行为和读写…...

承泰科技Q3再获30多个智驾项目,新增订单0.86亿!累计近11亿!
中国毫米波雷达市场正处于高速发展期,以承泰科技为代表的本土供应商在前装量产赛道上展示出加速度。 高工智能汽车研究院预测,随着L2及L2持续处于市场增长的高速期,对应毫米波雷达上车量将在2023年实现30-50%的同比增速。 根据高工智能汽车…...

以太网Ethernet通信协议
一、以太网简介 计算机网络可分为局域网(LAN)、 城域网(MAN)、广域网(WAN)、互联网(Initernet)。局域网按传输介质所使用的访问控制方法可分为:以太网(Ethernet)、光纤分布式数据接口(FDDI)、异步传输模式(ATM)、令牌环网(Token Ring)、交换网(Switching) 等&#x…...

内网横向移动—资源约束委派
内网横向移动—资源约束委派 1. 资源约束委派1.1. 基于资源的约束委派的优势1.2. 约束性委派和基于资源的约束性委派配置的差别1.3. 利用条件1.3.1. 什么用户能够修改msDS-AllowedToActOnBehalfOfOtherIdentity属性1.3.2. 将机器加入域的域用户 2. 案例操作2.1. 获取目标信息2.…...
Spring Boot Logback日志格式改为JSON
在阿里云、或者日志分析时使用JSON格式输出日志更加方便。 依赖 增加Logbak JSON解析依赖。 另外需要注意的是JSON格式输出依赖Jackson,根据工程情况按需添加Jackson依赖。 <!--日志--><dependency><groupId>ch.qos.logback.contrib</grou…...
Linux 块设备操作函数
和字符设备的fil_operations一样,块设备也有操作集,为结构体block_device_operations,此结构体定义在include/linux/blkdev.h中,结构体内容如下: struct block_device_operations {int (*open) (struct block_device …...
linux c++网络编程基础:服务端与客户端的实现
在Linux环境下,我们可以使用socket编程来实现网络通信。下面是一个简单的C++版本的客户端和服务端的示例代码。 服务端代码: #include <sys/socket.h> #include <netinet/in.h> #include <unistd.h> #include <string.h> #...

坐标转换-使用geotools读取和转换地理空间表的坐标系(sqlserver、postgresql)
前言: 业务上通过GIS软件将空间数据导入到数据库时,因为不同的数据来源和软件设置,可能导入到数据库的空间表坐标系是各种各样的。 如果要把数据库空间表发布到geoserver并且统一坐标系,只是在geoserver单纯的设置坐标系只是改了…...
JavaScript的主要应用场景有哪些?请描述一下JavaScript的基本数据类型和引用数据类型分别是哪些?
1、JavaScript的主要应用场景有哪些? JavaScript是一种广泛使用的编程语言,它主要用于Web开发、移动应用开发、游戏开发、物联网设备开发等场景。以下是JavaScript的主要应用场景: Web开发:JavaScript是Web开发中最常用的编程语…...

铭豹扩展坞 USB转网口 突然无法识别解决方法
当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…...

【JavaEE】-- HTTP
1. HTTP是什么? HTTP(全称为"超文本传输协议")是一种应用非常广泛的应用层协议,HTTP是基于TCP协议的一种应用层协议。 应用层协议:是计算机网络协议栈中最高层的协议,它定义了运行在不同主机上…...
STM32+rt-thread判断是否联网
一、根据NETDEV_FLAG_INTERNET_UP位判断 static bool is_conncected(void) {struct netdev *dev RT_NULL;dev netdev_get_first_by_flags(NETDEV_FLAG_INTERNET_UP);if (dev RT_NULL){printf("wait netdev internet up...");return false;}else{printf("loc…...

2.Vue编写一个app
1.src中重要的组成 1.1main.ts // 引入createApp用于创建应用 import { createApp } from "vue"; // 引用App根组件 import App from ./App.vue;createApp(App).mount(#app)1.2 App.vue 其中要写三种标签 <template> <!--html--> </template>…...

《通信之道——从微积分到 5G》读书总结
第1章 绪 论 1.1 这是一本什么样的书 通信技术,说到底就是数学。 那些最基础、最本质的部分。 1.2 什么是通信 通信 发送方 接收方 承载信息的信号 解调出其中承载的信息 信息在发送方那里被加工成信号(调制) 把信息从信号中抽取出来&am…...

视频字幕质量评估的大规模细粒度基准
大家读完觉得有帮助记得关注和点赞!!! 摘要 视频字幕在文本到视频生成任务中起着至关重要的作用,因为它们的质量直接影响所生成视频的语义连贯性和视觉保真度。尽管大型视觉-语言模型(VLMs)在字幕生成方面…...

SpringBoot+uniapp 的 Champion 俱乐部微信小程序设计与实现,论文初版实现
摘要 本论文旨在设计并实现基于 SpringBoot 和 uniapp 的 Champion 俱乐部微信小程序,以满足俱乐部线上活动推广、会员管理、社交互动等需求。通过 SpringBoot 搭建后端服务,提供稳定高效的数据处理与业务逻辑支持;利用 uniapp 实现跨平台前…...

C# 类和继承(抽象类)
抽象类 抽象类是指设计为被继承的类。抽象类只能被用作其他类的基类。 不能创建抽象类的实例。抽象类使用abstract修饰符声明。 抽象类可以包含抽象成员或普通的非抽象成员。抽象类的成员可以是抽象成员和普通带 实现的成员的任意组合。抽象类自己可以派生自另一个抽象类。例…...

Linux-07 ubuntu 的 chrome 启动不了
文章目录 问题原因解决步骤一、卸载旧版chrome二、重新安装chorme三、启动不了,报错如下四、启动不了,解决如下 总结 问题原因 在应用中可以看到chrome,但是打不开(说明:原来的ubuntu系统出问题了,这个是备用的硬盘&a…...
HTML前端开发:JavaScript 常用事件详解
作为前端开发的核心,JavaScript 事件是用户与网页交互的基础。以下是常见事件的详细说明和用法示例: 1. onclick - 点击事件 当元素被单击时触发(左键点击) button.onclick function() {alert("按钮被点击了!&…...