Vue2.x + UEditor + v-model双向绑定。之所以有这个
repo
的原因是:
1、UEditor依然是国内使用频率极高的所见即所得编辑器而Vue又有着广泛的使用,所以将两者结合使用,是很多Vue项目开发者的切实需求。
2、目前没有发现满足这种需求,而使用又很方便的repo
、有的可能也只是简单的暴露一个UEditor
的实例,仍然需要开发者手动去调用getContent
,setContent
,而通过v-model绑定数据也是很多人期待的方式。于是自己在写公司项目时就手动撸了一个,周末整理一下分享出来,希望能帮助到有同样需求的小伙伴。
$ npm i vue-ueditor-wrap
Quick Start(基于vue-cli,完整DEMO)
-
下载官方资源文件下载最新编译的资源文件 官网下载的版本是
1.4.3.3
,存在诸多BUG,例如Issue1和Issue8,且官方不再积极维护。为了世界的和平,针对一些BUG,我进行了修复,并把编译好的文件放在了本仓库的dist
目录下,你可以放心下载,当然你也可以自己clone
官方源码并编译将dist目录下的UEditor资源文件解压并重命名为
UEditor
(只需要选择一个你需要的版本,比如utf8-php),放入你项目的static
目录下因为
Ueditor
本身也依赖ZeroClipboard
,codemirror
等第三方库,并在Ueditor
源码中有自动引入依赖的方法。所以没有直接将Ueditor
封装在当前组件中,我提供的只是一个Wrapper
以及自动加载。这也就是为什么你还需要去官网下载Ueditor
。如果小伙伴们有更好的解决方案,欢迎PR
。如果你的项目中有出现
ZeroClipboard
,codemirror
等字眼的相关报错,很可能的原因就是因为你没有按照我的方法放置Ueditor
资源文件。当然你也可以根据你的项目结构修改UEDITOR_HOME_URL
,具体参见官方文档和步骤5
-
引入
VueUeditorWrap
组件import VueUeditorWrap from 'vue-ueditor-wrap'
-
注册组件
components: { VueUeditorWrap },
-
v-model
绑定数据<vue-ueditor-wrap v-model="msg"></vue-ueditor-wrap>
data () { return { msg: '<h2><img src="http://img.baidu.com/hi/jx2/j_0003.gif"/>Vue2.x + UEditor + v-model双向绑定</h2>' } }
至此你已经可以在页面中看到一个初始化之后的
UEditor
了,并且它已经成功和数据绑定了! -
根据项目需求修改配置,完整配置选项查看ueditor.config.js源码或 官方文档
<vue-ueditor-wrap :config="myConfig"></vue-ueditor-wrap>
data () { return { myConfig: { // 如果需要上传功能,找后端小伙伴要服务器接口地址 // serverUrl: 'http://api.demo.com/ueditor/upload', // 你的UEditor资源存放的路径,相对于打包后的index.html UEDITOR_HOME_URL: './static/UEditor/', // 编辑器不自动被内容撑高 autoHeightEnabled: false, // 初始容器高度 initialFrameHeight: 240, // 初始容器宽度 initialFrameWidth: '100%', // 关闭自动保存 enableAutoSave: false } } }
-
获取
UEditor
实例<vue-ueditor-wrap @ready="ready"></vue-ueditor-wrap>
methods: { ready(editorInstance) { console.log(`你要的实例${editorInstance.key}: `,editorInstance) } }
-
设置是否在组件的
beforeDestroy
钩子里销毁UEditor
实例<vue-ueditor-wrap :destroy="true"></vue-ueditor-wrap>
-
通过传入 init 参数来对 window.UE 进行二次开发,如添加自定义按钮等。init 函数将在 scripts 加载完毕、editor 初始化之前运行。
<vue-ueditor-wrap :init="myInit"></vue-ueditor-wrap>
methods: { myInit() { window.UE.registerUI(/* ... */) } }
-
结合
init
参数以及本组件提供的registerButton
方法,方便地添加自定义按钮:<template> <vue-ueditor-wrap ref="ueditor" v-model="html" :init="myInit"></vue-ueditor-wrap> </template> <script> export default { ... methods: { myInit() { this.$refs.ueditor.registerButton({ name: 'test', icon: '/static/test-button.png', tip: 'this is a test tip', handler: (editor, name) => { editor.execCommand('inserthtml', `<span>text inserted by test button</span>`) } }) } } } </script>
参数:
name
按钮名称;icon
按钮图标;tip
按钮 hover 时显示的简介;handler
以 editor 和 name 为入参的按钮动作函数。
-
v-model
双向数据绑定!简单、易用。你的代码里将没有实例化,没有getContent
,setContent
,你只需要像绑定input框一样绑定vue-ueditor-wrap
组件。当然如果你需要获取当前UEditor
的实例,vue-ueditor-wrap
也提供ready
事件,你只需要接收ready
事件触发函数的第一个参数即可,那就是你想要的。 -
完全遵从官方API。所有的配置参数和实例方法与官方完全一致,通过给
vue-ueditor-wrap
组件的config
属性传递一个对象,你就可以得到一个完全独立配置的UEditor
编辑器。 -
自动添加依赖。你不需要自己在
index.html
或main.js
里引入UEditor
的各种js
文件。更重要的是即使你在一个页面里同时使用多个vue-ueditor-wrap
组件,它所依赖的js
文件也只会加载一次。这么做的原因在于你不需要在用户一打开项目时就先加载大量UEditor
相关的资源,所有的资源只会在vue-ueditor-wrap
组件所在页面打开时才加载、当然如果你在index.html
或main.js
里引入了相关资源、vue-ueditor-wrap
也会自动准确判断,你不用担心它会重复加载资源。 -
每个
vue-ueditor-wrap
组件是完全独立的。你甚至可以在上面使用v-for
一次渲染99个兔斯基(不要忘记添加key
值)。
-
是否支持IE等低版本浏览器?
因为使用了Promise
,事件对象Event
等,所以请自行bable
,后续也许会加v1.2.0开始,支持到IE9
-
为什么我会看到这个?
这是因为你的
UEDITOR_HOME_URL
路径填写错误,请参考步骤5
-
为什么我会看到
后台配置项返回格式出错
那时因为
UEditor
包含上传图片、文件等需要与后台配合的功能,而你没有在config
中设置正确的serverUrl
,UEditor
默认的地址是根据你下载版本生成的,去找你的后端小伙伴要吧 -
为什么我输入
"? ! $ #"
这些特殊字符,没有绑定上去?那时因为
v-model
的实现基于UEditor
实例上contentChange
事件的监听,由于你输入这些特殊字符时通常是按住shift
键的,UEditor
本身的contentChange
在shift
键按住时不会触发,你也可以尝试同时按下多个键,你会发现contentChange
只触发一次。所有我也很无奈呀!请移步UEditor -
单图片上传后v-model绑定的是loading小图标,我最新编辑的版本,修复了官方的这个BUG,如果你使用的是官网的资源文件,请替换资源文件或参见Issue1)
更多Issues,由于个人能力有限,如果小伙伴们有好的建议或更炫酷的操作,欢迎
PR
,如果你觉得这个组件给你的开发带来了实实在在的方便,也非常感谢你的Star和关注
PR之前请先执行
npm run lint
进行代码风格检测,大部分语法细节可以通过npm run fix
修正,记得修改package.json
的版本号version