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使用的時候,遇到跨域上傳文件的問題,按照網上的好多辦法都解決不了。我們的項目不涉及這個問題,我是在本地調試的時候遇到的。

 好了,今天就到這里,周末快樂!

  

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM