mirror of
https://gitee.com/ulthon/ulthon_admin.git
synced 2026-10-29 08:58:22 +08:00
refactor(component): tagInput/propertyInput/tableData 模板改为懒加载异步获取
原实现三个组件在 JS 顶层用 $.ajax({async:false}) 同步拉取 .html 模板,
每个页面打开固定发 3 个同步请求(阻塞主线程,与组件是否被使用无关),
且路径硬编码 /static/ 与 __STATIC__(OSS 部署)脱节,模板 URL 无版本
参数存在与 js 缓存不同步的漂移问题,请求失败时静默渲染空白。
改造内容:
- 模板改为首次 render() 时异步获取,Deferred 缓存供同页多实例共享,
失败不缓存并在下次 render 自动重试,失败时 console.error + 提示
- 模板 URL 取 CONFIG.STATIC + CONFIG.STATIC_VERSION,layout 的
window.CONFIG 新增这两项注入;无注入时逐级回退 /static 与 VERSION,
兼容下游覆盖 layout 的旧页面
- 组件 CSS 由 _require.html 直接 link 引入(__STATIC__ + 版本键),
替代原 JS 动态注入
- render() 返回 Promise(resolve Vue 实例);仓库内调用均为
fire-and-forget,无兼容影响
This commit is contained in:
@@ -9,6 +9,9 @@
|
|||||||
<link rel="stylesheet" href="__STATIC__/admin/css/public.css?t={:get_site_version_key()}" media="all">
|
<link rel="stylesheet" href="__STATIC__/admin/css/public.css?t={:get_site_version_key()}" media="all">
|
||||||
<link rel="stylesheet" href="__STATIC__/common/css/theme/index.css?t={:get_site_version_key()}">
|
<link rel="stylesheet" href="__STATIC__/common/css/theme/index.css?t={:get_site_version_key()}">
|
||||||
<link rel="stylesheet" href="__STATIC__/plugs/wangeditor/style.css">
|
<link rel="stylesheet" href="__STATIC__/plugs/wangeditor/style.css">
|
||||||
|
<link rel="stylesheet" href="__STATIC__/plugs/lay-module/tagInput/tagInput.css?t={:get_site_version_key()}">
|
||||||
|
<link rel="stylesheet" href="__STATIC__/plugs/lay-module/propertyInput/propertyInput.css?t={:get_site_version_key()}">
|
||||||
|
<link rel="stylesheet" href="__STATIC__/plugs/lay-module/tableData/tableData.css?t={:get_site_version_key()}">
|
||||||
|
|
||||||
<!-- 基础js -->
|
<!-- 基础js -->
|
||||||
<script src="__STATIC__/plugs/jquery-3.4.1/jquery-3.4.1.min.js?t={:get_site_version_key()}"></script>
|
<script src="__STATIC__/plugs/jquery-3.4.1/jquery-3.4.1.min.js?t={:get_site_version_key()}"></script>
|
||||||
|
|||||||
@@ -17,7 +17,13 @@
|
|||||||
IS_SUPER_ADMIN: "{$isSuperAdmin|default='false'}",
|
IS_SUPER_ADMIN: "{$isSuperAdmin|default='false'}",
|
||||||
VERSION: "{$version|default='1.0.0'}",
|
VERSION: "{$version|default='1.0.0'}",
|
||||||
CSRF_TOKEN: "{:token()}",
|
CSRF_TOKEN: "{:token()}",
|
||||||
PAGE_KEY_NAME:'{$pageKeyName|default=$Request.url}'
|
PAGE_KEY_NAME:'{$pageKeyName|default=$Request.url}',
|
||||||
|
// 静态资源根路径(与 __STATIC__ 模板替换一致,OSS 部署时指向 OSS),
|
||||||
|
// 供 JS 内部动态拼接静态资源地址的组件使用(tagInput/propertyInput/tableData 等)
|
||||||
|
STATIC: "__STATIC__",
|
||||||
|
// 静态资源版本键,与 _require.html 中 js/css 的 ?t= 参数同源,
|
||||||
|
// 保证动态请求的模板与引入的 js/css 缓存版本一致
|
||||||
|
STATIC_VERSION: "{:get_site_version_key()}"
|
||||||
};
|
};
|
||||||
|
|
||||||
var PATH_CONFIG = {
|
var PATH_CONFIG = {
|
||||||
|
|||||||
@@ -1,30 +1,51 @@
|
|||||||
(function () {
|
(function () {
|
||||||
const propertyInputCss = '/static/plugs/lay-module/propertyInput/propertyInput.css';
|
// 组件模板懒加载:首次 render 时才异步请求,同页多实例共享一次请求;
|
||||||
const propertyInputHtml = '/static/plugs/lay-module/propertyInput/propertyInput.html';
|
// 路径与版本跟随页面注入的 CONFIG.STATIC / CONFIG.STATIC_VERSION,
|
||||||
|
// 与 _require.html 中 js/css 的缓存键保持一致;失败不缓存,下次 render 重试。
|
||||||
|
// 样式 propertyInput.css 已改为在 _require.html 中直接引入,不再由 JS 注入。
|
||||||
|
var propertyInputTemplatePromise = null;
|
||||||
|
|
||||||
var propertyInput = function () {
|
function loadPropertyInputTemplate() {
|
||||||
$(function () {
|
if (propertyInputTemplatePromise !== null) {
|
||||||
var cssElement = document.createElement('link');
|
return propertyInputTemplatePromise;
|
||||||
|
|
||||||
cssElement.setAttribute('rel', 'stylesheet');
|
|
||||||
|
|
||||||
cssElement.setAttribute('href', propertyInputCss);
|
|
||||||
|
|
||||||
document.body.appendChild(cssElement);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
var propertyInputTemplate = '';
|
|
||||||
|
|
||||||
$.ajax({
|
|
||||||
type: "get",
|
|
||||||
url: propertyInputHtml,
|
|
||||||
cache: true,
|
|
||||||
async: false,
|
|
||||||
success: function (template) {
|
|
||||||
propertyInputTemplate = template;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
var config = window.CONFIG || {};
|
||||||
|
var staticRoot = config.STATIC || '/static';
|
||||||
|
var version = config.STATIC_VERSION || config.VERSION || '';
|
||||||
|
var url = staticRoot + '/plugs/lay-module/propertyInput/propertyInput.html?t=' + version;
|
||||||
|
var deferred = $.Deferred();
|
||||||
|
|
||||||
|
$.ajax({
|
||||||
|
type: 'get',
|
||||||
|
url: url,
|
||||||
|
cache: true,
|
||||||
|
dataType: 'text'
|
||||||
|
}).done(function (template) {
|
||||||
|
if ($.trim(template)) {
|
||||||
|
deferred.resolve(template);
|
||||||
|
} else {
|
||||||
|
deferred.reject('模板内容为空');
|
||||||
|
}
|
||||||
|
}).fail(function (xhr) {
|
||||||
|
deferred.reject(xhr);
|
||||||
|
});
|
||||||
|
|
||||||
|
propertyInputTemplatePromise = deferred.promise();
|
||||||
|
propertyInputTemplatePromise.fail(function (reason) {
|
||||||
|
console.error('propertyInput 模板加载失败: ' + url, reason);
|
||||||
|
var ua = window.UA_ADMIN || window.ua;
|
||||||
|
if (ua) {
|
||||||
|
ua.msg.error('propertyInput 组件初始化失败');
|
||||||
|
}
|
||||||
|
// 失败不缓存,下次 render 自动重试
|
||||||
|
propertyInputTemplatePromise = null;
|
||||||
|
});
|
||||||
|
|
||||||
|
return propertyInputTemplatePromise;
|
||||||
|
}
|
||||||
|
|
||||||
|
var propertyInput = function () { };
|
||||||
|
|
||||||
propertyInput.prototype.render = function (elem, data) {
|
propertyInput.prototype.render = function (elem, data) {
|
||||||
|
|
||||||
@@ -184,88 +205,88 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
app = new Vue({
|
return loadPropertyInputTemplate().then(function (template) {
|
||||||
el: elem,
|
return new Vue({
|
||||||
data() {
|
el: elem,
|
||||||
return {
|
data() {
|
||||||
setting: options,
|
return {
|
||||||
value: '',
|
setting: options,
|
||||||
listItem: [
|
value: '',
|
||||||
|
listItem: [
|
||||||
|
|
||||||
],
|
],
|
||||||
originalValue: '',
|
originalValue: '',
|
||||||
field: options.field,
|
field: options.field,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
created() {
|
created() {
|
||||||
if (this.setting.value) {
|
if (this.setting.value) {
|
||||||
this.originalValue = $.extend(true, [], this.setting.value);
|
this.originalValue = $.extend(true, [], this.setting.value);
|
||||||
this.listItem = $.extend(true, [], this.setting.value);
|
this.listItem = $.extend(true, [], this.setting.value);
|
||||||
this.updateValue(this.listItem);
|
this.updateValue(this.listItem);
|
||||||
|
|
||||||
if (this.listItem.length == 0) {
|
if (this.listItem.length == 0) {
|
||||||
this.onAddItem();
|
this.onAddItem();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
if (options.required == 1) {
|
||||||
|
$(this.$refs['propertyInput']).closest('.layui-form-item').children('.layui-form-label').addClass('required');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
template: template,
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
onResetItem() {
|
||||||
|
this.listItem = $.extend(true, [], this.originalValue);
|
||||||
|
if (this.listItem.length == 0) {
|
||||||
|
this.onAddItem();
|
||||||
|
}
|
||||||
|
|
||||||
|
this.updateValue(this.listItem);
|
||||||
|
},
|
||||||
|
onAddItem() {
|
||||||
|
|
||||||
|
var emptyItem = {};
|
||||||
|
|
||||||
|
emptyItem.uid = ua.randdomString();
|
||||||
|
|
||||||
|
for (var i = 0; i < this.field.length; i++) {
|
||||||
|
emptyItem[this.field[i].key] = this.field[i].default;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.listItem.push(emptyItem);
|
||||||
|
|
||||||
|
this.updateValue(this.listItem);
|
||||||
|
},
|
||||||
|
onItemChange(item, index, itemField, event) {
|
||||||
|
this.listItem[index][itemField.key] = event.target.value;
|
||||||
|
|
||||||
|
this.updateValue(this.listItem);
|
||||||
|
},
|
||||||
|
onItemDelete(item, index) {
|
||||||
|
if (this.listItem.length <= 1) {
|
||||||
|
this.listItem = [
|
||||||
|
{
|
||||||
|
name: '',
|
||||||
|
value: ''
|
||||||
|
}
|
||||||
|
];
|
||||||
|
} else {
|
||||||
|
this.listItem.splice(index, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.updateValue(this.listItem);
|
||||||
|
},
|
||||||
|
updateValue(newValue) {
|
||||||
|
this.value = JSON.stringify(newValue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
});
|
||||||
},
|
|
||||||
mounted() {
|
|
||||||
if (options.required == 1) {
|
|
||||||
$(this.$refs['propertyInput']).closest('.layui-form-item').children('.layui-form-label').addClass('required');
|
|
||||||
}
|
|
||||||
},
|
|
||||||
template: propertyInputTemplate,
|
|
||||||
|
|
||||||
methods: {
|
|
||||||
onResetItem() {
|
|
||||||
this.listItem = $.extend(true, [], this.originalValue);
|
|
||||||
if (this.listItem.length == 0) {
|
|
||||||
this.onAddItem();
|
|
||||||
}
|
|
||||||
|
|
||||||
this.updateValue(this.listItem);
|
|
||||||
},
|
|
||||||
onAddItem() {
|
|
||||||
|
|
||||||
var emptyItem = {};
|
|
||||||
|
|
||||||
emptyItem.uid = ua.randdomString();
|
|
||||||
|
|
||||||
for (var i = 0; i < this.field.length; i++) {
|
|
||||||
emptyItem[this.field[i].key] = this.field[i].default;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.listItem.push(emptyItem);
|
|
||||||
|
|
||||||
this.updateValue(this.listItem);
|
|
||||||
},
|
|
||||||
onItemChange(item, index, itemField, event) {
|
|
||||||
this.listItem[index][itemField.key] = event.target.value;
|
|
||||||
|
|
||||||
this.updateValue(this.listItem);
|
|
||||||
},
|
|
||||||
onItemDelete(item, index) {
|
|
||||||
if (this.listItem.length <= 1) {
|
|
||||||
this.listItem = [
|
|
||||||
{
|
|
||||||
name: '',
|
|
||||||
value: ''
|
|
||||||
}
|
|
||||||
];
|
|
||||||
} else {
|
|
||||||
this.listItem.splice(index, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
this.updateValue(this.listItem);
|
|
||||||
},
|
|
||||||
updateValue(newValue) {
|
|
||||||
this.value = JSON.stringify(newValue);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
return app;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
window.propertyInput = new propertyInput();
|
window.propertyInput = new propertyInput();
|
||||||
|
|||||||
@@ -1,29 +1,53 @@
|
|||||||
(function () {
|
(function () {
|
||||||
const tableDataCss = '/static/plugs/lay-module/tableData/tableData.css';
|
// 组件模板懒加载:首次 render 时才异步请求,同页多实例共享一次请求;
|
||||||
const tableDataHtml = '/static/plugs/lay-module/tableData/tableData.html';
|
// 路径与版本跟随页面注入的 CONFIG.STATIC / CONFIG.STATIC_VERSION,
|
||||||
|
// 与 _require.html 中 js/css 的缓存键保持一致;失败不缓存,下次 render 重试。
|
||||||
|
// 样式 tableData.css 已改为在 _require.html 中直接引入,不再由 JS 注入。
|
||||||
|
var tableDataTemplatePromise = null;
|
||||||
|
|
||||||
var tableData = function () {
|
function loadTableDataTemplate() {
|
||||||
$(function () {
|
if (tableDataTemplatePromise !== null) {
|
||||||
var cssElement = document.createElement('link');
|
return tableDataTemplatePromise;
|
||||||
cssElement.setAttribute('rel', 'stylesheet');
|
|
||||||
cssElement.setAttribute('href', tableDataCss);
|
|
||||||
document.body.appendChild(cssElement);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
var tableDataTemplate = '';
|
|
||||||
|
|
||||||
$.ajax({
|
|
||||||
type: "get",
|
|
||||||
url: tableDataHtml,
|
|
||||||
cache: true,
|
|
||||||
async: false,
|
|
||||||
success: function (template) {
|
|
||||||
tableDataTemplate = template;
|
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
var config = window.CONFIG || {};
|
||||||
|
var staticRoot = config.STATIC || '/static';
|
||||||
|
var version = config.STATIC_VERSION || config.VERSION || '';
|
||||||
|
var url = staticRoot + '/plugs/lay-module/tableData/tableData.html?t=' + version;
|
||||||
|
var deferred = $.Deferred();
|
||||||
|
|
||||||
|
$.ajax({
|
||||||
|
type: 'get',
|
||||||
|
url: url,
|
||||||
|
cache: true,
|
||||||
|
dataType: 'text'
|
||||||
|
}).done(function (template) {
|
||||||
|
if ($.trim(template)) {
|
||||||
|
deferred.resolve(template);
|
||||||
|
} else {
|
||||||
|
deferred.reject('模板内容为空');
|
||||||
|
}
|
||||||
|
}).fail(function (xhr) {
|
||||||
|
deferred.reject(xhr);
|
||||||
|
});
|
||||||
|
|
||||||
|
tableDataTemplatePromise = deferred.promise();
|
||||||
|
tableDataTemplatePromise.fail(function (reason) {
|
||||||
|
console.error('tableData 模板加载失败: ' + url, reason);
|
||||||
|
var ua = window.UA_ADMIN || window.ua;
|
||||||
|
if (ua) {
|
||||||
|
ua.msg.error('tableData 组件初始化失败');
|
||||||
|
}
|
||||||
|
// 失败不缓存,下次 render 自动重试
|
||||||
|
tableDataTemplatePromise = null;
|
||||||
|
});
|
||||||
|
|
||||||
|
return tableDataTemplatePromise;
|
||||||
|
}
|
||||||
|
|
||||||
|
var tableData = function () { };
|
||||||
|
|
||||||
tableData.prototype.render = function (elem, data) {
|
tableData.prototype.render = function (elem, data) {
|
||||||
var app;
|
|
||||||
var clienWidth, clientHeight;
|
var clienWidth, clientHeight;
|
||||||
clienWidth = '100%';
|
clienWidth = '100%';
|
||||||
clientHeight = '100%';
|
clientHeight = '100%';
|
||||||
@@ -65,123 +89,123 @@
|
|||||||
options.className = 'layui-textarea';
|
options.className = 'layui-textarea';
|
||||||
}
|
}
|
||||||
|
|
||||||
app = new Vue({
|
return loadTableDataTemplate().then(function (template) {
|
||||||
el: elem,
|
return new Vue({
|
||||||
data() {
|
el: elem,
|
||||||
return {
|
data() {
|
||||||
setting: options,
|
return {
|
||||||
listSelected: [],
|
setting: options,
|
||||||
value: ''
|
listSelected: [],
|
||||||
};
|
value: ''
|
||||||
},
|
};
|
||||||
watch: {
|
},
|
||||||
listSelected(value) {
|
watch: {
|
||||||
|
listSelected(value) {
|
||||||
|
|
||||||
var valueList = value.map(itemValue => itemValue[valueField]);
|
var valueList = value.map(itemValue => itemValue[valueField]);
|
||||||
var valueStr = valueList.join(',');
|
var valueStr = valueList.join(',');
|
||||||
if (options.selectType == 'checkbox') {
|
if (options.selectType == 'checkbox') {
|
||||||
if (options.trim == 0) {
|
if (options.trim == 0) {
|
||||||
valueStr = ',' + valueStr + ',';
|
valueStr = ',' + valueStr + ',';
|
||||||
}
|
|
||||||
}
|
|
||||||
this.value = valueStr;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
listSelectedShow() {
|
|
||||||
if (this.setting.fieldName.indexOf('|') < 0) {
|
|
||||||
return this.listSelected.map(
|
|
||||||
(item) => {
|
|
||||||
item['_select_show'] = ua.dataGet(item, this.setting.fieldName);
|
|
||||||
return item;
|
|
||||||
}
|
}
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
var fieldNameList = this.setting.fieldName.split('|');
|
|
||||||
return this.listSelected.map(item => {
|
|
||||||
var showText = '';
|
|
||||||
fieldNameList.forEach(fieldName => {
|
|
||||||
showText += ua.dataGet(item, fieldName) + ' ';
|
|
||||||
});
|
|
||||||
item['_select_show'] = showText;
|
|
||||||
|
|
||||||
return item;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
this.value = options.selectValue;
|
|
||||||
if (typeof this.value != 'string') {
|
|
||||||
this.value = this.value.toString();
|
|
||||||
}
|
|
||||||
var valueLength = this.value.split(',').length;
|
|
||||||
loading.show();
|
|
||||||
$.get(options.index, {
|
|
||||||
page: 1,
|
|
||||||
limit: valueLength,
|
|
||||||
filter: JSON.stringify({ [options.valueField]: this.value }),
|
|
||||||
op: JSON.stringify({ [options.valueField]: 'in' }),
|
|
||||||
group: options.valueField
|
|
||||||
}, (result) => {
|
|
||||||
loading.hide();
|
|
||||||
this.listSelected = result.data;
|
|
||||||
});
|
|
||||||
|
|
||||||
},
|
|
||||||
mounted() {
|
|
||||||
if (options.required == 1) {
|
|
||||||
$(this.$refs['tableData']).closest('.layui-form-item').children('.layui-form-label').addClass('required');
|
|
||||||
}
|
|
||||||
},
|
|
||||||
template: tableDataTemplate,
|
|
||||||
|
|
||||||
methods: {
|
|
||||||
openSelectPage() {
|
|
||||||
|
|
||||||
if (options.readonly == 1) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
var selectedIds = this.listSelected.map(item => item.id);
|
|
||||||
var index = layer.open({
|
|
||||||
title: '选择数据',
|
|
||||||
type: 2,
|
|
||||||
area: [options.width, options.height],
|
|
||||||
content: options.selectIndex + '&selectedIds=' + selectedIds.join(','),
|
|
||||||
maxmin: true,
|
|
||||||
moveOut: true,
|
|
||||||
shadeClose: true,
|
|
||||||
success: (layero, index) => {
|
|
||||||
window[options.selectConfirmCallback] = (data) => {
|
|
||||||
data.forEach(dataItem => {
|
|
||||||
|
|
||||||
if (options.selectType == 'radio') {
|
|
||||||
this.listSelected = [];
|
|
||||||
}
|
|
||||||
var itemFind = this.listSelected.find(itemSelect => itemSelect[valueField] == dataItem[valueField]);
|
|
||||||
if (itemFind == undefined) {
|
|
||||||
this.listSelected.push(dataItem);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
this.$forceUpdate();
|
|
||||||
layer.close(index);
|
|
||||||
};
|
|
||||||
},
|
|
||||||
end: function () {
|
|
||||||
index = null;
|
|
||||||
window[options.selectConfirmCallback] = undefined;
|
|
||||||
}
|
}
|
||||||
|
this.value = valueStr;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
listSelectedShow() {
|
||||||
|
if (this.setting.fieldName.indexOf('|') < 0) {
|
||||||
|
return this.listSelected.map(
|
||||||
|
(item) => {
|
||||||
|
item['_select_show'] = ua.dataGet(item, this.setting.fieldName);
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
var fieldNameList = this.setting.fieldName.split('|');
|
||||||
|
return this.listSelected.map(item => {
|
||||||
|
var showText = '';
|
||||||
|
fieldNameList.forEach(fieldName => {
|
||||||
|
showText += ua.dataGet(item, fieldName) + ' ';
|
||||||
|
});
|
||||||
|
item['_select_show'] = showText;
|
||||||
|
|
||||||
|
return item;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
this.value = options.selectValue;
|
||||||
|
if (typeof this.value != 'string') {
|
||||||
|
this.value = this.value.toString();
|
||||||
|
}
|
||||||
|
var valueLength = this.value.split(',').length;
|
||||||
|
loading.show();
|
||||||
|
$.get(options.index, {
|
||||||
|
page: 1,
|
||||||
|
limit: valueLength,
|
||||||
|
filter: JSON.stringify({ [options.valueField]: this.value }),
|
||||||
|
op: JSON.stringify({ [options.valueField]: 'in' }),
|
||||||
|
group: options.valueField
|
||||||
|
}, (result) => {
|
||||||
|
loading.hide();
|
||||||
|
this.listSelected = result.data;
|
||||||
});
|
});
|
||||||
|
|
||||||
},
|
},
|
||||||
removeItem(item, index) {
|
mounted() {
|
||||||
this.listSelected.splice(index, 1);
|
if (options.required == 1) {
|
||||||
}
|
$(this.$refs['tableData']).closest('.layui-form-item').children('.layui-form-label').addClass('required');
|
||||||
}
|
}
|
||||||
});
|
},
|
||||||
|
template: template,
|
||||||
|
|
||||||
return app;
|
methods: {
|
||||||
|
openSelectPage() {
|
||||||
|
|
||||||
|
if (options.readonly == 1) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
var selectedIds = this.listSelected.map(item => item.id);
|
||||||
|
var index = layer.open({
|
||||||
|
title: '选择数据',
|
||||||
|
type: 2,
|
||||||
|
area: [options.width, options.height],
|
||||||
|
content: options.selectIndex + '&selectedIds=' + selectedIds.join(','),
|
||||||
|
maxmin: true,
|
||||||
|
moveOut: true,
|
||||||
|
shadeClose: true,
|
||||||
|
success: (layero, index) => {
|
||||||
|
window[options.selectConfirmCallback] = (data) => {
|
||||||
|
data.forEach(dataItem => {
|
||||||
|
|
||||||
|
if (options.selectType == 'radio') {
|
||||||
|
this.listSelected = [];
|
||||||
|
}
|
||||||
|
var itemFind = this.listSelected.find(itemSelect => itemSelect[valueField] == dataItem[valueField]);
|
||||||
|
if (itemFind == undefined) {
|
||||||
|
this.listSelected.push(dataItem);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
this.$forceUpdate();
|
||||||
|
layer.close(index);
|
||||||
|
};
|
||||||
|
},
|
||||||
|
end: function () {
|
||||||
|
index = null;
|
||||||
|
window[options.selectConfirmCallback] = undefined;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
},
|
||||||
|
removeItem(item, index) {
|
||||||
|
this.listSelected.splice(index, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
window.tableData = new tableData();
|
window.tableData = new tableData();
|
||||||
|
|||||||
@@ -1,30 +1,51 @@
|
|||||||
(function () {
|
(function () {
|
||||||
const tagInputCss = '/static/plugs/lay-module/tagInput/tagInput.css';
|
// 组件模板懒加载:首次 render 时才异步请求,同页多实例共享一次请求;
|
||||||
const tagInputHtml = '/static/plugs/lay-module/tagInput/tagInput.html';
|
// 路径与版本跟随页面注入的 CONFIG.STATIC / CONFIG.STATIC_VERSION,
|
||||||
|
// 与 _require.html 中 js/css 的缓存键保持一致;失败不缓存,下次 render 重试。
|
||||||
|
// 样式 tagInput.css 已改为在 _require.html 中直接引入,不再由 JS 注入。
|
||||||
|
var tagInputTemplatePromise = null;
|
||||||
|
|
||||||
var tagInput = function () {
|
function loadTagInputTemplate() {
|
||||||
$(function () {
|
if (tagInputTemplatePromise !== null) {
|
||||||
var cssElement = document.createElement('link');
|
return tagInputTemplatePromise;
|
||||||
|
|
||||||
cssElement.setAttribute('rel', 'stylesheet');
|
|
||||||
|
|
||||||
cssElement.setAttribute('href', tagInputCss);
|
|
||||||
|
|
||||||
document.body.appendChild(cssElement);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
var tagInputTemplate = '';
|
|
||||||
|
|
||||||
$.ajax({
|
|
||||||
type: "get",
|
|
||||||
url: tagInputHtml,
|
|
||||||
cache: true,
|
|
||||||
async: false,
|
|
||||||
success: function (template) {
|
|
||||||
tagInputTemplate = template;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
var config = window.CONFIG || {};
|
||||||
|
var staticRoot = config.STATIC || '/static';
|
||||||
|
var version = config.STATIC_VERSION || config.VERSION || '';
|
||||||
|
var url = staticRoot + '/plugs/lay-module/tagInput/tagInput.html?t=' + version;
|
||||||
|
var deferred = $.Deferred();
|
||||||
|
|
||||||
|
$.ajax({
|
||||||
|
type: 'get',
|
||||||
|
url: url,
|
||||||
|
cache: true,
|
||||||
|
dataType: 'text'
|
||||||
|
}).done(function (template) {
|
||||||
|
if ($.trim(template)) {
|
||||||
|
deferred.resolve(template);
|
||||||
|
} else {
|
||||||
|
deferred.reject('模板内容为空');
|
||||||
|
}
|
||||||
|
}).fail(function (xhr) {
|
||||||
|
deferred.reject(xhr);
|
||||||
|
});
|
||||||
|
|
||||||
|
tagInputTemplatePromise = deferred.promise();
|
||||||
|
tagInputTemplatePromise.fail(function (reason) {
|
||||||
|
console.error('tagInput 模板加载失败: ' + url, reason);
|
||||||
|
var ua = window.UA_ADMIN || window.ua;
|
||||||
|
if (ua) {
|
||||||
|
ua.msg.error('tagInput 组件初始化失败');
|
||||||
|
}
|
||||||
|
// 失败不缓存,下次 render 自动重试
|
||||||
|
tagInputTemplatePromise = null;
|
||||||
|
});
|
||||||
|
|
||||||
|
return tagInputTemplatePromise;
|
||||||
|
}
|
||||||
|
|
||||||
|
var tagInput = function () { };
|
||||||
|
|
||||||
tagInput.prototype.render = function (elem, data) {
|
tagInput.prototype.render = function (elem, data) {
|
||||||
|
|
||||||
@@ -35,81 +56,79 @@
|
|||||||
|
|
||||||
var options = $.extend(defaultOption, data);
|
var options = $.extend(defaultOption, data);
|
||||||
|
|
||||||
|
return loadTagInputTemplate().then(function (template) {
|
||||||
|
return new Vue({
|
||||||
app = new Vue({
|
el: elem,
|
||||||
el: elem,
|
data() {
|
||||||
data() {
|
return {
|
||||||
return {
|
setting: options,
|
||||||
setting: options,
|
value: '',
|
||||||
value: '',
|
inputValue: '',
|
||||||
inputValue: '',
|
inputWidth: 100,
|
||||||
inputWidth: 100,
|
inputValuePreview: '',
|
||||||
inputValuePreview: '',
|
listTag: []
|
||||||
listTag: []
|
};
|
||||||
};
|
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
inputValue(value) {
|
|
||||||
|
|
||||||
this.inputValuePreview = value;
|
|
||||||
this.updateInputWidth();
|
|
||||||
},
|
},
|
||||||
listTag(value) {
|
watch: {
|
||||||
this.value = value.join(',');
|
inputValue(value) {
|
||||||
}
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
if (options.value.length > 0) {
|
|
||||||
this.listTag = options.value.split(',');
|
|
||||||
|
|
||||||
}
|
this.inputValuePreview = value;
|
||||||
|
this.updateInputWidth();
|
||||||
|
},
|
||||||
|
listTag(value) {
|
||||||
|
this.value = value.join(',');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
if (options.value.length > 0) {
|
||||||
|
this.listTag = options.value.split(',');
|
||||||
|
|
||||||
},
|
}
|
||||||
mounted() {
|
|
||||||
if (options.required == 1) {
|
|
||||||
$(this.$refs['tagInput']).closest('.layui-form-item').children('.layui-form-label').addClass('required');
|
|
||||||
}
|
|
||||||
},
|
|
||||||
template: tagInputTemplate,
|
|
||||||
|
|
||||||
methods: {
|
},
|
||||||
onInputConfirm(e) {
|
mounted() {
|
||||||
|
if (options.required == 1) {
|
||||||
|
$(this.$refs['tagInput']).closest('.layui-form-item').children('.layui-form-label').addClass('required');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
template: template,
|
||||||
|
|
||||||
if (e) e.preventDefault();
|
methods: {
|
||||||
|
onInputConfirm(e) {
|
||||||
|
|
||||||
if ($.trim(this.inputValue).length == 0) {
|
if (e) e.preventDefault();
|
||||||
|
|
||||||
|
if ($.trim(this.inputValue).length == 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.listTag.push(this.inputValue);
|
||||||
|
this.inputValue = '';
|
||||||
return false;
|
return false;
|
||||||
|
},
|
||||||
|
onContainerClick() {
|
||||||
|
$(this.$refs['tagInputMain']).focus();
|
||||||
|
},
|
||||||
|
onInputChange(e) {
|
||||||
|
|
||||||
|
var cvalue = $(e.target).val();
|
||||||
|
this.inputValuePreview = cvalue;
|
||||||
|
|
||||||
|
},
|
||||||
|
updateInputWidth() {
|
||||||
|
var width = $(this.$refs['preshow']).width();
|
||||||
|
|
||||||
|
if (width < 100) {
|
||||||
|
width = 100;
|
||||||
|
}
|
||||||
|
this.inputWidth = width + 60;
|
||||||
|
},
|
||||||
|
removeItem(item, index) {
|
||||||
|
this.listTag.splice(index, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.listTag.push(this.inputValue);
|
|
||||||
this.inputValue = '';
|
|
||||||
return false;
|
|
||||||
},
|
|
||||||
onContainerClick() {
|
|
||||||
$(this.$refs['tagInputMain']).focus();
|
|
||||||
},
|
|
||||||
onInputChange(e) {
|
|
||||||
|
|
||||||
var cvalue = $(e.target).val();
|
|
||||||
this.inputValuePreview = cvalue;
|
|
||||||
|
|
||||||
},
|
|
||||||
updateInputWidth() {
|
|
||||||
var width = $(this.$refs['preshow']).width();
|
|
||||||
|
|
||||||
if (width < 100) {
|
|
||||||
width = 100;
|
|
||||||
}
|
|
||||||
this.inputWidth = width + 60;
|
|
||||||
},
|
|
||||||
removeItem(item, index) {
|
|
||||||
this.listTag.splice(index, 1);
|
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
return app;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
window.tagInput = new tagInput();
|
window.tagInput = new tagInput();
|
||||||
|
|||||||
Reference in New Issue
Block a user