借助Blazor在浏览器运行dotnet代码

借助Blazor在浏览器运行dotnet代码 本文重点,想看步骤的请直接移步正文 如何精简Blazor的代码,移除界面部分 如何和c#部分交互 如何访问FS部分 打包构建 因为工作上的需要,需要在网页上进行usm格式的视频,但是usm的视频格式并没有相关的说明,导致也没办法和之前一样直接通过读取二进制流的方式解码然后转mp4流喂给<video> 不过业内也都是使用CriDemuxer来对usm视频格式进行解交织的,而且CriDemuxer有开源,只不过代码是基于C#的,所以最后问题变成了,怎么在网页中运行C#代码 碎碎念结束 BLAZOR 目前将c#运行在浏览器端主要靠编译成wasm运行,在net5之前,想让dotnet多端运行就得借助mono进行编译,然后mono有推出过一个mono-wasm0.1的包,可以将编译为wasm可以因为维护的原因,已经下不到了 不过好在微软官方有一个借助mono-wasm的项目 Blazor 来实现用 C# 来构建网页,虽然用不上他的页面功能,但是四舍五入一下,却可以用它来实现在浏览器端运行 C# 代码 实现步骤 安装环境 根据官方教程即可 https://dotnet.microsoft.com/apps/aspnet/web-apps/blazor 创建项目 我们创建一个基于wasm的app dotnet new blazorwasm -o BlazorApp --no-https 然后项目就创建完了,记住和官方教程不一样,是blazorwasm dev cd BlazorApp dotnet watch run 一个基础项目就起来了,之后开始进行改造 移除页面相关文件 目录 pages Shared 文件 App.razor _Imports.razor 修改 Program.cs移除` builder.RootComponents.Add("#app"); `这行 这个时候运行,页面上应该就只有一个Loading...了,如果觉得难受,可以修改wwwroot下的index.html文件 编写代码 之后整个项目其实就是一个标准的dotnet项目了,可以直接将编写的代码移动进来,比如我这里就直接把CriDemuxerCore的代码直接移动进来 编写调用代码 在Program.cs内注入相关的js入口即可 这样的话,在浏览器内就能调用c#的代码了 using Microsoft.JSInterop; [JSInvokable] public static async Task<string> Demux(string filePath) { if (File.Exists(filePath)) { MpegStream.DemuxOptionsStruct demuxOptions = new MpegStream.DemuxOptionsStruct(); demuxOptions.ExtractVideo = true; return await Task.Run(() => { Console.WriteLine("Start"); CriUsmStream criUsmStream = new CriUsmStream(filePath); return criUsmStream.DemultiplexStreams(demuxOptions)[0]; }); } else { throw new Exception(filePath + " Not exists"); } } 在浏览器中的调用方法 ...

May 10, 2021 · 1 min · 134 words · 水华

el-table横向滚动条吸底处理方案思路

起因 工作中用到的 el-table显示大批量数据的时候,一页放不下,一般性的处理方案是限定了高,让表格固定表头之后内部可以滚动,不过因为实际操作中样式的问题,需要我把整个表格高度全部显示出来,这样就造成了一个问题,就是横向滚动不方便 不过作为mac用户已开始没啥感觉,但是被用windows的同事吐槽了好久,于是终于决定花半天时间解决 仓库 已开源,不想看的,可以直接看代码https://github.com/mizuka-wu/el-table-horizontal-scroll 或者安装npm i el-table-horizontal-scroll用指令的形式使用该项目 实现原理 其实是模拟了一个el-scroll进行同步,为了方便,制作成了一个指令 核心代码 通过Scroller类,创建一个scroller的dom,并插入到指令提供的el内部 el.appendChild(scroller.dom) 目标对象 const targetTableWrapperEl = el.querySelector('.el-table__body-wrapper') Scroller类 具体地址 主要负责了scroller的创建和管理,具体可以直接看代码 其模拟了一个el-scroll的dom结构(为了省的写样式) 大概会出现一个这样的dom结构 <!-- scroll/dom整个dom结构 --> <div class="el-scrollbar"> <!-- bar横条容器 --> <div class="'el-scrollbar__bar is-horizontal"> <!-- thumb滑块 --> <div class="el-scrollbar__thumb"></div> </div> </div> 然后整体就是对这个结构进行操作 例如,scroll的整体样式需要手动添加,让其可以自由浮动,然后显示在fixed列前,所以需要 scroller.style.height = '12px' scroller.style.position = 'fixed' scroller.style.bottom = 0 scroller.style.zIndex = 3 以及一些其他的调整,具体不再阐述 自动吸底原理 这个就是目前监听document的scroll事件,判断是否需要显示 核心判断代码就是判断el的底部是否出现在页面内 const viewHeight = window.innerHeight || document.documentElement.clientHeight const { bottom } = targetTableWrapperEl.getBoundingClientRect() // 当前的el-table的wrapper,可以在el内获取到 if (bottom <= viewHeight) { hideScroller() } else { showScroller() } 平时就position: fixed在页面底部,如果表格底部显示在页面里了,就自动隐藏即可 ...

July 9, 2019 · 2 min · 215 words · 水华

axios如何中断请求

axios 是一个非常方便的请求库,但是缺没有原生提供一个 abort 接口,因为 axios 的返回是一个 promise,我们可以利用 promise 的特性来实现一个 abort 方法 Promise.race promise.race 方法从字面意思上就是赛跑,其中只要有任意一个完成了,就返回完成的那个,有一个失败了,就改为失败,利用这个特性就能完成我们的 abort 方法 Promise.race([ // 等待取消组 new Promise((_resolve, reject) => { notify.onClose = function() { reject(new Error('手动停止导出!')) } }), // 获取数据组 axios.get() ) 当然,例子中利用了 element-ui 的 notify 组件,绑定了 notify 组件的 onClose 方法,实际上也可以通过封装对象的方式实现

October 15, 2018 · 1 min · 45 words · 水华