在这篇文章中,我们将为您详细介绍antd+dva笔记的内容,并且讨论关于antddva的相关问题。此外,我们还会涉及一些关于AntDesignPro(React/dva/antd)、antd中@umi
在这篇文章中,我们将为您详细介绍antd+dva笔记的内容,并且讨论关于antd dva的相关问题。此外,我们还会涉及一些关于Ant Design Pro(React/dva/antd)、antd 中 @umijs/plugin-dva 如何使用?、antdv Spin组件拓展、antdv 引入 svg的知识,以帮助您更全面地了解这个主题。
本文目录一览:- antd+dva笔记(antd dva)
- Ant Design Pro(React/dva/antd)
- antd 中 @umijs/plugin-dva 如何使用?
- antdv Spin组件拓展
- antdv 引入 svg
antd+dva笔记(antd dva)
参考
React中函数式声明组件
Dva + Ant Design 前后端分离之 React 应用实践
React+DvaJS 之 hook 路由权限控制
dva 知识地图
react-router Guides and API docs (v2,v3)
react-sage
redux-saga 是一个用于管理 Redux 应用异步操作,可以用来代替 redux-thunk 中间件。
《Redux-saga 中文文档》
需要提前做一个学习,不然model里面估计不太看得懂
其作用和redux-thunk
差不多,可以用来替代redux-thunk
Sagas 是通过 Generator 函数来创建的,就是这货funciton* xxx()
阮一峰《ECMAScript 6 入门》之Generator 函数的语法
手动删除model后的无法找到文件的错误
通过dva g model test的,手动将这个models/test.js文件删除掉,会报这个错。
Error in ./src/index.js Module not found: [CaseSensitivePathsPlugin] `/Users/Grea/Workspace/grea/kuaidi-ui/src/models/post.js` does not match the corresponding path on disk - File does not exist.
【解决方法】
尝试执行 rm -r node_modules/.cache/babel-loader
再执行 npm start
issues:https://github.com/dvajs/dva/...
Ant Design Pro(React/dva/antd)
Ant Design Pro 是一个企业级中后台前端/设计解决方案。本地环境需要安装 node 和 git,技术栈基于 ES2015+、React、dva、g2 和 antd。
参考:https://dvajs.com/
https://github.com/ant-design/ant-design-pro/blob/master/README.zh-CN.md
https://pro.ant.design/docs/getting-started-cn
1、预备知识
1)Redux 是 JavaScript 状态容器,提供可预测化的状态管理;Redux 除了和 React 一起用外,还支持其它界面库。
connect([mapStateToProps], [mapDispatchToProps], [mergeProps], [options]):
连接 React 组件与 Redux store。
[mapStateToProps(state, [ownProps]): stateProps
] (Function): 如果定义该参数,组件将会监听 Redux store 的变化。任何时候,只要 Redux store 发生改变,mapStateToProps
函数就会被调用。该回调函数必须返回一个纯对象,这个对象会与组件的 props 合并。
-
函数将被调用两次。第一次是设置参数,第二次是组件与 Redux store 连接:
connect(mapStateToProps, mapDispatchToProps, mergeProps)(MyComponent)
。 -
connect 函数不会修改传入的 React 组件,返回的是一个新的已与 Redux store 连接的组件,而且你应该使用这个新组件。
-
mapStateToProps
函数接收整个 Redux store 的 state 作为 props,然后返回一个传入到组件 props 的对象。
注入 dispatch
和 todos
function mapStateToProps(state) {
return { todos: state.todos }
}
export default connect(mapStateToProps)(TodoApp)
// 注入 dispatch 和全局 state
export default connect(state => state)(TodoApp)
// 不要这样做!这会导致每次 action 都触发整个 TodoApp 重新渲染
// 最好在多个组件上使用 connect(),每个组件只监听它所关联的部分 state。
Action 是把数据从应用(这里之所以不叫 view 是因为这些数据有可能是服务器响应,用户输入或其它非 view 的数据 )传到 store 的有效载荷。它是 store 数据的唯一来源。一般来说你会通过 store.dispatch()
将 action 传到 store。
Action 本质上是 JavaScript 普通对象。我们约定,action 内必须使用一个字符串类型的 type
字段来表示将要执行的动作。
2)redux-saga
是一个 redux 中间件,意味着这个线程可以通过正常的 redux action 从主应用程序启动,暂停和取消,它能访问完整的 redux state,也可以 dispatch redux action。
redux-saga 使用了 ES6 的 Generator 功能,让异步的流程更易于读取,写入和测试。通过这样的方式,这些异步的流程看起来就像是标准同步的 Javascript 代码。
effects: {
*create({ payload: values }, { call, put }) {
yield call(usersService.create, values);
yield put({ type: ''reload'' });
},
*reload(action, { put, select }) {
const page = yield select(state => state.users.page);
yield put({ type: ''fetch'', payload: { page } });
},
}
call(fn, ...args)
创建一个 Effect 描述信息,用来命令 middleware 以参数 args
调用函数 fn
。
fn: Function
- 一个 Generator 函数, 也可以是一个返回 Promise 或任意其它值的普通函数。args: Array<any>
- 传递给fn
的参数数组。
put(action)
创建一个 Effect 描述信息,用来命令 middleware 向 Store 发起一个 action。 这个 effect 是非阻塞型的,并且所有向下游抛出的错误(例如在 reducer 中),都不会冒泡回到 saga 当中。
select(selector, ...args)
创建一个 Effect,用来命令 middleware 在当前 Store 的 state 上调用指定的选择器。
-
selector: Function
- 一个(state, ...args) => args
的函数。它接受当前 state 和一些可选参数,并返回当前 Store state 上的一部分数据。
2、dva 首先是一个基于 redux 和 redux-saga 的数据流方案,然后为了简化开发体验,dva 还额外内置了 react-router 和 fetch,所以也可以理解为一个轻量级的应用框架。
dva 是基于现有应用架构 (redux + react-router + redux-saga 等)的一层轻量封装,没有引入任何新概念。dva 帮你自动化了Redux 架构一些繁琐的步骤,比如redux store 的创建,中间件的配置,路由的初始化等等,只需写几行代码就可以实现上述步骤。
1)使用 antd
通过 npm 安装 antd
和 babel-plugin-import
,babel-plugin-import
是用来按需加载 antd 的脚本和样式的;编辑 .webpackrc
,使 babel-plugin-import
插件生效。
// .webpackrc.js
extraBabelPlugins: [[''import'', { libraryName: ''antd'', libraryDirectory: ''es'', style: true }]]
2)dva应用
// src/index.js 入口js
import dva from ''dva'';
import browserHistory from ''history/createBrowserHistory'';
import createLoading from ''dva-loading'';
// 1. Initialize
const app = dva({
history: browserHistory(),
});
// 2. Plugins
app.use(createLoading());
// 3. Model
app.model(require(''./models/global'').default);
app.model(require(''./models/menu'').default);
// 4. Router
app.router(require(''./router'').default);
// 5. Start
app.start(''#root''); // 启动应用
app = dva(opts)-》
创建应用,返回 dva 实例。(注:dva 支持多实例)
opts
包含:
history
:指定给路由用的 history,默认是hashHistory
2)定义路由
app.router(({ history, app }) => RouterConfig)
注册路由表,推荐把路由信息抽成一个单独的文件,这样结合 babel-plugin-dva-hmr 可实现路由和组件的热加载(只更新页面修改的部分,不会刷新整个页面)。
// .webpackrc.js
env: {
development: {
extraBabelPlugins: [''dva-hmr''],
},
},
3)定义 Model(处理数据和逻辑)
dva 通过 model 的概念把一个领域的模型管理起来,包含同步更新 state 的 reducers,处理异步逻辑的 effects,订阅数据源的 subscriptions 。
import * as usersService from ''../services/users'';
export default {
namespace: ''users'',
state: {
list: [],
total: null,
page: null,
},
reducers: {
save(state, { payload: { data: list, total, page } }) {
return { ...state, list, total, page };
},
},
effects: {
*fetch({ payload: { page = 1 } }, { call, put }) {
const { data, headers } = yield call(usersService.fetch, { page });
yield put({
type: ''save'',
payload: {
data,
total: parseInt(headers[''x-total-count''], 10),
page: parseInt(page, 10),
},
});
},
*remove({ payload: id }, { call, put }) {
yield call(usersService.remove, id);
yield put({ type: ''reload'' });
},*reload(action, { put, select }) {
const page = yield select(state => state.users.page);
yield put({ type: ''fetch'', payload: { page } });
},
},
subscriptions: {
setup({ dispatch, history }) {
return history.listen(({ pathname, query }) => {
if (pathname === ''/users'') {
dispatch({ type: ''fetch'', payload: query });
}
});
},
},
};
namespace:model 的命名空间,同时也是他在全局 state 上的属性
state:初始值
reducers:以 key/value 格式定义 reducer。用于处理同步操作,唯一可以修改 state
的地方。由 action
触发
effects:以 key/value 格式定义 effect。用于处理异步操作和业务逻辑,不直接修改 state
。由 action
触发,可以触发 action
,可以和服务器交互,可以获取全局 state
的数据等等。
subscriptions:以 key/value 格式定义 subscription。subscription 是订阅,用于订阅一个数据源,然后根据需要 dispatch 相应的 action。在 app.start()
时被执行,数据源可以是当前的时间、服务器的 websocket 连接、keyboard 输入、geolocation 变化、history 路由变化等等。
app.model(model)-》
注册 model
4)编写UI Component并connect起来
import React from ''react'';
import { connect } from ''dva'';
import { Table, Pagination, Popconfirm, Button } from ''antd'';
import { routerRedux } from ''dva/router'';
import styles from ''./Users.css'';
import { PAGE_SIZE } from ''../../../../constants'';
import UserModal from ''./UserModal'';
function Users({ dispatch, list: dataSource, loading, total, page: current }) {
function deleteHandler(id) {
dispatch({
type: ''users/remove'',
payload: id,
});
}
function pageChangeHandler(page) {
dispatch(
routerRedux.push({
pathname: ''/users'',
query: { page },
})
);
}
const columns = [
{
title: ''Username'',
dataIndex: ''username'',
key: ''username'',
render: text => <a href="">{text}</a>,
},
{
title: ''Street'',
dataIndex: ''address.street'',
key: ''street'',
},
{
title: ''Website'',
dataIndex: ''website'',
key: ''website'',
},
{
title: ''Operation'',
key: ''operation'',
render: (text, record) => (
<span className={styles.operation}>
<Popconfirm title="Confirm to delete?" onConfirm={deleteHandler.bind(null, record.id)}>
<a href="">Delete</a>
</Popconfirm>
</span>
),
},
];
return (
<div className={styles.normal}>
<div>
<Table
columns={columns}
dataSource={dataSource}
loading={loading}
rowKey={record => record.id}
pagination={false}
/>
<Pagination
className="ant-table-pagination"
total={total}
current={current}
pageSize={PAGE_SIZE}
onChange={pageChangeHandler}
/>
</div>
</div>
);
}
function mapStateToProps(state) {
const { list, total, page } = state.users;
return {
loading: state.loading.models.users,
list,
total,
page,
};
}
export default connect(mapStateToProps)(Users);
5)相关概念
dva 提供了 connect 方法,这个 connect 就是 react-redux 的 connect 。 connect 方法返回的也是一个 React 组件,通常称为容器组件。因为它是原始 UI 组件的容器,即在外面包了一层 State。connect 方法传入的第一个参数是 mapStateToProps 函数,mapStateToProps 函数会返回一个对象,用于建立 State 到 Props 的映射关系。
数据的改变发生通常是通过用户交互行为或者浏览器行为(如路由跳转等)触发的,当此类行为会改变数据的时候可以通过 dispatch
发起一个 action,如果是同步行为会直接通过 Reducers
改变 State
,如果是异步行为(副作用)会先触发 Effects
然后流向 Reducers
最终改变 State。
Model 对象的属性
- namespace: 当前 Model 的名称。整个应用的 State,由多个小的 Model 的 State 以 namespace 为 key 合成
- state: 该 Model 当前的状态。数据保存在这里,直接决定了视图层的输出
- reducers: Action 处理器,处理同步动作,用来算出最新的 State
- effects:Action 处理器,处理异步动作
Action 是一个普通 javascript 对象,它是改变 State 的唯一途径。无论是从 UI 事件、网络回调,还是 WebSocket 等数据源所获得的数据,最终都会通过 dispatch 函数调用一个 action,从而改变对应的数据。action 必须带有 type
属性指明具体的行为,其它字段可以自定义,如果要发起一个 action 需要使用 dispatch
函数;需要注意的是 dispatch
是在组件 connect Models以后,通过 props 传入的。在 dva 中,connect Model 的组件通过 props 可以访问到 dispatch,可以调用 Model 中的 Reducer 或者 Effects
dispatch({
type: ''user/add'', // 如果在 model 外调用,需要添加 namespace
payload: {}, // 需要传递的信息
});
Reducer函数接受两个参数:之前已经累积运算的结果和当前要被累积的值,返回的是一个新的累积结果。在 dva 中,reducers 聚合积累的结果是当前 model 的 state 对象。通过 actions 中传入的值,与当前 reducers 中的值进行运算获得新的值(也就是新的 state)。
state: {
list: [],
total: null,
page: null,
},
reducers: {
save(state, { payload: { data: list, total, page } }) {
return { ...state, list, total, page };
},
}
Effect:Action 处理器,处理异步动作,基于 Redux-saga 实现。Effect 指的是副作用。根据函数式编程,计算以外的操作都属于 Effect,典型的就是 I/O 操作、数据库读写。
dva 提供多个 effect 函数内部的处理函数,比较常用的是 call
和 put
。
- call:执行异步函数
- put:发出一个 Action,类似于 dispatch
effects: {
*create({ payload: values }, { call, put }) {
yield call(usersService.create, values);
yield put({ type: ''reload'' });
},
*reload(action, { put, select }) {
const page = yield select(state => state.users.page);
yield put({ type: ''fetch'', payload: { page } });
},
}
Router:这里的路由通常指的是前端路由,由于我们的应用现在通常是单页应用,所以需要前端代码来控制路由逻辑,通过浏览器提供的 History API 可以监听浏览器url的变化,从而控制路由相关操作。
dva 实例提供了 router 方法来控制路由,使用的是react-router。
在组件设计方法中,我们提到过 Container Components,在 dva 中我们通常将其约束为 Route Components,因为在 dva 中我们通常以页面维度来设计 Container Components。
所以在 dva 中,通常需要 connect Model的组件都是 Route Components,组织在/routes/
目录下,而/components/
目录下则是纯组件。
组件设计
React 应用是由一个个独立的 Component 组成的,我们在拆分 Component 的过程中要尽量让每个 Component 专注做自己的事。
一般来说,我们的组件有两种设计:Container Component、Presentational Component
- Container Component
Container Component 一般指的是具有监听数据行为
的组件,一般来说它们的职责是绑定相关联的 model 数据
,以数据容器的角色包含其它子组件。
- Presentational Component
它不会关联订阅 model 上的数据,而所需数据的传递则是通过 props 传递到组件内部。
对组件分类,主要有两个好处:让项目的数据处理更加集中;让组件高内聚低耦合,更加聚焦;
试想如果每个组件都去订阅数据 model,那么一方面组件本身跟 model 耦合太多,另一方面代码过于零散,到处都在操作数据,会带来后期维护的烦恼。
除了写法上订阅数据的区别以外,在设计思路上两个组件也有很大不同。 Presentational Component
是独立的纯粹的,可以参考 ant.design UI组件的React实现 ,每个组件跟业务数据并没有耦合关系,只是完成自己独立的任务,需要的数据通过 props
传递进来,需要操作的行为通过接口暴露出去。 而 Container Component
更像是状态管理器,它表现为一个容器,订阅子组件需要的数据,组织子组件的交互逻辑和展示。
3、其它
1)roadhog-》和 webpack 相似的库,起的是 webpack 自动打包和热更替的作用
roadhog 是一个 cli 工具,提供 dev、 build
和 test
三个命令,分别用于本地调试、构建和测试,并且提供了特别易用的 mock 功能。在体验上,保持了和 create-react-app一致(如 redbox 显示出错信息、HMR、ESLint 出错提示等等),并且提供了 JSON 格式的配置方式。如果 create-react-app 的默认配置不能满足需求,而他又不提供定制的功能,于是基于他实现了一个可配置版。所以如果既要 create-react-app 的优雅体验,又想定制配置,那么可以试试 roadhog 。
## Install globally or locally
$ npm i roadhog -g
## Local development
$ roadhog dev
## Build
$ roadhog build
## Test
$ roadhog test
roadhog dev支持mock, 在.roadhogrc.mock.js里配置
export default {
// Support type as Object and Array
''GET /api/users'': { users: [1,2] },
// Method like GET or POST can be omitted(省略)
''/api/users/1'': { id: 1 },
// Support for custom functions, the API is the same as express@4
''POST /api/users/create'': (req, res) => { res.end(''OK''); },
};
roadhog的webpack部分是基于af-webpack的实现。在项目根目录创建 .webpackrc进行配置,格式是
JSON。
2)react-router-redux和dva
redux 是状态管理的库,router 是(唯一)控制页面跳转的库。两者都很美好,但是不美好的是两者无法协同工作。换句话说,当路由变化以后,store 无法感知到。于是便有了 react-router-redux
。
react-router-redux
是 redux 的一个中间件,主要作用是:加强了React Router库中history这个实例,以允许将history中接受到的变化反应到state中去。
从代码上讲,主要是监听了 history 的变化。dva 在此基础上又进行了一层代理,把代理后的对象当作初始值传递给了 dva-core,方便其在 model 的 subscriptions 中监听 router 变化。
3)dva/fetch-》异步请求库,输出 isomorphic-fetch 的接口。
4)dva-loading
dva 有一个管理 effects 执行的 hook,并基于此封装了 dva-loading 插件。通过这个插件,我们可以不必一遍遍地写 showLoading 和 hideLoading,当发起请求时,插件会自动设置数据里的 loading 状态为 true 或 false 。然后我们在渲染 components 时绑定并根据这个数据进行渲染。
// 1、注册 dva-loading 插件
import dva from ''dva'';
import createLoading from ''dva-loading'';
const app = dva();
app.use(createLoading());
// 2、从store中获取loading状态
import React from ''react'';
import { connect } from ''dva'';
import { Table } from ''antd'';
function Users({ dispatch, list: dataSource, loading }) {
const columns = [
{
title: ''Username'',
dataIndex: ''username'',
key: ''username'',
render: text => <a href="">{text}</a>,
},
{
title: ''Street'',
dataIndex: ''address.street'',
key: ''street'',
},
{
title: ''Website'',
dataIndex: ''website'',
key: ''website'',
}
];
return (
<div className={styles.normal}>
<Table
columns={columns}
dataSource={dataSource}
loading={loading}
rowKey={record => record.id}
pagination={false}
/>
</div>
);
}
function mapStateToProps(state) {
const { list } = state.users;
return {
loading: state.loading.models.users,
list,
};
}
export default connect(mapStateToProps)(Users);
2、项目积累
1)React 中常见模式是为一个组件返回多个元素。为了包裹多个元素我们写过很多的 div 和 span,进行不必要的嵌套,无形中增加了浏览器的渲染压力。
react15版以前,render 函数的返回必须有一个根节点,否则报错,为满足这一原则我会使用一个没有任何样式的 div 包裹一下。
import React from ''react'';
export default function () {
return (
<div>
<div>一步 01</div>
<div>一步 02</div>
<div>一步 03</div>
</div>
);
}
react 16版开始, render支持返回数组,这一特性已经可以减少不必要节点嵌套。
import React from ''react'';
export default function () {
return [
<div>一步 01</div>,
<div>一步 02</div>,
<div>一步 03</div>
];
}
而且,React 16为我们提供了Fragment。Fragment与Vue.js的<template>
功能类似,可做不可见的包裹元素。
import React from ''react'';
export default function () {
return (
<React.Fragment>
<div>一步 01</div>
<div>一步 02</div>
<div>一步 03</div>
</React.Fragment>
);
}
参考:https://segmentfault.com/a/1190000013220508
附录:es6
1)Generator 函数
Generator 函数是 ES6 提供的一种异步编程解决方案,语法行为与传统函数完全不同。
形式上,Generator 函数是一个普通函数,但是有两个特征。一是,function
关键字与函数名之间有一个星号;二是,函数体内部使用yield
表达式,定义不同的内部状态。
Generator 函数有多种理解角度。语法上,首先可以把它理解成,Generator 函数是一个状态机,封装了多个内部状态。执行 Generator 函数会返回一个遍历器对象,也就是说,Generator 函数除了状态机,还是一个遍历器对象生成函数。返回的遍历器对象,可以依次遍历 Generator 函数内部的每一个状态。
function* helloWorldGenerator() {
yield ''hello'';
yield ''world'';
return ''ending'';
}
var hw = helloWorldGenerator();
上面代码定义了一个 Generator 函数helloWorldGenerator
,它内部有两个yield
表达式(hello
和world
),即该函数有三个状态:hello,world 和 return 语句(结束执行)。
然后,Generator 函数的调用方法与普通函数一样,也是在函数名后面加上一对圆括号。不同的是,调用 Generator 函数后,该函数并不执行,返回的也不是函数运行结果,而是一个指向内部状态的指针对象—遍历器对象。
下一步,必须调用遍历器对象的next
方法,使得指针移向下一个状态。也就是说,每次调用next
方法,内部指针就从函数头部或上一次停下来的地方开始执行,直到遇到下一个yield
表达式(或return
语句)为止。换言之,Generator 函数是分段执行的,yield
表达式是暂停执行的标记,而next
方法可以恢复执行。
hw.next() // { value: ''hello'', done: false }
hw.next() // { value: ''world'', done: false }
hw.next() // { value: ''ending'', done: true }
hw.next() // { value: undefined, done: true }
遍历器对象的next
方法的运行逻辑如下。
(1)遇到yield
表达式,就暂停执行后面的操作,并将紧跟在yield
后面的那个表达式的值,作为返回的对象的value
属性值。
(2)下一次调用next
方法时,再继续往下执行,直到遇到下一个yield
表达式。
(3)如果没有再遇到新的yield
表达式,就一直运行到函数结束,直到return
语句为止,并将return
语句后面的表达式的值,作为返回的对象的value
属性值。
(4)如果该函数没有return
语句,则返回的对象的value
属性值为undefined
。
总结一下,调用 Generator 函数,返回一个遍历器对象,代表 Generator 函数的内部指针。以后,每次调用遍历器对象的next
方法,就会返回一个有着value
和done
两个属性的对象。value
属性表示当前的内部状态的值,是yield
表达式后面那个表达式的值;done
属性是一个布尔值,表示是否遍历结束。另外需要注意,yield
表达式只能用在 Generator 函数里面,用在其他地方都会报错。
2)Generator 函数的异步应用
ES6 诞生以前,异步编程的方法,大概有四种:回调函数、事件监听、发布/订阅、Promise 对象。Generator 函数将 JavaScript 异步编程带入了一个全新的阶段。
antd 中 @umijs/plugin-dva 如何使用?
特性概览
- 约定的 model 组织方式
- 文件名即 namespace
- 内置 dva-loading,直接 connect loading 字段使用即可
- 支持 immer,通过配置 immer 开启
约定的 model 组织方式
model 文件
符合以下规则的文件会被认为是 model 文件,
src/models 下的文件 src/pages 下,子目录中 models 目录下的文件 src/pages 下,所有 model.ts 文件
文件校验
默认,上一小节的找到的文件,会做一次校验,校验通过后,才会被添加到最终到 dva model 列表(可配置跳过校验)。
校验示例:
// 通过
export default { namespace: ''foo'' };
export default { reducers: ''foo'' };
// 通过
const model = { namespace: ''foo'' };
export default model;
// 通过,支持 dva-model-extend
import dvaModelExtend from ''dva-model-extend'';
export default dvaModelExtend(baseModel, {
namespace: ''foo'',
});
// 通过
export default <Model>{ namespace: ''foo'' };
// 不通过
export default { foo: ''bar'' };
配置
编译时配置,具体参考链接
export default {
dva: {
immer: true,
hmr: false,
skipModelValidate: false,
},
}
运行时配置
import { createLogger } from ''redux-logger'';
import { message } from ''antd'';
export const dva = {
config: {
onAction: createLogger(),
onError(e: Error) {
message.error(e.message, 3);
},
},
};
类型
通过 umi 导出类型:ConnectRC,ConnectProps,Dispatch,Action,Reducer,ImmerReducer,Effect,Subscription,和所有 model 文件中导出的类型。
示例
查看
antdv Spin组件拓展
antdv 组件库种Spin组件未提供直接的函数式全局调用方法;
在ajax请求,或者其他一些用纯js中需要调用的时候比较麻烦。
基于Spin拓展
util/decorator/spin
import Vue from "vue";
import { Spin } from "ant-design-vue";
let instance = null;
function getInstance() {
if (!instance) {
instance = new Vue({
data: {
show: false,
},
methods: {
loading() {
this.show = true;
},
close() {
this.show = false;
},
},
render(h, data) {
const fullscreenLoading = {
position: "fixed",
left: 0,
top: 0,
width: "100%",
height: "100%",
display: "flex",
justifyContent: "center",
alignItems: "center",
};
return this.show ? (
<div style={fullscreenLoading}>
<Spin />
</div>
) : (
""
);
},
});
const component = instance.$mount();
document.body.appendChild(component.$el);
}
return instance;
}
Spin.show = function () {
getInstance().loading();
};
Spin.hide = function () {
getInstance().close();
};
export default Spin;
antdv 引入 svg
本文目的:用antdv 的a-icon 标签显示svg图标,这样引入的好处是svg样式与a-icon图标样式一致,统一管理
antdv 组件官网icon说明:链接
引入第三方下载的svg图标:Iconfont
vue.config.js中需要配置 vue-svg-icon-loader,这个loader的作用是将svg图标转换成可直接引入(import)的vue组件,配置内容:
chainWebpack: config => {
config.resolve.alias.set(''@$'', resolve(''src''))
const svgRule = config.module.rule(''svg'')
svgRule.uses.clear()
svgRule
.oneOf(''inline'')
.resourceQuery(/inline/)
.use(''vue-svg-icon-loader'')
.loader(''vue-svg-icon-loader'')
.end()
.end()
.oneOf(''external'')
.use(''file-loader'')
.loader(''file-loader'')
.options({
name: ''assets/[name].[hash:8].[ext]''
})
}
vue文件中代码:
import TreeIcon from ''@/assets/icons/tree-right.svg?inline''
export default {
name: ''Hello'',
data () {
return {
TreeIcon
}
},
render () {
return (
<a-icon component={TreeIcon} />
)
}
}
需要注意的是末尾一定要加上?inline
,这样编译器才能按照inline的模式进行编译
今天关于antd+dva笔记和antd dva的介绍到此结束,谢谢您的阅读,有关Ant Design Pro(React/dva/antd)、antd 中 @umijs/plugin-dva 如何使用?、antdv Spin组件拓展、antdv 引入 svg等更多相关知识的信息可以在本站进行查询。
本文标签: