UNPKG

lia_acp_1

Version:

//初始项目构建案例:创建config.js文件 const acp = require('lia_acp_1');

958 lines (880 loc) 30.3 kB
const fs = require('fs'); const path = require('path'); function init(fileObj) { const dirPath = '../../'; if(!fs.existsSync(path.join(__dirname, dirPath, 'lia.js'))) { fs.writeFile(path.join(__dirname, dirPath, 'lia.js'), template_html('js', 'lia'), function(err) { if(err) { console.log(err); } }); } if(!fs.existsSync(path.join(__dirname, dirPath, 'event.js'))) { fs.writeFile(path.join(__dirname, dirPath, 'event.js'), template_html('js', 'event'), function(err) { if(err) { console.log(err); } }); } traverse(fileObj, dirPath); } function traverse(fileObj, dirpath) { for(const i in fileObj) { if(typeof fileObj[i] === 'object') { if(!fs.existsSync(path.join(__dirname, dirpath, i))) { fs.mkdirSync(path.join(__dirname, dirpath, i)); traverse(fileObj[i], path.join(dirpath, i)); } else { console.log(i + '文件夹已存在'); traverse(fileObj[i], path.join(dirpath, i)); } } else { if(fileObj[i] === 0) { const fname = i.split('_')[0] + '.' + i.split('_')[1]; if(!fs.existsSync(path.join(__dirname, dirpath, '/', fname))) { let template = ''; if(i.split('_')[1] == 'html') { template = template_html('html', i.split('_')[0]); } else if(i.split('_')[1] == 'css') { template = template_html('css', i.split('_')[0]); } else if(i.split('_')[1] == 'js') { template = template_html('js', i.split('_')[0]); } fs.writeFile(path.join(__dirname, dirpath, '/', fname), template, function(err) { if(err) { console.log(err); } }); } else { console.log(fname + '文件已存在') } } else { console.log(fileObj[i] + ':输入错误!') } } } } function template_html(type, name) { if(type == 'html') { //html文件模板 if(name == 'index') { return `<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="shortcut icon" href="https://qileshang.top/resources/image/logo2.jpg" type="image/x-icon"> <link rel="stylesheet" href="./${ name }.css"> <title>欢迎使用lia.js</title> </head> <body> <!-- template --> <div class="${ name }"> <div class="${ name }-header"> </div> <div class="${ name }-mainer"> </div> <div class="${ name }-footer"> </div> </div> <!-- template --> <script src="./${ name }.js" type="module"></script> </body> </html>` } else if(name == 'head') { return `<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="stylesheet" href="./head.css"> <title>head</title> </head> <body> <!-- template --> <div class="head"> <div class="logo"> <img src="https://qileshang.top/resources/image/logo2.jpg" alt=""> <span class="title">lia框架使用模板--(测试阶段)</span> </div> <nav> <div class="bt-link main_link"> <span>首页</span> </div> <div class="bt-link anime_link"> <span>动画</span> </div> <div class="bt-link comic_link"> <span>漫画</span> </div> <div class="bt-link novel_link"> <span>小说</span> </div> <div class="bt-link game_link"> <span>游戏</span> </div> <div class="bt-link info_link"> <span>资讯</span> </div> </nav> <div class="search"> <input type="text" placeholder="请输入"> </div> <div class="login"> <div class="box"> <img src="https://qileshang.top/resources/image/logo.jpg" alt=""> <span>任相随</span> </div> </div> </div> <!-- template --> <script src="./head.js" type="module"></script> </body> </html>` } else if(name == 'main') { return `<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="shortcut icon" href="https://qileshang.top/resources/image/logo2.jpg" type="image/x-icon"> <link rel="stylesheet" href="./${ name }.css"> <title>欢迎使用lia框架</title> </head> <body> <!-- template --> <div class="${ name }"> <p>main组件</p> <div class="${ name }-header"> </div> <div class="${ name }-mainer"> </div> <div class="${ name }-footer"> </div> </div> <!-- template --> <script src="./${ name }.js" type="module"></script> </body> </html>` } else if(name == 'foot') { return `<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="shortcut icon" href="https://qileshang.top/resources/image/logo2.jpg" type="image/x-icon"> <link rel="stylesheet" href="./${ name }.css"> <title>欢迎使用lia框架</title> </head> <body> <!-- template --> <div class="${ name }"> <p>foot组件</p> <div class="${ name }-header"> </div> <div class="${ name }-mainer"> </div> <div class="${ name }-footer"> </div> </div> <!-- template --> <script src="./${ name }.js" type="module"></script> </body> </html>` } else { return `<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="shortcut icon" href="https://qileshang.top/resources/image/logo2.jpg" type="image/x-icon"> <link rel="stylesheet" href="./${ name }.css"> <title>欢迎使用lia框架</title> </head> <body> <!-- template --> <div class="${ name }"> <p>${ name }组件</p> <div class="${ name }-header"> </div> <div class="${ name }-mainer"> </div> <div class="${ name }-footer"> </div> </div> <!-- template --> <script src="./${ name }.js" type="module"></script> </body> </html>` } } else if(type == 'css') { //css文件模板 if(name == 'index') { return `a { font-size: 16px; } span { font-size: 16px; } body { padding: 0; margin: 0; } .${ name } { background-color: white; }` } else if(name == 'head') { return `a { font-size: 16px; } span { font-size: 14px; } body { margin: 0; padding: 0; } .head { width: 100%; min-width: 1140px; background-color: #f6f6f6; display: grid; justify-content: space-between; } .head .logo { grid-column: 1; grid-row: 1 / span 2; display: flex; justify-content: center; align-items: center; margin-left: 50px; } .head .logo img { width: 100px; margin-right: 10px; } .head .logo .title { font-size: 24px; } .head nav { width: 480px; height: 60px; grid-column: 2; grid-row: 1; display: flex; justify-content: space-between; align-items: center; } .head nav .bt-link{ width: 50px; height: 35px; display: inline-flex; justify-content: center; align-items: center; cursor: pointer; } .head nav .bt-link span { pointer-events: none; } .head .search { width: 480px; grid-column: 2; grid-row: 2; display: flex; justify-content: center; align-items: center; margin-bottom: 30px; } .head .search input{ width: 480px; height: 35px; text-indent: 2em; box-sizing: border-box; border: 2px solid #8d8383; border-radius: 15px; } .head .login { width: 100px; grid-column: 3; grid-row: 1 / span 2; display: flex; justify-content: center; align-items: center; margin-right: 50px; position: relative; } .head .login .box { display: flex; flex-direction: column; justify-content: center; align-items: center; z-index: 100; position: static; } /*.entry-box-more { width: 80px; height: 100px; background-color: #ffffff; position: fixed; right: 50px; top: 200px; border-radius: 10px; box-shadow: 0 0 13px 2px #3d3d3d; cursor: pointer; }*/ .head .login .box img { width: 30px; border: 1px solid #8d8383; border-radius: 50%; padding: 5px; margin-bottom: 15px; cursor: pointer; animation: userIamge 2s infinite; } @keyframes userIamge { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } } ` } else if(name == 'main') { return `a { font-size: 16px; } span { font-size: 16px; } body { padding: 0; margin: 0; } .${ name } { width: 100%; height: 500px; background-color: white; display: flex; justify-content: center; align-items: center; } .${ name } p { font-size: 30px; }` } else if(name == 'foot') { return `a { font-size: 16px; } span { font-size: 16px; } body { padding: 0; margin: 0; } .${ name } { width: 100%; height: 120px; background-color: #f6f6f6; display: flex; justify-content: center; align-items: center; } .${ name } p { font-size: 30px; }` } else { return `a { font-size: 16px; } span { font-size: 16px; } body { padding: 0; margin: 0; } .${ name } { width: 100%; height: 500px; background-color: white; display: flex; justify-content: center; align-items: center; } .${ name } p { font-size: 30px; }` } } else if(type == 'js') { //js文件模板 if(name == 'index') { return `import lia from './lia.js'; import head from './component/head/head.js' import main from './component/main/main.js' import foot from './component/foot/foot.js' const index = { name: 'index', data: null, router: null, main: function() { const initObj = { '.index-header': head, '.index-mainer': main, '.index-footer': foot } lia.init(initObj); index_code(); } } function index_code() { } lia.run(index); export { index }` } else if(name == 'head') { return `import lia from '../../lia.js'; import main from '../main/main.js'; import anime from '../anime/anime.js'; import comic from '../comic/comic.js'; import game from '../game/game.js'; import novel from '../novel/novel.js'; import info from '../info/info.js'; const head = { name: 'head', data: null, router: { '.main_link': { '.index-mainer': main }, '.anime_link': { '.index-mainer': anime }, '.comic_link': { '.index-mainer': comic }, '.novel_link': { '.index-mainer': novel }, '.game_link': { '.index-mainer': game }, '.info_link': { '.index-mainer': info } }, main: function() { head_code(); } } function head_code() { } //单独运行组件 lia.run(head); export default head;`; } else if(name == 'lia') { return `//此处组件的概念: //这里的组件指的是一个包含了html、css和js三类文件的组合体,它的表象是一个里面有着html、css和js这三类文件并与三者同名的文件 //比如:有一个名为head的文件夹,该文件夹里面有head.html文件、head.css文件以及head.js文件,这些组合起来称之为head组件 import events from "./event.js"; let bindModelViewObj = {}; let bindViewModelObj = { value: [], textarea: [] }; let proxyObj = {}; const lia = { //注册事件,删除事件----这样应该可以减少各组件之间的依赖,确保的它们独立性!!! //注销事件函数 //遍历所有注册过的事件,并将之注销 unregister: function (entryClassName) { lia.traverse(events.index, entryClassName); }, traverse: function (obj, entryClassName = null) { //console.log(obj); if(entryClassName != null) { if(obj.el == entryClassName) { document.removeEventListener('scroll', obj.events[0]); if(obj.childs != null) { for(let i in obj.childs) { lia.traverse(obj.childs[i]); } } } else { if(obj.childs != null) { for(let i in obj.childs) { lia.traverse(obj.childs[i], entryClassName); } } } } else { document.removeEventListener('scroll', obj.events[0]); if(obj.childs != null) { for(let i in obj.childs) { lia.traverse(obj.childs[i]); } } } }, //el对象 //el全称是element,即元素 //通过el()方法可以获取到一个跟DOM元素相关的对象,该对象包含了很多实现DOM操作的属性,这些属性的值本质上是封装了DOM操作的函数 el: function (ClassName) { return { backgroundColor: function(value) { document.querySelector(ClassName).style.backgroundColor = value; }, color: function(value) { document.querySelector(ClassName).style.color = value; }, width: function(value) { document.querySelector(ClassName).style.width = value; }, height: function(value) { document.querySelector(ClassName).style.height = value; }, display: function(value) { document.querySelector(ClassName).style.display = value; }, visibility: function(value) { document.querySelector(ClassName).style.visibility = value; }, value: function(value) { document.querySelector(ClassName).value = value; }, get: function() { return document.querySelector(ClassName); } }; }, //ajax函数 //对原生ajax的简单封装 ajax: function (method, url, callback, asc) { const xhr = new XMLHttpRequest(); xhr.onreadystatechange = function() { if (this.readyState == 4 && this.status == 200) { //这一步很重要,不能省略 callback(this.response); } } xhr.open(method, url, asc); xhr.send(); }, //组件配置函数component() //通过该函数可以实现在任意位置添加组件 component: function (entryClassName, componentName, componentJs, routerObj, dpath = './component/') { let url = dpath + componentName + '/' + componentName +'.html'; lia.ajax('GET', url, function(response) { //第一步:添加html模板 const template = response.split('<!-- template -->')[1]; document.querySelector(entryClassName).innerHTML = template; //第二步:添加css样式 //实现了entryClassName当前位置对应的样式link元素的切换 //也就是entryClassName当前位置添加了哪个组件就切换使用那个组件的样式 let previous_link = document.querySelector('[data-sign="l' + entryClassName + '"]'); if(!previous_link) { //如果entryClassName对应的样式link元素未存在,则在下面创建link元素并添加到html文档的head里面 let link = document.createElement('link'); link.rel = 'stylesheet' link.href = dpath + componentName + '/' + componentName + '.css'; link.type = 'text/css' link.dataset.sign = 'l' + entryClassName; document.head.appendChild(link); } else { //如果entryClassName对应的样式link元素已存在,则先删除原来的link元素,再创建新的link元素并添加到html文档的head里面 previous_link .remove(); let link = document.createElement('link'); link.rel = 'stylesheet' link.href = dpath + componentName + '/' + componentName + '.css'; link.type = 'text/css' link.dataset.sign = 'l' + entryClassName; document.head.appendChild(link); } }, false); //第三步:添加js脚本 //componentJs()是当前组件对应的方法,基本包含了该组件的脚本内容实现 //这里设置componentJs()相当于为html文档添加了js文件,只是与设置script元素形式上不同,但内容实现是一样的 componentJs(); //如果routerObj存在,那就意味着不仅为entryClassName对应位置添加组件,同时还为该组件设置路由 if(routerObj) { lia.router(routerObj, dpath); } }, //页面初始配置函数init() //该函数是用来在index.html文件中相应的位置添加组件 //initOb为页面初始配置对象 init: function (initObj, dpath) { //console.log(obj); for(const entryClassName in initObj) { const componentName = initObj[entryClassName].name; const componentJs = initObj[entryClassName].main; const routerObj = initObj[entryClassName].router; lia.component(entryClassName, componentName, componentJs, routerObj, dpath); } }, //路由配置函数router() //该函数是用来为当前组件设置路由用的 //routerObj路由配置对象 router: function (routerObj, dpath) { for(const linkClassName in routerObj) { for(const entryClassName in routerObj[linkClassName]) { if(document.querySelector(entryClassName)) { const componentName = routerObj[linkClassName][entryClassName].name; const componentJs = routerObj[linkClassName][entryClassName].main; const next_routerObj = routerObj[linkClassName][entryClassName].router; document.querySelector(linkClassName).addEventListener('click', function() { lia.unregister(entryClassName); setTimeout(function() { document.documentElement.scrollTop = 0; lia.component(entryClassName, componentName, componentJs, next_routerObj, dpath); }, 100); }); } } } }, //后面的待完善 //数据渲染视图 record: function (obj) { for(let key in obj) { bindModelViewObj[key]=[]; } }, //单向数据绑定 bindModelView: function (domName, type, property) { if(document.querySelector(domName) && (typeof lia.getProxy()) != 'undefined') { if(type == 'backgroundColor') { //console.log('ok'); document.querySelector(domName).style.backgroundColor = lia.getProxy()[property]; }else if(type == 'color') { //document.querySelector(domName).style.color = lia.getProxy()[property]; } else if(type == 'width') { document.querySelector(domName).style.width = lia.getProxy()[property]; } else if(type == 'height') { document.querySelector(domName).style.height = lia.getProxy()[property]; } else if(type == 'display') { document.querySelector(domName).style.display = lia.getProxy()[property]; } else if(type == 'visibility') { document.querySelector(domName).style.visibility = lia.getProxy()[property]; } else if(type == 'input') { document.querySelector(domName).value = lia.getProxy()[property]; } else { document.querySelector(domName).setAttribute(type, lia.getProxy()[property]); } } else { if(typeof bindModelViewObj[property] != 'undefined') { bindModelViewObj[property].push([domName, type]); } } }, achieveModelToView: function (target, key) { for(const property in bindModelViewObj) { //遍历原始数据对象,完成初始化页面数据的渲染 if(!key) { for(let i = 0; i < bindModelViewObj[property].length; i++) { let [domName, type] = bindModelViewObj[property][i]; if(type == 'backgroundColor') { lia.el(domName).backgroundColor(target[property]); } else if(type == 'color') { lia.el(domName).color(target[property]); } else if(type == 'width') { lia.el(domName).width(target[property]); } else if(type == 'height') { lia.el(domName).height(target[property]); } else if(type == 'display') { lia.el(domName).display(target[property]); } else if(type == 'visibility') { lia.el(domName).visibility(target[property]); } else if(type == 'input') { lia.el(domName).value(target[property]); } else { document.querySelector(domName).setAttribute(type, target[property]); } } } //侦听数据变化,并重新渲染页面 if(property == key) { for(let i = 0; i < bindModelViewObj[property].length; i++) { let [domName, type] = bindModelViewObj[property][i]; if(type == 'backgroundColor') { document.querySelector(domName).style.backgroundColor = target[key]; } else if(type == 'color') { document.querySelector(domName).style.color = target[key]; } else if(type == 'width') { document.querySelector(domName).style.width = target[key]; } else if(type == 'height') { document.querySelector(domName).style.height = target[key]; } else if(type == 'display') { document.querySelector(domName).style.display = target[key]; } else if(type == 'visibility') { document.querySelector(domName).style.visibility = target[key]; } else if(type == 'input') { document.querySelector(domName).value = target[key]; } else { document.querySelector(domName).setAttribute(type, target[key]); } } } } }, //视图更新数据 //单向数据绑定 bindViewModel: function (domName, type, property) { if(type == 'value') { bindViewModelObj.value.push([domName, property]); } else if(type == 'textarea') { bindViewModelObj.textarea.push([domName, property]); } }, achieveViewToModel: function (proxy) { for(const i in bindViewModelObj) { if(bindViewModelObj[i].length != 0) { if(i == 'value') { for(let j = 0; j < bindViewModelObj[i].length; j++) { let [domName, property] = bindViewModelObj[i][j]; document.querySelector(domName).addEventListener('keyup', function() { proxy[property] = document.querySelector(domName).value; }); } } } } }, //双向数据绑定 bind: function (domName, type, property) { //下面两者结合相当于双向数据绑定 lia.bindModelView(domName, type, property); lia.bindViewModel(domName, type, property); }, ref: function (obj) { let o = new Object(); o.runs = function() { lia.achieveModelToView(obj); const proxy = new Proxy(obj, { set(trapTarget, key, value, receiver) { const result = Reflect.set(...arguments); lia.achieveModelToView(receiver, key); return result; } }); } }, //使用代理实现数据绑定的效果 proxyFun: function (target) { //页面初始化时触发 lia.achieveModelToView(target); const proxy = new Proxy(target, { set(trapTarget, key, value, receiver) { const result = Reflect.set(...arguments); //更改数据时触发 lia.achieveModelToView(receiver, key); return result; } }); lia.achieveViewToModel(proxy); proxyObj.proxy = proxy; }, getProxy: function () { return proxyObj.proxy; }, //组件运行函数 run: function (componentObj) { if(document.querySelector('.' + componentObj.name)) { if(componentObj.data != null) { //记录原始数据对象 lia.record(componentObj.data); } if(componentObj.router != null) { //配置路由功能 lia.router(componentObj.router, '../'); } componentObj.main('../'); if(componentObj.data != null) { //实例化响应数据 lia.proxyFun(componentObj.data); } } } } export default lia;` } else if(name == 'event') { return `//事件处理机制————现在感觉很完美 let indexObj = { index: { el: null, events: [], childs: { head: { el: '.index-header', events: [], chils: null }, main: { el: '.index-mainer', events: [], childs: null }, anime: { el: '.index-mainer', events: [], childs: null }, comic: { el: '.index-mainer', events: [], childs: null }, novel: { el: '.index-mainer', events: [], childs: null }, game: { el: '.index-mainer', events: [], childs: null }, info: { el: '.index-mainer', events: [], childs: null }, foot: { el: '.index-mainer', events: [], childs: null } } } }; const events = new Proxy(indexObj, { get(target, key) { return Reflect.get(...arguments); }, set(target, key, value) { return Reflect.set(...arguments); } }); export default events;`; } else { return `import lia from '../../lia.js'; const ${ name } = { name: '${ name }', data: null, router: null, main: function() { ${ name }_code(); } } function ${ name }_code() { } //单独运行组件 lia.run(${ name }); export default ${ name };` } } } module.exports = { init: init }