1 Star 0 Fork 20

godlong / CefSharpVue

forked from 放羊娃 / CefSharpVue 
加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
README.md 14.54 KB
一键复制 编辑 原始数据 按行查看 历史
放羊娃 提交于 2021-06-24 11:31 . .

📌CefSharpVue📌

介绍

使用vue来创建界面,用winform来显示界面,使用C#实现后台逻辑开发。当前项目已搭建框架开发结构。 在vue创建的界面通过CefSharp的chrome核心来呈现界面,使其通过简单的js调用,来访问后端数据,后端通过反射,统一接管处理请求,实现业务,只需要简单的添加类和类的特性即可进行后端方法逻辑的访问。 通过修改vue的打包生产相关的js,使其支持实时动态查看vue的元素更改(如果需要刷新页面,可以通过F12调出chrome的开发者工具,在工具上使用F5进行页面刷新)。

快速入门

点击查看入门教程

相关示例和文章

示例1:使用当前框架开发图片管理 文章:使用当前框架开发图片管理

示例2:使用CefSharpVue开发个人文件助手

效果图如下

软件架构

软件架构说明 使用winform创建基础窗口,在基础窗口上使用chrom浏览器展现html页面,通过vue来编写页面,目前将vue集成到winform项目中,在vue项目中通过调用js方法,在winform中通过类来实现业务逻辑。

使用环境及需要的开发软件

  1. Nodejs
  2. vue2.x
  3. C# winform

开发软件

  1. visual studio 2019
  2. windows10
  3. Hbuilderx 开发vue

安装教程(可直接查看使用说明)

  1. 下载或克隆目前项目的代码
  2. 在项目目录 CefSharpVue/ui/vue 下使用 npm install 命令来安装常用的类库(推荐);或者也可在当前目录下使用vue2.x的脚手架和webpack创建vue项目,但需使用当前项目/WInform_Vue/ui/vue/build文件夹,该文件是对相关js的修改,使其支持winform使用
  3. 使用visual studio 2019或相关版本打开项目
  4. 因为使用的是csfsharp进行的封装,请遵行他的代码许可。

使用说明

  1. 下载或克隆项目
  2. 打开visual stuido
  3. 选择Debug或者Release
  4. 选择Debug或者Release模式对应vue不同的生产运行策略。
  5. 执行对应模式下的相关命令,在visual stuido启动winform项目

不同模式下的对应操作命令

Debug模式下的操作

  1. 在visual studio 打开的情况下,运行终端(vs中找:视图->终端)并运行如下命令(建议将终端固定到编辑器中,防止vs运行时找不到终端)
# cd ../项目名称/ui/vue
> cd ./WInform_Vue/ui/vue
# 首次使用 ,需要执行 npm install命令进行安装相关依赖
> npm install
> npm run dev
  1. 在visual studio 中运行项目

:这种模式下将 vue 项目启动起来后,可以进行动态修改页面,实时进行查看效果,且在终端存在vs的状态下,不需要再次启动,后续只需要启动winform项目即可。目前已内置F12启动devTools控制台;如需刷新页面,可先调出devTools ,之后F5,刷新页面。

Release模式下的操作

  1. 在visual studio 打开的情况下,运行终端(vs中找:视图->终端)并运行如下命令(建议将终端固定到编辑器中,防止vs运行时找不到终端)
# cd ../项目名称/ui/vue
> cd ./WInform_Vue/ui/vue
> npm run build
  1. 在visual studio 中运行项目

:在这种模式下每次启动项目,都需要手动执行npm run build打包命令,这种模式适合发布使用,不适合开发使用。

业务实现

  1. 界面上实现业务

1.1. 切换到vue目录

打开到 ./CefSharpVue/ui/vue

1.2. 在index.vue页面中添加如下代码

<template>
  <div class="w h-vh box-b">
    <div>请求测试</div>
    <h1 class="t-l p-l10">
      参数为普通字段 string key
    </h1>
    <el-card class="box-b">
      <button @click="method1">
        调用/login/login
      </button>
      结果:
      <span class="c-s">
        {{dataResult1}}
      </span>
    </el-card>
    <!--  -->
    <h1 class="t-l p-l10">
      完整的参数调用,请克隆项目,查看运行示例
    </h1>

  </div>
</template>

<script>
  export default {
    data() {
      return {
        //参数一
        data1: {
          phone: '18888888888',
          password: '123456'
        },
        dataResult1: null,
      }
    },
    watch: {

    },
    methods: {
      method1() {
        this.$api.login(this.data1).then(res => {
          this.dataResult1 = res;
        });

      },
    },
    created() {}
  }
</script>

<style>
</style>

1.3. 在 API/api-method.js中添加如下代码


//// ------------------------------
///rquest(path,param,methodType) 方法的三个参数


// path: `请求路径`;它由两部分组成【请求类的注解和请求方法的注解】   

// param: `请求参数`;【可为空】

// methodType: `请求类型`【可为空,为空时默认值为:GET】;目的是为了 无缝切换使用http请求模式,当后台服务进行更改时,可以只需要切换 构建的request方法的js文件即可

////-----------------------------

const api = {
    //后台使用2个字段接收参数
    login: function(data) {
        return request('/login/login', data, 'POST');
    },
    //后台使用 实体类 接收参数
    userInfo:function(data){
    return request('/login/userInfo', data, 'POST');
    },
    //后台使用 多个 实体类 接收参数
    userExpansionEntity:function(data){
    return request('/login/userExpansionEntity', data, 'POST');
    },

    //后台使用 实体类 和 List<实体类> 接收参数
    userExpansionEntityList:function(data){
    return request('/login/userExpansionEntityList', data, 'POST');
    },

    //后台使用 List<实体类> 接收参数
    userInfoList:function(data){
    return request('/login/userInfoList', data, 'GET');
    },

    //后台使用 List<string> 接收参数
    strList:function(data){
    return request('/login/strList', data, 'GET');
    },

    //其他代码

}
  1. 在winform项目中添加如下代码

2.1. 添加controller目录,将请求方法归纳到一个文件夹

2.1.1 在controller目录下,创建TestController.cs

using System;
using System.Collections.Generic;
using CefSharpVue.core.attribute;
using CefSharpVue.core.util.response;
using CefSharpVue.entity;

namespace CefSharpVue.Project.Controllers
{
    [Controller]
    [RequestMapping("/login")]
   public class TestController
    {
        /// <summary>
        /// 测试指定参数赋值
        /// </summary>
        /// <returns></returns>
        [RequestMapping("/login", MethodType.POST)]
        public BaseResponse<Object> GetLogin(string phone, string password)
        {
            if (phone == "18888888888" && password == "1234567890")
            {
                Dictionary<string, string> useInfo = new Dictionary<string, string> {
                     {"phone","18888888888"},{"nickName","超级管理员"},{"sex","1"}
                };
                return new BaseResponse<Object>("登录成功!", useInfo);
            }
            return new BaseResponse<Object>(StatusCode.Fail, "用户名或密码错误!",new object[] { phone,password });
        }

        /// <summary>
        /// 测试接受参数自动赋值包装成对象
        /// </summary>
        /// <param name="userInfoEntity"></param>
        /// <returns></returns>
        [RequestMapping("/userInfo", MethodType.POST)]
        public BaseResponse<Object> GetUserInfo(UserInfoEntity userInfoEntity)
        {
            return new BaseResponse<Object>(userInfoEntity);
        }



        /// <summary>
        /// 测试接受参数自动赋值包装成对象
        /// </summary>
        /// <returns></returns>
        [RequestMapping("/userExpansionEntity", MethodType.POST)]
        public BaseResponse<Object> GetUserExpansionEntity(UserInfoEntity userInfo,UserExpansionEntity userExpanis)
        {
            return new BaseResponse<Object>(new object[] { userInfo, userExpanis });
        }



        /// <summary>
        /// 测试接受参数自动赋值包装成对象
        /// </summary>
        /// <returns></returns>
        [RequestMapping("/userExpansionEntityList", MethodType.POST)]
        public BaseResponse<Object> GetuserExpansionEntityList(List<UserInfoEntity> userInfo, UserExpansionEntity userExpanis)
        {
            return new BaseResponse<Object>(new object[] { userInfo, userExpanis });
        }




        /// <summary>
        /// 测试接受参数自动赋值包装成对象集合
        /// </summary>
        /// <param name="userInfoEntity"></param>
        /// <returns></returns>
        [RequestMapping("/userInfoList", MethodType.GET)]
        public BaseResponse<Object> GetUserInfoList(List<UserInfoEntity> userInfoEntityList)
        {
            return new BaseResponse<Object>(userInfoEntityList);
        }


        /// <summary>
        /// 测试接受参数自动赋值包装成对象集合
        /// </summary>
        /// <param name="userInfoEntity"></param>
        /// <returns></returns>
        [RequestMapping("/strList", MethodType.GET)]
        public BaseResponse<Object> GetStrListt(List<string> list)
        {
            return new BaseResponse<Object>(list);
        }

    }
}

2.2. 添加entity目录,将请求方法归纳到一个文件夹

2.2.1 在entity目录下,创建UserExpansionEntity.cs



namespace CefSharpVue.Entitys
{
    public class UserExpansionEntity
    {
        public string NickName { get; set; }
        public string MobilePhone { get; set; }
        public string Job { get; set; }
        public int IsMarriage { get; set; }
        public int QQ { get; set; }
        public int WeiXin { get; set; }
    }
}

2.2.2 在entity目录下,创建UserInfoEntity.cs


namespace CefSharpVue.Entitys
{
   public class UserInfoEntity
    {
        public string NickName { get; set; }
        public string Phone { get; set; }
        public string Password { get; set; }
        public int Sex { get; set; }
        public int Age { get; set; }
    }
}

为了更好的使用反射接管相关请求和执行方法,我们做了如下约定

1.前端请求统一处理类 后缀为 xxxController

2.方法参数使用实体类 后缀为 xxxEntity

3.接管的js请求的方法类需要添加 [Controller]特性和[RequestMapping("/login")]特性

4.接管的js请求的方法类中的 ·方法· 需要添加 [RequestMapping("/login", MethodType.POST)]特性 methodType为空时默认为MethodType.GET

5.前端请求参数的约定

5.1当后端的入参有且只有一个参数为实体类时

  • 支持如下json
  {
      "phone":"123456",
      "password":"123456",
      "sex":"1",
      ...
      //实体类的其他属性
  }

5.2当后端的入参为多个时

  • 支持如下json
  {
      "userInfo":{
        "phone":"123456",
        "password":"123456",
        "sex":"1",
        //...
        //实体类的其他属性
      },
      "addName":"张三",
      "userExpanis": {
        "isMarriage": 0,
        "job": "IT",
        "mobilePhone": "0931-000000",
        "nickName": "张三分",
        "QQ": "1427xxxxx",          //上文的实体类定义的类型为int ,因此这里是会赋值失败;最终值为0
        "weiXin": "xxxxxxx"         //上文的实体类定义的类型为int,因此这里是会赋值失败;最终值为0
      },
      //...
      //其他参数
  }

6.当入参为集合时,

6.1 前端js请求参数json如下

  • 当类型为List<T> T 为实体类时,仅支持如下表达
  {
    "userInfoEntityList": [{
    "phone": "1555555555",
    "password": "123456",
    "sex": 2,
    "age": "20"
    }, {
    "phone": "16666666666",
    "password": "123456",
    "sex": 1,
    "age": "10"
    }, {
    "phone": "18888888888",
    "password": "123456",
    "sex": 3,
    "age": "30"
    }, {
    "phone": "1777777777",
    "password": "123456",
    "sex": 4,
    "age": "50"
    }]
}
  
  • 当类型为List<T> T 为常见类型 string, int ,float, double 等等 时,支持如下json表达
    [1,3,4,5,6,7,8] //泛型T  int 
    ["20","21","22","26","28"]  //泛型T  string, int ,float,double等; 核心逻辑会尝试继续类型转化,当前数组值可以进行转化成 int、float、double等 

只需遵守如上传参规则即可轻松使用程序,可对前台的业务进行更小粒度的管理和维护,可以将相同的业务设计到一个文件中进行维护和管理。


改进计划

  1. 继续进行自动化配置,实现继承到vs一键启动
  2. 完善打包后相关业务
  3. 利用反射继承多数据库业务支持
  4. 添加相关的日志类,处理相关业务和日志

该项目的发展离不开你的支持和贡献

  1. 你可以通过参与项目一起改进

  2. 你可以通过赞赏或捐助,进行项目的发展

参与贡献

  1. 加入一起开发 (个人QQ:1427953302)

  2. 加入参与文档翻译(中译英)

  3. 加入参与改进计划

  4. 加入制定更多的支持规则和功能

C#
1
https://gitee.com/godlong/cef-sharp-vue.git
git@gitee.com:godlong/cef-sharp-vue.git
godlong
cef-sharp-vue
CefSharpVue
master

搜索帮助