前言
当我们需要制作更复杂的插件时,你可能希望有更多封装好的组件可以使用,或者你希望更灵活地控制UI适配、配色、动态适配…
这些功能HTML开发中都已经有非常多的解决方案啦! 得益于Cocos插件面板可以使用HTML进行开发,我们也可以通过引入Vue、UI组件库等模块解决这些问题!还好上学时技能点得比较花,当时就想到了Vuetify、Quasar、Element-UI这些ui组件库。
一顿操作之后发现,Creator内置的Vue版本才1.x,组件库基本要求2.x。
Vue2.x提供了比Vue1.x更多的功能,比如组件式开发,我们可以封装自己的组件(就像游戏中的Prefab)。
所以我们也顺便把内置的Vue版本升级一下!
虽然经过了多次没有结果的尝试以及放弃,但还是给我折腾出来了!
写出来跟大家分享一下,虽然并没有实现全部Element-UI的功能,如果有大佬研究过了,还希望不吝赐教~
源码已发布至Store,如果你不想自己动手,可直接翻到结尾~
一、使用Vue
创建空插件
起手式不赘述了了,我创建的插件名是vuedemo,注意修改对应的路径~
附上官方文档:
你的第一个扩展包 · Cocos Creator
下载vue脚本
可以前往以下网站获取:
vue CDN by jsDelivr - A CDN for npm and GitHub
引入Vue
将下载的脚本放到插件目录中
并在index.js文件中导入vue脚本:
const Vue = Editor.require(
packages://vuedemo/utils/vue.js);
测试Vue
写一个简单的页面
// index.js
Editor.Panel.extend({
style: "",
template: `
<div id="app">{{name}}</div>
`,
$: {
app: '#app',
},
ready() {
new Vue({
el: this.$app,
data: {
name: "hello world~"
},
methods: {
}
});
},
messages: {
}
});
至此就顺利引入了Vue。这部分还是很简单的。
需要注意的是,要暴露Vue对应的根节点,即代码中的#app
。
注意
Creator内置了Vue,所以一定要手动导入Vue,不能使用npm安装Vue,也不能直接require(“vue”)导入!
二、使用Element-UI
引入Element-UI
Element-UI可以选择使用npm方式引入:
npm install Element-UI
由于Element-UI基于Vue2.x,因此不需要指定版本(demo的Element-UI版本:2.15.13)
除了Element-UI本身,还会下载一堆它的依赖项,问题不大。
注册Element-UI
// index.js
const Vue = Editor.require(`packages://vuedemo/utils/vue.js`);
const VueCache = window.Vue;
window.Vue = Vue;
const ElementUi = Editor.require(`packages://vuedemo/node_modules/element-ui`);
Vue.use(ElementUi);
window.Vue = VueCache;
虽然注册只需要简单的一句Vue.use
,但由于存在内置的Vue1.x,需要临时替换全局变量**Vue**
为Vue2.x,否则Element-UI会被注册到Vue1.x上…
由于Element-UI并没有内置版本,你也可以使用require(
element-ui);
。
引用样式文件
Element-UI的样式文件(css)需要单独引入。我们可以将它写到html代码(template属性)中。
// index.js
template: `
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="${Editor.url("packages://vuedemo/node_modules/element-ui/lib/theme-chalk/index.css")}">
</head>
<div id="app">{{name}}</div>
`
这里使用了绝对路径,不是很美观,但相对路径并不是当前文件夹… 如果你有更好的方案欢迎留言讨论~
测试Element-UI
复制一段官网的代码来试试看~
// index.js
Editor.Panel.extend({
template: `
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="${Editor.url("packages://vuedemo/node_modules/element-ui/lib/theme-chalk/index.css")}">
</head>
<div id="app">
<div>{{name}}</div>
<el-row>
<el-button type="primary">主要按钮</el-button>
<el-button type="success">成功按钮</el-button>
<el-button type="info">信息按钮</el-button>
<el-button type="warning">警告按钮</el-button>
<el-button type="danger">危险按钮</el-button>
</el-row>
</div>
`,
});
注意
所有HTML元素都应放在app元素之内,否则会失去Vue、Element-UI的功能。
水哦~
Element-UI封装了大量常用的组件,可以极大地减少开发的成本。
三、Vue组件式开发
创建组件
这里会将上面的按钮组作为一个组件(vue的component)来示例。
先创建对应的文件夹、文件:
编写组件脚本内容:
// components/buttonGroup.js
Vue.component("button-group", {
template: `
<div>
<el-row>
<el-button type="primary">{{buttonName}}</el-button>
<el-button type="success">成功按钮</el-button>
<el-button type="info">信息按钮</el-button>
<el-button type="warning">警告按钮</el-button>
<el-button type="danger">危险按钮</el-button>
</el-row>
</div>
`,
data() {
return {
buttonName: "一个按钮"
}
},
});
导入组件
返回到index.js中,导入上面制作的buttonGroup组件:
// index.js
const VueCache = window.Vue;
window.Vue = Vue;
const ElementUi = Editor.require(`packages://vuedemo/node_modules/element-ui`);
Vue.use(ElementUi);
// 👇在这里
Editor.require(`packages://vuedemo/components/buttonGroup.js`);
// 👆在这里
window.Vue = VueCache;
只需要一行代码。
注意:要写在Vue被覆盖之后。这是为了组件代码中可以直接通过全局变量使用Vue,而不需要再次导入。
使用组件
在HTML代码中添加组件:
// index.js
Editor.Panel.extend({
template: `
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="${Editor.url("packages://vuedemo/node_modules/element-ui/lib/theme-chalk/index.css")}">
</head>
<div id="app">
<div>{{name}}</div>
<div>👇在这里</div>
<button-group></button-group>
<div>👆在这里</div>
</div>
`
});
完成~
组件的功能远不止演示的这么一点,它还可以传递参数、回调…
组件可以对常用的组件进行复用,也减少了单文件下的复杂代码逻辑。具体就看Vue文档啦~
四、一些问题
虽然到这里已经可以使用了,但其实有一些隐藏问题。
- 有部分Element-UI的功能无法使用,比如Message、Notification。
无法使用的原因是,代码中使用了import Vue from 'vue';
,这样获取到的是内置的Vue,因此调用时会产生错误。
我尝试修改代码,使其得到正确的Vue,但遇到了另一个奇怪的问题… 它们被挂到了页面上,但是不显示。
庆幸的是,这部分功能只有若干(会动态挂载节点的)模块,其他功能不受影响。
- 无法使用Element-UI的字体图标
我看到了字体文件的css代码文件,但就是无法正确显示…
这些内容稍微超出了我微弱的前端知识… 如果有相关解决方案,欢迎指教~
五、想不到吧有解决方案
无法使用字体
const fontStyleTag = document.createElement('style');
fontStyleTag.innerHTML = `
@font-face {
font-family: element-icons;
src: url('https://unpkg.com/element-ui/lib/theme-chalk/fonts/element-icons.woff') format("woff"),
url('https://unpkg.com/element-ui/lib/theme-chalk/fonts/element-icons.ttf') format("truetype");
font-weight: 400;
font-display: "auto";
font-style: normal
}`;
document.head.appendChild(fontStyleTag);
不知道为何,无法从html代码中发出http请求,因此下载不到对应的字体文件。
上述方案中,通过代码动态地在中插入了节点,就可以顺利进行下载了。这不是一个很完美的方案,但能解决问题。
无法使用部分功能的问题,虽然修改源码可以绕过require和显示等问题,但修改npm包源码会不利于传播和升级,如果不是必要的话,还是不改了吧。
结尾
过程中踩了许多坑,主要还是因为内置Vue… 导致同时存在两个Vue版本,需要各种处理。
个人其实更喜欢Vuetify,但Vuetify在内部逻辑上禁止同时存在多个Vue版本,尝试了好几次最后还是放弃了。
如果你在读完本文后没有达到最后的效果,可以参考我发布在商店的示例源码(需要一瓶快乐水):
Cocos Store-vue2.x+element-ui插件开发示例源码
感谢论坛各位大佬的经验,给了我很多的帮助,本文主要参考了以下论坛文章:
成功!cc2.*+ 插件升级vue并引入element-ui组件