习惯了这样的写法了,上来先来一个背景,交待一下事情的起因。事情的起因很简单,用惯了 mvc 框架,想来一发前后端完全分离的框架试试。选用的人员和技术是这样子的,让原本做 java 的 web 开发的人员使用 vue,在 visual studio code 里面写纯前端的代码,然后由. net 的同事,提示 webapi2 的接口。关于这个设计中的权限验证等问题,会单独一篇笔记进行介绍。
这里要说的是,由于前后端分离,导致没有了后台的 java 模板或者. net 的 razor 之类的视图引擎。没有了这种东西会很尴尬,因为需要用 ajax 来获取数据,获取到数据之后呢,用 jquery 的选择器选择 dom 然后一个个填充,提交的时候再用 jquery 的选择器选择 dom 取其值——。这样子的话,估计我要被同事们骂死……。为了邻里和谐,我觉得 vue 比较流行,而且它的 mvvm 据说速度不错,试用了一下,觉得简单方便条条框框少,毕竟我只是要用它的 mvvm 功能,只是为了把对象与 dom 绑定,把事件相绑定。
这个是我比较头疼的问题,其实个人比较倾向单面应用,因为直观上觉得虽然第一次要加载的东西比较多,但是,由于浏览器有缓存以及做好载入界面,用户其实是容易接受的。而多页面每次都要加载许多东西,虽然也有缓存,但是许多对象都需要初始化,直觉上就知道总的性能不如单页应用。然后我就开始搭建 vue 的 spa 了,用了 vue 的 webpack 模板,搭建出来的项目如下:
由于使用的工具是 vscode,所以,输入命令,调用 bower,npm 等还是比较爽的,而且可以直接开发了。但是,我发现,我想使用的是一个开源的基于 bootstrap 的后台管理系统模板,这个模板相互依赖特别多,我理了半天,没理清楚,更别说把它做成 vue 的组件化了。没过多久,我就放弃了这条我其实比较喜欢的路。
放弃了 spa,选择了多页,但是,多页又带来了另外一个问题,就是是用 iframe 将菜单、导航等独立在外以便共用,还是每个页面都带一个菜单、导航。
公司的项目一直都是在使用 iframe,但是,这次的项目有个明确的要求,就是要自适应布局,要能在手机上无缝转换,这个,就是我很不放心 iframe,我试着将 iframe 放在 bootstrap 自适应的布局中,确实也可以很好的进行工作,但是,总觉得有一天它无故导致出现滚动条,无故导致某些东西展示不全。同时,它还有一个致命的问题,就是模态弹窗只能遮住 iframe,而非整个浏览器页面,这就很头疼。这样用户的操作流程就是开放性的了,很难摸清楚用户的实际操作流程,会导致什么意外的情况发生。
所以,最后,只能用纯多页的了。
纯多页其实也存在一个问题,就是上面所说的,共用区域在每个页面里面都要写一次,其实,头部导航、左边菜单,还是很烦的,加上没有后台帮助渲染,前端的代码少不了。所以,我自己写了一个方法,用来将其它的 html 页面加载至当前界面的当前位置,其实类似于 include。
- function HtmlInclude(url) {
- var req = false;
- // Safari, Firefox, 及其他非微软浏览器
- if (window.XMLHttpRequest) {
- try {
- req = new XMLHttpRequest();
- } catch(e) {
- req = false;
- }
- } else if (window.ActiveXObject) {
- // For Internet Explorer on Windows
- try {
- req = new ActiveXObject("Msxml2.XMLHTTP");
- } catch(e) {
- try {
- req = new ActiveXObject("Microsoft.XMLHTTP");
- } catch(e) {
- req = false;
- }
- }
- }
- if (req) {
- // 同步请求,等待收到全部内容
- req.open('GET', url, false);
- req.send(null);
- document.write(req.responseText);
- } else {
- document.write("对不起,你的浏览器不支持" + "XMLHTTPRequest 对象。这个网页的显示要求" + "Internet Explorer 5 以上版本, " + "或 Firefox 或 Safari 浏览器,也可能会有其他可兼容的浏览器存在。");
- }
- }
调用的方法如下:
这样,在
- <script>
- HtmlInclude("snip/menu_left.html");
- </script>
的位置,最终就会变成 "snip/menu_left.html" 中的代码,简单完美!但是,在后面的调试过程中发现,浏览器中根本无法调试 "snip/menu_left.html" 中的代码,这就很尴尬了~~~
vue 的组件化提供了相当牛逼的特性,但是,对于单文件的支持非常地不行,只能在 webpack 等 "编译" 功能的前提下,才可以使用. vue 文件之类的组件单文件模式。但是,公司内部其实连 html,CSS,javascript 是非常模糊,让一下子跃过 html,css,js 直接去用 webpack 编译,估计不仅调试起来让人崩溃,甚至连开始都开始不了。所以,咱们还是从实际出发,以 html 为骨骼,以 css 为皮肉, 以 javascript 为筋脉。
查阅了一下,vue 提供了另外两个模式的方式,其一是内联模板,这种内联模板其实是让组件的调用者给予组件的 template 内容,这相当于在每个页面里面都要把对应的组件的模板写一遍,与我们的需求不符。其二便是 X-Templates,这个东西与我们需要的功能类似。它将 template 内容单独写成 html 格式的 js 文件,然后可以通过 <script type='text/x-template'src='' id''> 去加载,在之后再加载与之对应的组件 js 文件,并在组件的 template 处写上面那个 x-template 标签中的 id。这下又尴尬了,每个组件的引用必须引用两个文件,而且还分先后,并且,引用模板的 js 文件时,需要特殊指定 type,同时,因为是 js 文件,编辑器对 html 提示功能就瞎了。所以,vue 内置的这两种模式并不适合我。
可能是经历的原因,我觉得,我的任何项目里面都要有 jquery,虽然 vue 提供了 ajax 的请求插件,但是,我依然觉得有必须引用一下 jquery,有了它,我才有安全感,客户的各种奇葩需求,我心中才有底,不然今天动画,明天校验的,我能给愁死。
于是,我做了另外一个打算,既然
- Vue.component('my-component', {
- template: ""
- });
我给 template 这个对象字符串,而我又想给它的是 html 页面,那么我用 jquery 请求就是喽,如下:
- Vue.component('my-component', {
- template: $.getSync("templates/com1.html")
- });
这样子的话,我只需要在 templates 文件夹中增加这个 com1.html,供 vue 使用即可。这个 $.getSync 是我实现的一个 jquery 的扩展方法,因为 jquery 的同步请求只有 $.ajax 中才有,而且还是要通过回调,$.get 方法是异步的,除非设置全局同步,全局同步会影响其它的功能代码,所以,万船无奈自己用 $.ajax 封装了一个 $.getSync 方法。
- jQuery.extend({
- getSync: function(url) {
- var result = null;
- $.ajax({
- url: url,
- async: false,
- success: function(data) {
- result = data;
- }
- });
- return result;
- }
- });
来源: http://www.cnblogs.com/ensleep/p/7259907.html