建立无需build的vue单页面应用SPA框架

news/2024/11/16 9:49:49/

vue、react这种前端渲染的框架,比较适合做SPA(Single Page Application)。如果用ejs做SPA,js代码控制好全局变量冲突不算严重,但dom元素用jquery操作会遇到很多的名称上的冲突(tag、id、name)。

SPA要解决的问题:

(1)业务组件用什么文件格式?如果使用*.vue文件,需要在部署前build转换。使用*.js文件,部署前不需要buid转换。本来js的初心就是“即改即用”,我不太喜欢ts,jsx这些需要build的东西。

(2)业务组件如何加载?业务组件不可能写的时候全部知道(根据用户权限决定),也不可能一次性全部加载(影响首屏效率),应该是需要的时候,才从服务器加载。vue为此提供了异步组件,可以用Vue.defineAsyncComponent来创建。

demo.html

<html><header></header><head><!-- <script src="/js/jquery-1.11.1/jquery-1.11.1.min.js"></script> --><!-- <script src="/js/vue-3.3.4/dist/vue.global.js"></script> --><script type="importmap">{"imports": {"vue": "/js/vue-3.3.4/dist/vue.esm-browser.js","easyui":"/js/v3-easyui-3.0.14/dist/v3-easyui.js"}}</script><style>@import '/js/v3-easyui-3.0.14/dist/themes/default/easyui.css';@import '/js/v3-easyui-3.0.14/dist/themes/icon.css';@import '/js/v3-easyui-3.0.14/dist/themes/color.css';@import '/js/v3-easyui-3.0.14/dist/themes/vue.css';</style></head><body><div id="app"></div><script type="module">import * as Vue from 'vue';//console.log(Vue);import EasyUI from 'easyui';//console.log(EasyUI);import main from './com.main.js';let app=Vue.createApp(main);app.use(EasyUI);app.config.globalProperties.t=function(DDKey){return DDKey};//console.log(app);app.mount('#app');</script></body>
</html>

页面划分为上中下三层,中间划分为左右两部分,左边是功能树,右边是功能区。

com.main.js

import * as Vue from 'vue';
import EasyUI from 'easyui';
//console.log(EasyUI);
import Com_Header from './com.header.js';
import Com_Left from './com.left.js';export default {components: {Com_Header,Com_Left},data() {return { tabFile:null,tabs:[]}},created(){this.$messager.ok=this.t('OK');this.$messager.cancel=this.t('Cancel');},methods:{switchTab(name,file){console.log(name,file);console.log(this.$refs.tabs);let tab=null;for(let i=0;i<this.tabs.length;i++){if (this.tabs[i].name==name){tab=this.tabs[i];this.$refs.tabs.select(i);break;}}if (!tab){let component=Vue.defineAsyncComponent(function(){let com=import(file);let comMark=Vue.markRaw(com);return comMark;});component=Vue.shallowRef(component);this.tabs.push({name,component});this.$nextTick(function(){this.$refs.tabs.select(this.tabs.length-1);});}},onCloseTab(tab){console.log(tab);console.log(tab.title);for(let i=0;i<this.tabs.length;i++){if (this.tabs[i].name==tab.title){this.tabs.splice(i,1);break;}}}},template: `<a href="/">{{t('Home')}}</a><h1>{{t('Demo:translate at frontend browser,translate needed(vue)')}}</h1><span>SPA:Single Page Application</span><div className='layout-header2' style="background-color:bisque"><Com_Header></Com_Header></div><div className='layout-middle'><div v-Resizable="{minWidth:200,handles:'e'}" className='layout-left' style="width:200px;float:left;overflow:hidden;background-color:aquamarine"><Com_Left :switchTab=switchTab></Com_Left></div><div className='layout-right' style="margin-left:200px;overflow:hidden"><Tabs ref=tabs :scrollable="true" :plain=true @tabClose=onCloseTab><TabPanel v-for="tab in tabs" :key="tab.name" :title="tab.name" :closable=true><component :is="tab.component"></component></TabPanel></Tabs></div><div style="clear:both"></div></div><div className='layout-footer' style="background-color:brown;text-align:center"><span>copyright© Acroprise Inc. 2001-2023</span></div>`
}

这里要注意Vue.markRaw和Vue.shallowRef两个函数,如果不写,会有警告:

[Vue warn]: Vue received a Component which was made a reactive object. This can lead to unnecessary performance overhead, and should be avoided by marking the component with `markRaw` or using `shallowRef` instead of `ref`.

com.left.js

let Com_Left={props:['switchTab'],data(){return{   }},methods:{menu_click(e){//console.log(e);let name=e.target.innerHTML;//console.log(name);let file=e.target.getAttribute('file');//console.log(file);this.switchTab(name,file);e.preventDefault();}},template:`<div><a href='/'>{{t('Home')}}</a><br/><a href='DDEditor' @click=menu_click file='/vue/app/DDEditor/page.DDEditor.js'>{{t('Data Dictionary Editor')}}</a><br/><a href='likeButton' @click=menu_click file='/vue/app/likeButton/page.likeButton.js'>{{t('Like Button')}}</a><br/><a href='About' onClick={{this.menu_click}} file=''>{{t('&About')}}</a></div>`
}
export default Com_Left;

效果如下:


http://www.ppmy.cn/news/598692.html

相关文章

MySQL 逻辑备份mysqldump

逻辑备份mysqldump MySQL 自带的逻辑备份工具。可以保证数据的一致性和服务的可用性原理是通过协议连接到 MySQL 数据库&#xff0c;将需要备份的数据查询出来&#xff0c;将查询出的数据转换成对应的 insert 语句&#xff0c;当我们需要还原这些数据时&#xff0c;只要执行这些…

H3C官网-inode客户端下载

打开 新华三官网 &#xff0c;点击登录&#xff0c;用户名&#xff1a;yx800&#xff0c;密码&#xff1a;01230123 MacOS 安装 iNode Client 的事故与故事&#xff0c;提示【“libCoreUtils.dylib”将对您的电脑造成伤害】 - 知乎 怎么用mac通过inode上网&#xff1f; - 知…

【解决】萤石云接入视频报错视频编码类型非H264

说在前面 项目视频监控设备接入了萤石云&#xff0c;部分视频无法正常加载&#xff0c;报错页面如下&#xff1a; 原因分析 视频监控视频编码目前有H265和H264两种&#xff0c;萤石云仅支持H264的编码格式&#xff0c;所以对于接入的视频流才会出现这种错误。 解决方案 方案…

视频编解码 — 码控算法

目录 码控算法 码控算法的类型 具体操作过程如下 复杂度求解 帧组级 帧级 GOM级 码控算法 用算法来控制编码器输出码流的大小&#xff0c;码控就是为一帧图像选择一个合适的QP值的过程。 一帧图像的画面确定了之后&#xff0c;画面的复杂度和QP值几乎决定了编码之后的…

视频编解码器的现状 (2022)

在这个 2022 年的编解码器进展中&#xff0c;编解码器有很多&#xff1a;H.264、VP9、HEVC、AV1、多功能视频编码&#xff08;VVC&#xff09;、低复杂度增强型视频编码&#xff08;LCEVC&#xff09;和基本视频编码&#xff08;EVC&#xff09;。但篇幅有限&#xff0c;所以本…

新一代视频编解码标准正式公布!

作者 | 马超 责编 | 王晓曼 封图 | CSDN付费下载自东方IC 出品 | CSDN&#xff08;ID&#xff1a;CSDNnews&#xff09; 近日&#xff0c;新一代国际视频编解码标准&#xff08;H.266/VVC&#xff09;正式出炉&#xff0c;其中VVC是JVET&#xff08;Joint Video Exploration Te…

视频编解码——编码流程介绍

为什么需要编码&#xff1f; 原始视频数据很庞大&#xff0c;比如一个150分钟&#xff0c;30FPS&#xff0c;分辨率为720✖480的彩色电影需要占用280GB。无论是物理存储还是网络传输&#xff0c;这都是难以负担的。所以需要编码进行压缩。 编码方式 一般有两种编码方式&…

在Web网页播放网络摄像机(海康、大华等)RTSP视频流方案汇总

前言 由于项目需求&#xff0c;要在web上查看摄像机的实时视频&#xff08;不能用付费方案&#xff09;&#xff0c;所以写下此文章记录下学习过程&#xff0c;也是踩了不少坑Web端采用vue框架开发及测试所有方案都离不开ffmpeg&#xff0c;感谢ffmpeg开发者仅在Windows10下测…