mirror of
https://github.com/bufanyun/hotgo.git
synced 2025-11-13 12:43:45 +08:00
发布v2.8.4版本,更新内容请查看:https://github.com/bufanyun/hotgo/tree/v2.0/docs/guide-zh-CN/addon-version-upgrade.md
This commit is contained in:
@@ -22,15 +22,16 @@
|
||||
- [支付网关](sys-payment.md)
|
||||
- [数据库](sys-db.md)
|
||||
- [代码生成](sys-code.md)
|
||||
- 定时任务
|
||||
- [定时任务](sys-cron.md)
|
||||
- [消息队列](sys-queue.md)
|
||||
- [功能扩展库](sys-library.md)
|
||||
- 工具方法
|
||||
- [工具方法](sys-utility.md)
|
||||
- RESTful Api
|
||||
- Websocket服务器
|
||||
- TCP服务器
|
||||
- 单元测试
|
||||
- [TCP服务器](sys-tcp-server.md)
|
||||
- [单元测试](sys-test.md)
|
||||
|
||||
|
||||
#### 插件模块开发
|
||||
|
||||
- [模块介绍及目录](addon-introduce-catalog.md)
|
||||
@@ -38,16 +39,12 @@
|
||||
- [模块辅助说明](addon-helper.md)
|
||||
|
||||
|
||||
#### 实战开发
|
||||
- 服务端
|
||||
- web前端
|
||||
|
||||
|
||||
### 前端开发
|
||||
- [表单组件](web-form.md)
|
||||
- Websocket客户端
|
||||
- 工具库
|
||||
- [独立部署](web-deploy.md)
|
||||
|
||||
|
||||
#### 附录
|
||||
- [网址收录](append-website.md)
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 33 KiB |
@@ -12,6 +12,19 @@
|
||||
> 如果升级(覆盖)代码后打开会出现 sql 报错, 请检查更新的数据库格式或自行调整
|
||||
|
||||
|
||||
### v2.8.4
|
||||
updated 2023.07.22
|
||||
|
||||
- 增加:增加输入预处理中间件
|
||||
- 增加:增加文件选择器
|
||||
- 增加:增加在线服务监控,服务许可证管理
|
||||
- 增加:TCP服务器增加RPC路由消息注册、路由分发、拦截器注册,更方便的进行应用开发
|
||||
- 优化:gf版本升级到v2.5.0
|
||||
- 优化:优化CURD代码生成,简化控制器代码逻辑,升级列表数据查询方式
|
||||
- 修复:修复角色菜单子权限取消导致父级权限失效问题
|
||||
- 修复:修复上传驱动路径错误
|
||||
- 修复:修复CURD代码生成时间类型字段默认值获取异常
|
||||
|
||||
### v2.7.6
|
||||
updated 2023.06.19
|
||||
|
||||
@@ -19,7 +32,6 @@ updated 2023.06.19
|
||||
- 修复:部门管理查询空指针问题
|
||||
- 优化:附件md5生成方式调整(与更新前已上传的文件md5不兼容,如果业务有影响请注意调整)
|
||||
|
||||
|
||||
### v2.7.3
|
||||
updated 2023.05.14
|
||||
|
||||
|
||||
@@ -5,9 +5,11 @@
|
||||
- 使用条件
|
||||
- 生成配置
|
||||
- 一个生成增删改查列表例子
|
||||
- 内置gf-cli
|
||||
- 多数据库生成配置
|
||||
- 自定义生成模板
|
||||
- 内置gf-cli
|
||||
- 指定gf-cli版本
|
||||
- 指定数据库驱动类型
|
||||
|
||||
|
||||
> 在HotGo中可以通过后台开发工具快速的一键生成CRUD,自动生成Api、控制器、业务逻辑、Web页面、表单组件、菜单权限等。
|
||||
@@ -263,13 +265,6 @@ INSERT INTO `hg_test_table` (`id`, `category_id`, `title`, `description`, `conte
|
||||
|
||||
|
||||
|
||||
### 内置gf-cli
|
||||
|
||||
> 由于gf版本更新较常出现向下不兼容的情况,所以我们为了保证生成代码的依赖稳定性,我们将gf-cli工具内置到了系统中并做了一些在线执行的调整。
|
||||
|
||||
- 后续我们也将开放在线运行`gf gen dao`、`gf gen service`功能。在做插件开发时也会支持到在线生成插件下的service接口,这将会使得插件开发更加方便
|
||||
|
||||
|
||||
## 多数据库生成配置
|
||||
|
||||
#### 假设我们要增加一个库名为`hotgo2`、分组为`default2`的数据库,并要为其生成代码
|
||||
@@ -339,3 +334,53 @@ hggen:
|
||||
|
||||
- 如果你在实际的开发过程中默认模板需要调整的地方较多时,HotGo允许你新建新的模板分组来满足你的需求。新的模板可根据现有模板基础拷贝一份出来做改造,默认模板目录:[server/resource/generate/default](../../server/resource/generate/default)
|
||||
|
||||
|
||||
|
||||
### 内置gf-cli
|
||||
|
||||
> 为了确保生成代码的依赖稳定性,在面对`gf`版本更新可能导致向下不兼容情况时,HotGo将`gf-cli`工具内置到系统中并进行在线执行调整,从而提供更可靠和一致的生成代码功能。
|
||||
|
||||
- 后续我们也将开放在线运行`gf gen ...`功能。在做插件开发时也会支持到在线生成插件下的service接口,这将会使得插件开发更加方便
|
||||
|
||||
|
||||
|
||||
### 指定gf-cli版本
|
||||
|
||||
> HotGo多数情况下会和最新版本的gf-cli保持同步,如果更新不及时或你不想使用最新版本的gf-cli来生成代码,可以找到自己想要的版本进行替换即可。
|
||||
|
||||
- 下面大致做一些替换步骤说明:
|
||||
|
||||
1. 打开https://github.com/gogf/gf,找到你想要使用的版本`clone`下来
|
||||
2. 将`clone`代码中`gf/cmd/gf/internal/`目录覆盖到`server/internal/library/hggen/internal`
|
||||
3. 将覆盖过来的目录文件中引入包名`github.com/gogf/gf/cmd/gf/v2/`批量改为`hotgo/internal/library/hggen/`
|
||||
4. 运行`go mod tidy`
|
||||
5. 运行`go run main.go`,如果没有报错,那么恭喜你已经完成了。如果有报错一般都是版本差异带来的影响,需要根据情况自行调整
|
||||
|
||||
|
||||
|
||||
### 指定数据库驱动类型
|
||||
|
||||
> HotGo默认使用mysql驱动,如果你想用其他数据库驱动打开下方文件中注释即可
|
||||
|
||||
修改文件路径:server/internal/library/hggen/internal/cmd/cmd_gen_dao.go
|
||||
```go
|
||||
package cmd
|
||||
|
||||
import (
|
||||
//_ "github.com/gogf/gf/contrib/drivers/clickhouse/v2"
|
||||
//_ "github.com/gogf/gf/contrib/drivers/mssql/v2"
|
||||
_ "github.com/gogf/gf/contrib/drivers/mysql/v2"
|
||||
//_ "github.com/gogf/gf/contrib/drivers/oracle/v2"
|
||||
//_ "github.com/gogf/gf/contrib/drivers/pgsql/v2"
|
||||
//_ "github.com/gogf/gf/contrib/drivers/sqlite/v2"
|
||||
|
||||
"hotgo/internal/library/hggen/internal/cmd/gendao"
|
||||
)
|
||||
|
||||
type (
|
||||
cGenDao = gendao.CGenDao
|
||||
)
|
||||
|
||||
```
|
||||
|
||||
修改完成后运行`go mod tidy`
|
||||
|
||||
71
docs/guide-zh-CN/sys-cron.md
Normal file
71
docs/guide-zh-CN/sys-cron.md
Normal file
@@ -0,0 +1,71 @@
|
||||
## 定时任务
|
||||
|
||||
目录
|
||||
|
||||
- 实现接口
|
||||
- 一个例子
|
||||
- 更多
|
||||
|
||||
> 在实际的项目开发中,定时任务几乎成为不可或缺的一部分。HotGo为定时任务提供一个方便的后台操作界面,让您能够轻松地进行在线启停、修改和立即执行等操作。这样的设计可以极大地改善您在使用定时任务过程中的体验,让整个过程更加顺畅、高效。
|
||||
|
||||
|
||||
### 实现接口
|
||||
- 为了提供高度的扩展性,定时任务在设计上采用了接口化的思路。只需要实现以下接口,您就可以在任何地方注册和使用定时任务功能,从而实现更大的灵活性和可扩展性。
|
||||
|
||||
```go
|
||||
// Cron 定时任务接口
|
||||
type Cron interface {
|
||||
// GetName 获取任务名称
|
||||
GetName() string
|
||||
// Execute 执行一次任务
|
||||
Execute(ctx context.Context)
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### 一个例子
|
||||
|
||||
定时任务的文件结构可以根据具体需要进行调整,以下是一个常见的参考结构:
|
||||
|
||||
- 文件路径:server/internal/crons/test.go
|
||||
|
||||
```go
|
||||
package crons
|
||||
|
||||
import (
|
||||
"context"
|
||||
"hotgo/internal/library/cron"
|
||||
"time"
|
||||
)
|
||||
|
||||
func init() {
|
||||
cron.Register(Test)
|
||||
}
|
||||
|
||||
// Test 测试任务(无参数)
|
||||
var Test = &cTest{name: "test"}
|
||||
|
||||
type cTest struct {
|
||||
name string
|
||||
}
|
||||
|
||||
func (c *cTest) GetName() string {
|
||||
return c.name
|
||||
}
|
||||
|
||||
// Execute 执行任务
|
||||
func (c *cTest) Execute(ctx context.Context) {
|
||||
cron.Logger().Infof(ctx, "cron test Execute:%v", time.Now())
|
||||
}
|
||||
|
||||
|
||||
```
|
||||
|
||||
继续在后台系统设置-定时任务-添加任务,填写的任务名称需要和上面的名称保持一致,再进行简单的策略配置以后,一个后台可控的定时任务就添加好了!
|
||||
|
||||
|
||||
### 更多
|
||||
|
||||
定时任务源码路径:server/internal/library/cron/cron.go
|
||||
|
||||
更多文档请参考:https://goframe.org/pages/viewpage.action?pageId=1114187
|
||||
@@ -33,6 +33,9 @@ func main() {
|
||||
|
||||
// 演示系統操作限制,当开启演示模式时,所有POST请求将被拒绝
|
||||
service.Middleware().DemoLimit()
|
||||
|
||||
// 请求输入预处理,api使用gf规范路由并且XxxReq结构体实现了validate.Filter接口即可隐式预处理
|
||||
service.Middleware().PreFilter()
|
||||
|
||||
// HTTP响应预处理,在业务处理完成后,对响应结果进行格式化和错误过滤,将处理后的数据发送给请求方
|
||||
service.Middleware().ResponseHandler()
|
||||
@@ -143,7 +146,6 @@ func main() {
|
||||
2. 在`server/internal/logic/middleware/response.go`中根据请求的独有特征进行单独的处理,兼容后续http处理。
|
||||
|
||||
|
||||
|
||||
#### 重写响应错误提示
|
||||
|
||||
- 在实际开发中,我们可能想要隐藏一些敏感错误,返回给客户端友好的错误提示,但开发者同时又想需要看到真实的敏感错误。对此hotgo已经进行了过滤处理,下面是一个简单的例子:
|
||||
|
||||
271
docs/guide-zh-CN/sys-tcp-server.md
Normal file
271
docs/guide-zh-CN/sys-tcp-server.md
Normal file
@@ -0,0 +1,271 @@
|
||||
## TCP服务器
|
||||
|
||||
目录
|
||||
|
||||
- 配置文件
|
||||
- 一个基本的消息收发例子
|
||||
- 注册路由
|
||||
- 拦截器
|
||||
- 服务认证
|
||||
- 更多
|
||||
|
||||
> HotGo基于GF框架的TCP服务器组件,提供了一个简单而灵活的方式快速搭建基于TCP的服务应用。集成了许多常用功能,如长连接、服务认证、路由分发、RPC消息、拦截器和数据绑定等,大大简化和规范了服务器开发流程。
|
||||
|
||||
### 配置文件
|
||||
- 配置文件:server/manifest/config/config.yaml
|
||||
|
||||
```yaml
|
||||
tcp:
|
||||
# 服务器
|
||||
server:
|
||||
address: ":8099"
|
||||
# 客户端
|
||||
client:
|
||||
# 定时任务
|
||||
cron:
|
||||
group: "cron" # 分组名称
|
||||
name: "cron1" # 客户端名称
|
||||
address: "127.0.0.1:8099" # 服务器地址
|
||||
appId: "1002" # 应用名称
|
||||
secretKey: "hotgo" # 密钥
|
||||
# 系统授权
|
||||
auth:
|
||||
group: "auth" # 分组名称
|
||||
name: "auth1" # 客户端名称
|
||||
address: "127.0.0.1:8099" # 服务器地址
|
||||
appId: "mengshuai" # 应用名称
|
||||
secretKey: "123456" # 密钥
|
||||
|
||||
```
|
||||
- 可以看到,除了服务器配置外,还有两个客户端配置`cron` 和`auth`
|
||||
- `cron`是HotGo内置的定时任务服务,和http服务通过RPC通讯以实现和后台交互,使其可以独立、集群部署。
|
||||
- `auth`可以为第三方平台提供授权服务。如果你需要他,可以将它部署在第三方程序中,在重要的位置进行授权验证。
|
||||
|
||||
### 一个基本的消息收发测试用例
|
||||
|
||||
- 文件路径:server/internal/library/network/tcp/tcp_example_test.go
|
||||
|
||||
```go
|
||||
package tcp_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/gogf/gf/v2/os/gctx"
|
||||
"github.com/gogf/gf/v2/test/gtest"
|
||||
"hotgo/internal/library/network/tcp"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
var T *testing.T // 声明一个全局的 *testing.T 变量
|
||||
|
||||
type TestMsgReq struct {
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
type TestMsgRes struct {
|
||||
tcp.ServerRes
|
||||
}
|
||||
|
||||
type TestRPCMsgReq struct {
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
type TestRPCMsgRes struct {
|
||||
tcp.ServerRes
|
||||
}
|
||||
|
||||
func onTestMsg(ctx context.Context, req *TestMsgReq) {
|
||||
fmt.Printf("服务器收到消息 ==> onTestMsg:%+v\n", req)
|
||||
conn := tcp.ConnFromCtx(ctx)
|
||||
gtest.C(T, func(t *gtest.T) {
|
||||
t.AssertNE(conn, nil)
|
||||
})
|
||||
|
||||
res := new(TestMsgRes)
|
||||
res.Message = fmt.Sprintf("你的名字:%v", req.Name)
|
||||
conn.Send(ctx, res)
|
||||
}
|
||||
|
||||
func onResponseTestMsg(ctx context.Context, req *TestMsgRes) {
|
||||
fmt.Printf("客户端收到响应消息 ==> TestMsgRes:%+v\n", req)
|
||||
err := req.GetError()
|
||||
gtest.C(T, func(t *gtest.T) {
|
||||
t.AssertNil(err)
|
||||
})
|
||||
}
|
||||
|
||||
func onTestRPCMsg(ctx context.Context, req *TestRPCMsgReq) (res *TestRPCMsgRes, err error) {
|
||||
fmt.Printf("服务器收到消息 ==> onTestRPCMsg:%+v\n", req)
|
||||
res = new(TestRPCMsgRes)
|
||||
res.Message = fmt.Sprintf("你的名字:%v", req.Name)
|
||||
return
|
||||
}
|
||||
|
||||
func startTCPServer() {
|
||||
serv := tcp.NewServer(&tcp.ServerConfig{
|
||||
Name: "hotgo",
|
||||
Addr: ":8002",
|
||||
})
|
||||
|
||||
// 注册路由
|
||||
serv.RegisterRouter(
|
||||
onTestMsg,
|
||||
)
|
||||
|
||||
// 注册RPC路由
|
||||
serv.RegisterRPCRouter(
|
||||
onTestRPCMsg,
|
||||
)
|
||||
|
||||
// 服务监听
|
||||
err := serv.Listen()
|
||||
gtest.C(T, func(t *gtest.T) {
|
||||
t.AssertNil(err)
|
||||
})
|
||||
}
|
||||
|
||||
// 一个基本的消息收发
|
||||
func TestSendMsg(t *testing.T) {
|
||||
T = t
|
||||
go startTCPServer()
|
||||
|
||||
ctx := gctx.New()
|
||||
client := tcp.NewClient(&tcp.ClientConfig{
|
||||
Addr: "127.0.0.1:8002",
|
||||
})
|
||||
|
||||
// 注册路由
|
||||
client.RegisterRouter(
|
||||
onResponseTestMsg,
|
||||
)
|
||||
|
||||
go func() {
|
||||
err := client.Start()
|
||||
gtest.C(T, func(t *gtest.T) {
|
||||
t.AssertNil(err)
|
||||
})
|
||||
}()
|
||||
|
||||
// 确保服务都启动完成
|
||||
time.Sleep(time.Second * 1)
|
||||
|
||||
// 拿到客户端的连接
|
||||
conn := client.Conn()
|
||||
gtest.C(T, func(t *gtest.T) {
|
||||
t.AssertNE(conn, nil)
|
||||
})
|
||||
|
||||
// 向服务器发送tcp消息,不会阻塞程序执行
|
||||
err := conn.Send(ctx, &TestMsgReq{Name: "Tom"})
|
||||
gtest.C(T, func(t *gtest.T) {
|
||||
t.AssertNil(err)
|
||||
})
|
||||
|
||||
// 向服务器发送rpc消息,会等待服务器响应结果,直到拿到结果或响应超时才会继续
|
||||
var res TestRPCMsgRes
|
||||
if err = conn.RequestScan(ctx, &TestRPCMsgReq{Name: "Tony"}, &res); err != nil {
|
||||
gtest.C(T, func(t *gtest.T) {
|
||||
t.AssertNil(err)
|
||||
})
|
||||
}
|
||||
|
||||
fmt.Printf("客户端收到RPC消息响应 ==> TestRPCMsgRes:%+v\n", res)
|
||||
time.Sleep(time.Second * 1)
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
|
||||
### 注册路由
|
||||
|
||||
- 从上面的例子可以看到,不管是普通TCP消息和RPC消息的请求/响应结构体都采用类似GF框架的规范路由的结构,请求`XxxRes`/响应`XxxRes`的格式,是不是很亲切?
|
||||
|
||||
|
||||
### 拦截器
|
||||
|
||||
- 不管是服务端还是客户端,在初始化时都可以注册多个拦截器来满足更多场景的服务开发,下面是一个使用例子:
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"hotgo/internal/library/network/tcp"
|
||||
)
|
||||
|
||||
func main() {
|
||||
serv = tcp.NewServer(&tcp.ServerConfig{
|
||||
Name: "hotgo",
|
||||
Addr: ":8002",
|
||||
})
|
||||
|
||||
// 注册拦截器
|
||||
// 执行顺序是从前到后,即Interceptor -> Interceptor2 -> Interceptor3。如果中间有任意一个抛出错误,则会中断后续处理
|
||||
serv.RegisterInterceptor(Interceptor, Interceptor2, Interceptor3)
|
||||
|
||||
// 服务监听
|
||||
if err := serv.Listen(); err != nil {
|
||||
if !serv.IsClose() {
|
||||
g.Log().Warningf(ctx, "TCPServer Listen err:%v", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func Interceptor(ctx context.Context, msg *tcp.Message) (err error) {
|
||||
// 可以在拦截器中通过上下文拿到连接
|
||||
conn := tcp.ConnFromCtx(ctx)
|
||||
|
||||
// 拿到原始请求消息
|
||||
g.Dump(msg)
|
||||
|
||||
// 如果想要中断后续处理只需返回一个错误即可,但注意两种情况
|
||||
// tcp消息:如果你还想对该消息进行回复应在拦截器中进行处理,例如:conn.Send(ctx, 回复消息内容)
|
||||
// rpc消息:返回一个错误后系统会将错误自动回复到rpc响应中,无需单独处理
|
||||
return
|
||||
}
|
||||
|
||||
func Interceptor2(ctx context.Context, msg *tcp.Message) (err error) {
|
||||
// ...
|
||||
return
|
||||
}
|
||||
|
||||
func Interceptor3(ctx context.Context, msg *tcp.Message) (err error) {
|
||||
// ...
|
||||
return
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
|
||||
### 服务认证
|
||||
|
||||
- 一般情况下,建议客户端连接到服务器时都通过`授权许可证`的方式进行登录认证,当初始化客户端配置认证数据时,连接成功后会自动进行登录认证。
|
||||
|
||||
```go
|
||||
// 创建客户端配置
|
||||
clientConfig := &tcp.ClientConfig{
|
||||
Addr: "127.0.0.1:8002",
|
||||
AutoReconnect: true,
|
||||
// 认证数据
|
||||
// 认证数据可以在后台-系统监控-在线服务-许可证列表中添加,同一个授权支持多个服务使用,但多个服务不能使用相同的名称进行连接
|
||||
Auth: &tcp.AuthMeta{
|
||||
Name: "服务名称",
|
||||
Group: "服务分组",
|
||||
AppId: "APPID",
|
||||
SecretKey: "SecretKey",
|
||||
},
|
||||
}
|
||||
|
||||
// 初始化客户端
|
||||
client = tcp.NewClient(clientConfig)
|
||||
```
|
||||
|
||||
|
||||
### 更多
|
||||
|
||||
TCP服务器源码路径:server/internal/library/network/tcp
|
||||
|
||||
更多文档请参考:https://goframe.org/pages/viewpage.action?pageId=1114625
|
||||
3
docs/guide-zh-CN/sys-test.md
Normal file
3
docs/guide-zh-CN/sys-test.md
Normal file
@@ -0,0 +1,3 @@
|
||||
## 单元测试
|
||||
|
||||
请参考:https://goframe.org/pages/viewpage.action?pageId=1114153
|
||||
20
docs/guide-zh-CN/sys-utility.md
Normal file
20
docs/guide-zh-CN/sys-utility.md
Normal file
@@ -0,0 +1,20 @@
|
||||
## 工具方法
|
||||
|
||||
HotGo还提供一些系统中常用的工具库方法,在这里简单说明:
|
||||
|
||||
```
|
||||
/server
|
||||
├── utility
|
||||
│ ├── charset # 字符串处理
|
||||
│ ├── convert # 数据类型转换
|
||||
│ ├── encrypt # 数据加密/解密
|
||||
│ ├── excel # 电子表格导出/导入
|
||||
│ ├── file # 文件/目录处理
|
||||
│ ├── format # 数据格式化
|
||||
│ ├── simple # 一些简捷函数
|
||||
│ ├── tree # 树形结构
|
||||
│ ├── url # URL处理
|
||||
│ ├── useragent # 请求头代理处理
|
||||
└── └── validate # 数据验证
|
||||
```
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
- 多图上传 UploadImage
|
||||
- 单文件上传 UploadFile
|
||||
- 多文件上传 UploadFile
|
||||
- 文件选择器 FileChooser
|
||||
- 开关 Switch
|
||||
- 评分 Rate
|
||||
- 省市区选择器 CitySelector
|
||||
@@ -765,6 +766,35 @@ const value = ref(null);
|
||||
</script>
|
||||
```
|
||||
|
||||
### 文件选择器 FileChooser
|
||||
- 基础用法
|
||||
```vue
|
||||
<template>
|
||||
<FileChooser v-model:value="value" />
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref } from 'vue'
|
||||
import FileChooser from '@/components/FileChooser/index.vue';
|
||||
const value = ref(null);
|
||||
</script>
|
||||
```
|
||||
|
||||
- 指定fileType,支持多种选择器类型,默认情况是全部都可以选择
|
||||
```ts
|
||||
type FileType = 'image' | 'doc' | 'audio' | 'video' | 'zip' | 'other' | 'default';
|
||||
```
|
||||
|
||||
- 图片选择器
|
||||
```vue
|
||||
<FileChooser v-model:value="value" fileType="image" />
|
||||
```
|
||||
|
||||
- 多选支持,指定`maxNumber`多选数量
|
||||
```vue
|
||||
<FileChooser v-model:value="value" :maxNumber="10" fileType="image" />
|
||||
```
|
||||
|
||||
### 开关 Switch
|
||||
```vue
|
||||
<template>
|
||||
|
||||
Reference in New Issue
Block a user