做为一名前端开发人员,掌握vue/react/angular等框架已经是必不可少的技能了,我们都知道,vue或react等MVVM框架提倡组件化开发,这样一方面可以提高组件复用性和可扩展性,另一方面也带来了项目开发的灵活性和可维护,方便多人开发协作.接下来文章将介绍如何使用react,开发一个自定义json编辑器组件.我们这里使用了jsoneditor这个第三方库,官方地址: jsoneditor 通过实现一个json在线编辑器,来学习如何一步步封装自己的组件(不限于react,vue,原理类似).
细河ssl适用于网站、小程序/APP、API接口等需要进行数据传输应用场景,ssl证书未来市场广阔!成为创新互联公司的ssl证书销售渠道,可以享受市场价格4-6折优惠!如果有意向欢迎电话联系或者加微信:028-86922220(备注:SSL证书合作)期待与您的合作!
你将学到:
在介绍组件设计思路之前,有必要介绍一下著名的SOLID原则.
SOLID(单一功能、开闭原则、里氏替换、接口隔离以及依赖反转)是由罗伯特·C·马丁提出的面向对象编程和面向对象设计的五个基本原则。利用这些原则,程序员能更容易和高效的开发一个可维护和扩展的系统。SOLID被典型的应用在测试驱动开发上,并且是敏捷开发以及自适应软件开发的基本原则的重要组成部分。
掌握好这5个原则将有利于我们开发出更优秀的组件,请默默记住.接下来我们来看看json编辑器的设计思路.
如上所示, 和任何一个输入框一样, 参考antd组件设计方式并兼容antd的form表单, 我们提供了onChange方法.(具体细节下文会详细介绍)
首先利用jsoneditor渲染的基本样式以及API,我们能实现一个基本可用的json编辑器,然后通过对外暴露的json和onChange属性进行数据双向绑定, 通过onError来监控异常或者输入的错误, 通过themeBgColor来修改默认的主题色,通过这几个接口,我们便能完全掌握一个组件的运行情况.
接下来我们就正式开始我们的正文.由于本文的组件是基于react实现的,但是用在vue,angular上,基本模式同样适用.关键就是掌握好不同框架的生命周期.
在学习实现json编辑器组件之前,我们有必要了解一下jsoneditor这个第三方组件的用法与api.
安装
我们先执行npm install安装我们的组件
- npm install jsoneditor
其次手动引入样式文件
这样,我们就能使用它的api了:
所以你可能看到如下界面:
为了能实现实时预览和编辑,光这样还远远不够,我们还需要进行额外的处理.我们需要用到jsoneditor其他的api和技巧.
基于以上谈论,我们很容易将编辑器封装成react组件, 我们只需要在componentDidMount生命周期里初始化实例即可.react代码可能是这样的:
- import React, { PureComponent } from 'react'
- import JSONEditor from 'jsoneditor'
- import 'jsoneditor/dist/jsoneditor.css'
- class JsonEditor extends PureComponent {
- initJsonEditor = () => {
- const options = {
- mode: 'code',
- history: true,
- onChange: this.onChange,
- onValidationError: this.onError
- };
- this.jsoneditor = new JSONEditor(this.container, options)
- this.jsoneditor.set(this.props.value)
- }
- componentDidMount () {
- this.initJsonEditor()
- }
- componentWillUnmount () {
- if (this.jsoneditor) {
- this.jsoneditor.destroy()
- }
- }
- render() {
- return
this.container = elem} />- }
- }
- export default JsonEditor
至于options里的选项, 我们可以参考jsoneditor的API文档,里面写的很详细, 通过以上代码,我们便可以实现一个基本的react版的json编辑器组件.接下来我们来按照设计思路一步步实现可实时预览的json编辑器组件.
1.实现预览和编辑视图
其实这一点很好实现,我们只需要实例化2个编辑器实例,一个用于预览,一个用于编辑就好了.
- import React, { PureComponent } from 'react'
- import JSONEditor from 'jsoneditor'
- import 'jsoneditor/dist/jsoneditor.css'
- class JsonEditor extends PureComponent {
- onChange = () => {
- let value = this.jsoneditor.get()
- this.viewJsoneditor.set(value)
- }
- initJsonEditor = () => {
- const options = {
- mode: 'code',
- history: true
- };
- this.jsoneditor = new JSONEditor(this.container, options)
- this.jsoneditor.set(this.props.value)
- }
- initViewJsonEditor = () => {
- const options = {
- mode: 'view'
- };
- this.viewJsoneditor = new JSONEditor(this.viewContainer, options)
- this.viewJsoneditor.set(this.props.value)
- }
- componentDidMount () {
- this.initJsonEditor()
- this.initViewJsonEditor()
- }
- componentDidUpdate() {
- if(this.jsoneditor) {
- this.jsoneditor.update(this.props.value)
- this.viewJsoneditor.update(this.props.value)
- }
- }
- render() {
- return (
this.container = elem} /> this.viewContainer = elem} />- );
- }
- }
- export default JsonEditor
这样,我们便能实现一个初步的可实时预览的编辑器.可能效果长这样:
接近于成熟版,但是还有很多细节要处理.
2.对外暴露属性和方法以支持不同场景的需要
- import React, { PureComponent } from 'react'
- import JSONEditor from 'jsoneditor'
- import 'jsoneditor/dist/jsoneditor.css'
- class JsonEditor extends PureComponent {
- // 监听输入值的变化
- onChange = () => {
- let value = this.jsoneditor.get()
- this.props.onChange && this.props.onChange(value)
- this.viewJsoneditor.set(value)
- }
- // 对外暴露获取编辑器的json数据
- getJson = () => {
- this.props.getJson && this.props.getJson(this.jsoneditor.get())
- }
- // 对外提交错误信息
- onError = (errArr) => {
- this.props.onError && this.props.onError(errArr)
- }
- initJsonEditor = () => {
- const options = {
- mode: 'code',
- history: true,
- onChange: this.onChange,
- onValidationError: this.onError
- };
- this.jsoneditor = new JSONEditor(this.container, options)
- this.jsoneditor.set(this.props.value)
- }
- initViewJsonEditor = () => {
- const options = {
- mode: 'view'
- };
- this.viewJsoneditor = new JSONEditor(this.viewContainer, options)
- this.viewJsoneditor.set(this.props.value)
- }
- componentDidMount () {
- this.initJsonEditor()
- this.initViewJsonEditor()
- // 设置主题色
- this.container.querySelector('.jsoneditor-menu').style.backgroundColor = this.props.themeBgColor
- this.container.querySelector('.jsoneditor').style.border = `thin solid ${this.props.themeBgColor}`
- this.viewContainer.querySelector('.jsoneditor-menu').style.backgroundColor = this.props.themeBgColor
- this.viewContainer.querySelector('.jsoneditor').style.border = `thin solid ${this.props.themeBgColor}`
- }
- componentDidUpdate() {
- if(this.jsoneditor) {
- this.jsoneditor.update(this.props.json)
- this.viewJsoneditor.update(this.props.json)
- }
- }
- render() {
- return (
this.container = elem} /> this.viewContainer = elem} />- );
- }
- }
- export default JsonEditor
通过以上的过程,我们已经完成一大半工作了,剩下的细节和优化工作,比如组件卸载时如何卸载实例, 对组件进行类型检测等,我们继续完成以上问题.
3.使用PropTypes进行类型检测以及在组件卸载时清除实例
类型检测时react内部支持的,安装react的时候会自动帮我们安装PropTypes,具体用法可参考官网地址propTypes文档,其次我们会在react的componentWillUnmount生命周期中清除编辑器的实例以释放内存.完整代码如下:
- import React, { PureComponent } from 'react'
- import JSONEditor from 'jsoneditor'
- import PropTypes from 'prop-types'
- import 'jsoneditor/dist/jsoneditor.css'
- /**
- * JsonEditor
- * @param {object} json 用于绑定的json数据
- * @param {func} onChange 变化时的回调
- * @param {func} getJson 为外部提供回去json的方法
- * @param {func} onError 为外部提供json格式错误的回调
- * @param {string} themeBgColor 为外部暴露修改主题色
- */
- class JsonEditor extends PureComponent {
- onChange = () => {
- let value = this.jsoneditor.get()
- this.props.onChange && this.props.onChange(value)
- this.viewJsoneditor.set(value)
- }
- getJson = () => {
- this.props.getJson && this.props.getJson(this.jsoneditor.get())
- }
- onError = (errArr) => {
- this.props.onError && this.props.onError(errArr)
- }
- initJsonEditor = () => {
- const options = {
- mode: 'code',
- history: true,
- onChange: this.onChange,
- onValidationError: this.onError
- };
- this.jsoneditor = new JSONEditor(this.container, options)
- this.jsoneditor.set(this.props.value)
- }
- initViewJsonEditor = () => {
- const options = {
- mode: 'view'
- };
- this.viewJsoneditor = new JSONEditor(this.viewContainer, options)
- this.viewJsoneditor.set(this.props.value)
- }
- componentDidMount () {
- this.initJsonEditor()
- this.initViewJsonEditor()
- // 设置主题色
- this.container.querySelector('.jsoneditor-menu').style.backgroundColor = this.props.themeBgColor
- this.container.querySelector('.jsoneditor').style.border = `thin solid ${this.props.themeBgColor}`
- this.viewContainer.querySelector('.jsoneditor-menu').style.backgroundColor = this.props.themeBgColor
- this.viewContainer.querySelector('.jsoneditor').style.border = `thin solid ${this.props.themeBgColor}`
- }
- componentWillUnmount () {
- if (this.jsoneditor) {
- this.jsoneditor.destroy()
- this.viewJsoneditor.destroy()
- }
- }
- componentDidUpdate() {
- if(this.jsoneditor) {
- this.jsoneditor.update(this.props.json)
- this.viewJsoneditor.update(this.props.json)
- }
- }
- render() {
- return (
this.container = elem} /> this.viewContainer = elem} />- );
- }
- }
- JsonEditor.propTypes = {
- json: PropTypes.object,
- onChange: PropTypes.func,
- getJson: PropTypes.func,
- onError: PropTypes.func,
- themeBgColor: PropTypes.string
- }
- export default JsonEditor
由于组件严格遵守开闭原则,所以我们可以提供更加定制的功能在我们的json编辑器中,已实现不同项目的需求.对于组件开发的健壮性探讨,除了使用propTypes外还可以基于typescript开发,这样适合团队开发组件库或者复杂项目组件的追溯和查错.最终效果如下:
笔者已经将实现过的组件发布到npm上了,大家如果感兴趣可以直接用npm安装后使用,方式如下:
- npm i @alex_xu/xui
- // 导入xui
- import {
- Button,
- Skeleton,
- Empty,
- Progress,
- Tag,
- Switch,
- Drawer,
- Badge,
- Alert
- } from '@alex_xu/xui'
该组件库支持按需导入,我们只需要在项目里配置babel-plugin-import即可,具体配置如下:
- // .babelrc
- "plugins": [
- ["import", { "libraryName": "@alex_xu/xui", "style": true }]
- ]
npm库截图如下:
最后
本文转自《趣谈前端》如需转载请联系作者授权。
当前标题:前端进阶:二次封装一个可实时预览的json编辑器
URL标题:http://www.mswzjz.cn/qtweb/news25/40475.html攀枝花网站建设、攀枝花网站运维推广公司-贝锐智能,是专注品牌与效果的网络营销公司;服务项目有等
声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 贝锐智能
- Android 数据库使用存在缺点需了解 (android数据库缺点)
- postgresql如何查询数据库版本
- 发垃圾邮件的人到底能赚多少钱?
- Linux系统中查看文件的神奇魔力(linux显示文件)
- VPS怎么使用,VPS从哪里登陆,VPS教程?(外网远程登录)
- VB.NET编写托盘程序经验杂谈
- word封面打印用什么软件好
- .tv域名不能实名吗
- 机顶盒怎么改路由器
- Linux下快速启动数据库的技巧(linux数据库启动)
- godaddy购买域名可以用微信支付吗?(狗爹域名购买)
- Redis使用指南了解多种调用方式(redis调用方式)
- 自己如何搭建云手机服务器?云免服务器搭建教程
- 多ip服务器有什么用
- 浅谈数据安全治理与隐私计算