• vue前端开发那些事——vue开发遇到的问题


      vue web开发并不是孤立的。它需要众多插件的配合以及其它js框架的支持。本篇想把vue web开发的一些问题,拿出来讨论下。

           1、web界面采用哪个UI框架?项目中引用了layui框架。引入框架的好处就是解决界面风格统一的问题,良好的布局(自适应不同的设备),提供了大量基础组件及模块,如form提交、上传、弹出层。我觉得前台框架的引入,解放了美工的一些工作。以前有bootstrap、现在有layui、element ui(基于vue 2.0)。

     <body>
        <div id="app"></div>
        <script src="/static/layui/layui.all.js" charset="utf-8"></script>
     </body>

    我们以非模块化的方式加载。采用哪种方式加载,各有利弊。尽管官方推荐使用模块化加载,但是我觉得直接引用简单啊,用起来简单。当然,对于要求高性能的应用就另当别论了。项目中有弹出框的需要,于是用了layui的弹出层。一开始用的很happy,等测试的时候,在IE和火狐浏览器下,弹出框加载不出来页面。oh,my god。我们看看弹出组件:

    export default {
       open: function (options) {
    
         var defaults = {
           type: 2,
           shade: 0,
           maxmin: false,
           area: ["30%", "63%"],
           title: '',
           content: '',
           btnAlign: 'c', //按钮居中
    
           end: function () {
             if (options.end) {
               options.end();
             }
           }
    
         };
    
         var options = $.extend(true, {}, defaults, options);
         layer.open(options);
       }
     }

    type:2表示弹出iframe,所以content是一个url。调用的时候,我给传的是vue router中配置的路径,此时url:‘/login’

     {
          name: 'login',
          path: '/login',
          component: require('../indexs/login')
      }

          所有的vue路由传给弹出层,在IE和火狐下都打不开,只有chrome下完美呈现。我就在网上找了好多解决方案,但是都以失败告终。弹出层的效果,我们还是很想要的,怎么办呢?换个思路。记得之前应用bootstrap的时候,它的弹出层的思路是这样的:要弹出的东西,就在当前页面,只不过是隐藏的。当点击按钮的时候,它才显示出来。我借鉴了这个思路,实现了弹出层,完美兼容各大浏览器。在vue篇中已经阐述过了。

         使用layui的tab,也有一个问题,在tab外面,点击按钮,控制tab内部的切换。layui也提供了方法,我用了两处,一处是好的,另一处怎么都切换不了。如下图所示:

     填写我的求助,点击“生成求助”按钮,提交数据并切换tab “待应助”。ok,这个没有任何问题。看另外一处:

     当我点击右边的“我的求助”,需要切换tab到“我的求助”。这个不管怎样都切换不过来。

    2、vue-router

      我主要用它来做权限验证:

     name: 'admin',
          path: '/admin',
    
          component: require('../admin/root'),
          meta: {
            requiresAdminAuth:true 
          },

    添加了一个meta对象,在路由的时候“安检”,需要管理员权限的路由,必须检查,没有权限的就跳回到login。

    router.beforeEach((to, from, next) => {
      let unLgoin = beforeAction();
    
      if (to.path === '/login') {
        next()
      } else if (to.matched.some(r => r.meta.requiresAuth) && unLgoin) {
        next({
          path: '/login',
          query: {
            redirect: to.fullPath
          }
        })
      } else if (to.matched.some(r => r.meta.requiresAdminAuth) && (unLgoin || !isAdmin())) {
        next({
          path: '/login',
        })
      } else {
        next()
      }
    })

    router-view能做出像iframe框架的东西,如后台管理页面中,左侧和顶部一般是固定的部分,而中间的区域是加载不同的页面。

     <div class="layui-body layui-tab-content" style="bottom:0;z-index:1000" :style="readyShowContent?'top:0;left:0;':''">
            <router-view></router-view>
     </div>

    当然,这得配合路由表了。

    {
          name: 'admin',
          path: '/admin',
    
          component: require('../admin/root'),
          meta: {
            requiresAdminAuth:true 
          },
          children: [{
              path: '/',
              component: require('../admin/userManage')
            },
            {
              path: 'user',
              component: require('../admin/userManage')
            },
            {
              path: 'fixContent',
              component: require('../admin/fixContent')
            },
          ]
     }

    另外一个问题是router兼容性问题,在IE下面,a链接带有vue路由的,都打不开,如果换成router-link的时候,就可以正常打开链接。当界面的改动量太大的时候,我们还是采用其它的改法,检测浏览器是否为IE:

    export default {
        mounted() {
            function checkIE() {
                return '-ms-scroll-limit' in document.documentElement.style && '-ms-ime-align' in document.documentElement.style
            }
            if (checkIE()) {
                window.addEventListener('hashchange', () => {
                    var currentPath = window.location.hash.slice(1);
                    if (this.$route.path !== currentPath) {
                        this.$router.push(currentPath)
                    }
                }, false)
            }
        }
    };

    放到App.vue中。

    3、vue中http请求

       vue是一个纯前端的框架,需要webapi支持数据。通过http请求webapi就行了。我们既可以用jquery ajax请求,也可以使用axios请求,我们项目中选择了后者。axios里有个拦截器挺好的,它可以在请求发送前,添加请求头及一些工作。

    const requestInterceptor=axios.interceptors.request.use(
      config => {
        config.data = JSON.stringify(config.data);
        config.headers = {
          'Content-Type':'application/json',
          'Authorization':'Bearer '+getStore('token'),
           xhrFields: {
             withCredentials: true
          },
          'Pragma': 'no-cache',
          'Cache-Control': 'no-cache'
      }
        return config;
      },
      error => {
        return Promise.reject(err);
      }
    );

    这个拦截器做了两件事情:

    a、请求data:把js对象转为json字符串

    b、请求头:添加了数据发送格式,token验证、IE下get有缓存,所以加了‘Cache-Control’和‘Pragma’

    拦截器在请求的时候,也可以根据情况去掉:

    /**
     * post请求
     * @param url
     * @param data
     * @param  isRemoveInterceptor  是否移除拦截器
     * @returns {Promise}
     */
    
     export function post(url,data = {},isRemoveInterceptor=false){
       if(isRemoveInterceptor){
         axios.interceptors.request.eject(requestInterceptor);
       }
       return new Promise((resolve,reject) => {
         axios.post(axios.defaults.baseURL+url,data)
              .then(response => {
                resolve(response.data);
              },err => {
                reject(err)
              })
       })
     }

    4、vuex + local Storage

        有了vuex,为什么还需要local Storage?这是因为vuex相当于一个“娇弱”的内存数据库,如果F5刷新的话,它的数据会丢失。在使用过程中,vuex不能跨域多个标签页共享数据。这时候,可以采用h5的api  localStorage,它可以实现数据持久化。我们在登录的时候使用了vuex保持状态。如果其它页面需要判断当前用户是否登录,可以直接通过vuex获取,vuex为空的话,就去storage中去查看。用户登录的状态不能长期保持,因为涉及网站安全问题,所以得实现登录过期的方法,迫使用户重新登录。

    5、kindeditor

      在结合vue使用的时候,遇到跨域上传文件的问题,按照网上的好多办法都解决不了。我们的项目不涉及这个问题,我是在本地调试的时候遇到的。

     好了,今天就到这里,周末快乐!

      

  • 相关阅读:
    通过注册表选择文件默认打开方式
    oracle的imp和exp
    oracle 10g正则表达式 REGEXP_LIKE 用法
    oracle varchar 和varchar2的区别
    Oracle lower(Upper)函数|大小写|
    NC资金管理对外付款自动选上“网上支付”设置
    wmsys.wm_concat的几个用法
    GridView使用初步
    JavaScript学习笔记(一)—细节问题
    图片水印功能
  • 原文地址:https://www.cnblogs.com/wangqiang3311/p/10084302.html
Copyright © 2020-2023  润新知