作为一个后端,刚学 Vue 的后端,实在是不想再搞那套脚手架了,虽然搭脚手架是一劳永逸的事情。
不过,不搭脚手架就真的没办法好好用 Vue 了么?
我琢磨了一番,搞了这么一个方案,代码很少就可以搞定,主要用 RequireJS
来模块化加载。
主要思路,将 html
部分使用 template
标签写到一个或多个文件中。
然后加载后自动将 template
注册到 Vue 对象的组件中去。
例子如下:
Html 部分
<template component-name="yd-line-item" props="id,items">
<!-- 组件的 html 代码,老样子,多个顶级需要包起来。 -->
</template>
<template component-name="yd-line-map" props="row,maps">
<!-- 组件的 html 代码 -->
</template>
JavaScript 部分
define(['vue', 'data!app-template'], function (Vue, template) {
// 对象是需要的
let templates = {},
components = {};
/**
* 将字符串模板转换为对象列表
* @param {*} template_str
*/
function strToDoms(template_str) {
let templateDom = document.createElement('div'),
templates = {}, doms;
templateDom.innerHTML = template_str;
doms = templateDom.getElementsByTagName('template');
for (let i = 0; i < doms.length; i++) {
const template = doms[i];
let component_name = template.getAttribute('component-name');
if (!component_name) {
continue;
}
templates[component_name] = template;
}
return templates;
}
/**
* 字符串拆分为数组 如果不为空的话
* @param {*} str
* @param {*} splitter
*/
function splitStrOrNull(str, splitter) {
return ('string' == typeof str) && str.length > 0 ? str.split(splitter) : [];
}
/**
* 将模板转换为组件
* @param {*} templates
*/
function templatesTocomponents(templates) {
Object.keys(templates).forEach((component_name) => {
const template = templates[component_name];
let definition = {
props: splitStrOrNull(template.getAttribute('props'), ','),
template: template
};
// 如果有定义则合并
if ('object' == typeof components[component_name]) {
Object.assign(definition, components[component_name]);
}
Vue.component(component_name, definition);
})
}
/**
* 行内 地图
*/
components['yd-line-map'] = {
data: {
btn: false
},
methods: {
onClose: function (event) {}
}
}
}
// 转换模板到列表
templates = strToDoms(template);
// 统一转换为组件并注册
templatesTocomponents(templates);
});
思路:Ajax 加载 html 模板回来后,实例化并遍历顶级的 template
,将其注册为标签内指定的 component-name
,需要 props
可直接在标签上定义,如果需要 data 或 method 等其他选项,可以在 js 内定义同名对象,注册时会自动合并进去。