CefSharp结合VUE3进行界面开发

工作一直是做后端研发,近期使用CefSharp研究数据爬取时需要一些界面展示,但WinForm进行界面开发时过于繁琐,于是想通过CefSharp加载本地htm资源进行UI的一些开发,可以利用前端丰富的一些功能库快速的搭建UI。刚开始自己是基于Bootstrap以及JQuery进行界面的开发,但是复杂的界面单htm编写会非常庞大,不利于后期维护扩展,于是搜了下目前流行的前端框架,发现VUE3是很流行的,于是尝试在WinForm项目使用Vue3做界面。

搭建Vue3项目

本地安装node相关模块,然后使用Create Preset进行快速搭建

# 全局安装脚手架
npm install -g create-preset

# 使用 `vue3-ts-vite` 模板创建一个名为 `test-vue3` 的项目
preset init test-vue3 --template vue3-ts-vite

CefSharp加载本地资源文件

创建CustomSchemeHandler的工厂类

因为cefsharp采用了工厂的设计模式,所以还需要实现一个对应的工厂类

using CefSharp;
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;

public class MySchemeHandlerFactory : ISchemeHandlerFactory
    {
        public const string SchemeName = "lightjia";// 自定义Scheme的名称
        private Dictionary<string, MemoryStream> resources = null;
        
        public void MySchemeHandlerFactory()
        {
			string resDir = @"F://myvue";
            if(resources == null)
            {
                resources = new Dictionary<string, MemoryStream>();
            }

            var dirInfo = new DirectoryInfo(resDir);
            foreach (var fi in dirInfo.GetFiles())
            {
               
                using (FileStream fs = new FileStream(fi.FullName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
                {
                    using (BinaryReader br = new BinaryReader(fs))
                    {
                      
                        var dateLen = Convert.ToInt32(fs.Length);
                        MemoryStream ms = new MemoryStream(dateLen);
                        ms.Write(br.ReadBytes(dateLen), 0, dateLen);
                        resources[fi.Name] = ms;
                    }
                }
            }
        }

   

        public IResourceHandler Create(IBrowser browser, IFrame frame, string schemeName, IRequest request)
        {
            if (schemeName == SchemeName)
            {
                return new MySchemeHandler(resources);
            }
            else
            {
                //error handler
                return null;
            }
        }
    }

创建自定义的Scheme类

自定义的Scheme类MySchemeHandler

using CefSharp;
using CefSharp.Callback;
using System;
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;

public class MySchemeHandler : IResourceHandler
{
        private Dictionary<string, MemoryStream> resources;
        private string mimeType;
        private MemoryStream memStream;

        public MySchemeHandler(Dictionary<string, MemoryStream> res)
        {
            resources = res;
        }

        public void Cancel()
        {
        }

        public void Dispose()
        {
            memStream = null;
        }

        public void GetResponseHeaders(IResponse response, out long responseLength, out string redirectUrl)
        {
            redirectUrl = null;
            if (memStream != null)
            {
                response.MimeType = mimeType;
                responseLength = memStream.Length;
                response.StatusCode = (int)System.Net.HttpStatusCode.OK;
                response.StatusText = "OK";
            }
            else
            {
                responseLength = 0;
                response.StatusCode = (int)System.Net.HttpStatusCode.NotFound;
                response.StatusText = "NotFound";
            }
        }

        public bool Open(IRequest request, out bool handleRequest, ICallback callback)
        {
            var uri = new Uri(request.Url);
            var resourceName = uri.AbsolutePath.TrimEnd(new char[]{'/'});
            if (resources.TryGetValue(resourceName, out memStream))
            {
                memStream.Seek(0, SeekOrigin.Begin);
                handleRequest = false;
                Task.Run(() =>
                {
                    using (callback)
                    {
                        var fileExtension = Path.GetExtension(resourceName);
                        mimeType = ResourceHandler.GetMimeType(fileExtension);
                        callback.Continue();
                    }
                });

                return true;
            }
            else
            {
                mimeType = ResourceHandler.GetMimeType(".html");
                memStream = null;
                callback.Continue();
            }
            handleRequest = true;
            return false;
        }

        public bool ProcessRequest(IRequest request, ICallback callback)
        {
            throw new NotImplementedException();
        }

        public bool Read(Stream dataOut, out int bytesRead, IResourceReadCallback callback)
        {
            callback.Dispose();

            if (memStream == null)
            {
                bytesRead = 0;
                return false;
            }

            var buffer = new byte[dataOut.Length];
            bytesRead = memStream.Read(buffer, 0, buffer.Length);

            dataOut.Write(buffer, 0, buffer.Length);
           
            return bytesRead > 0;
        }

        public bool ReadResponse(Stream dataOut, out int bytesRead, ICallback callback)
        {
            throw new NotImplementedException();
        }

        public bool Skip(long bytesToSkip, out long bytesSkipped, IResourceSkipCallback callback)
        {
            throw new NotImplementedException();
        }
    }

vue编译后的资源与本地资源映射

import { createRouter, createWebHistory } from 'vue-router'
import routes from './routes'
import { websiteTitle } from '@/config'

const router = createRouter({
  //history: createWebHistory(import.meta.env.BASE_URL),
  //做资源映射
  history: createWebHistory(
    import.meta.env.DEV ? import.meta.env.BASE_URL : '/myvue/index.html'
  ),
  routes,
})

router.afterEach((to) => {
  const { title } = to.meta
  document.title = title ? `${title} - ${websiteTitle}` : websiteTitle
})

export default router

然后var ChromeBrowser = new ChromiumWebBrowser("lightjia://domin/myvue/index.html")

就会加载本地的资源文件

然后就进行web界面的开发

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值