Vue使用過程當中常見問題

目錄

1、vue監聽不到state數組/json對象內的元素的值的變化,要手動通知觸發
2、vue用splice刪除多維數組元素致使視圖更新失敗狀況
3、vue項目如何部署到php或者java環境的服務器?
4、vue-router各類路由及跳轉
5、vue-router如何取參?
6、vue中如何深度watch?
7、vue生命週期及全部東西
8、vue-router路由攔截中間件
9、axios請求攔截中間件處理
10、autoprefixer版本設置不能使用默認,browsers: ['last 2 versions']
11、設置反向代理來調用開發環境的接口實現跨域
12、scoped CSS樣式對子組件無效問題
十3、路由鑑權邏輯
十4、如何修改Vue打包以後的文件路徑爲相對路徑?
十5、在Vue中使用全局變量或者全局掛載
十6、舊系統手機及低版瀏覽器出現白屏問題的解決
十7、在vue的template裏面使用style動態設置圖片背景問題
十8、當配置vue項目打包出來的css/js文件不帶版本號時,如何解決緩存問題?
十9、路由頁面不變參數變化狀況,頁面狀態不更新問題
二10、Vue中配置反向代理使用localhost:8080時報[HPM] Error occurred while trying to proxy request,請求時報504錯誤
二11、Vue中node-sass忽然使用不了,報...Run `npm rebuild node-sass` to build the binding...等錯誤
二12、Vue發包上線cache control控制文件緩存策略問題,特別是index.html文件
二十3、document.activeElement.scrollIntoViewIfNeeded()解決iphone輸入框移位或者vue keep-alive頁面後退白屏問題
二十4、使用babel-polyfill解決舊版手機白屏或者PC瀏覽器兼容問題
二十5、使用computed的get,set可實時反向更改源數據
二十6、在頁面上如何調用組件內的函數?
二十7、在Vue中如何突破模版限制遞歸渲染類樹結構視圖內容?
二十8、vue-router路由攔截的寫法坑
二十9、移動端ios8的坑,路由前頁面沒有滾到頂部,路由後的頁面使用了fixed內容且寬爲100%時,寬度會超過750px/10rem,致使佈局錯亂
三10、axios請求formData的方式
三11、vue動態設置raw html的方式
三12、組件內部的點擊事件觸發dom結構重畫或者重流時,致使android微信瀏覽器崩潰問題
三十3、Vue中子組件如何向父組件傳遞事件?
三十4、Vuex中的mutations操做後視圖不更新問題
三十5、ios系統$router.go(-1)後退後頁面圖片不渲染問題
三十6、Vue內頁中引入相對路徑build時,實際上是相對於index.html這文件的路徑
三十7、Vue中使用canvas畫布畫圖要注意的問題
三十8、Element-UI日曆date-picker組件在IE下的首次渲染初始值失敗問題
三十9、Vue中使用css3組合動畫要注意vdom的從新渲染問題
四10、axios怎麼獲取到error中的response響應數據
四11、element-ui的table表格控件表頭與內容列不對齊問題
四12、axios下載excel文件(blob二進制方式/arraybuffer方式)
四十3、如何建立一個支持v-model的組件
四十4、dev或者打包時報TypeError: Cannot assign to read only property 'exports' of object '#<Object>'錯誤

本文同步發佈到 http://www.kt5.cn/fe/2019/11/04/vue-qna/javascript


1、vue監聽不到state數組/json對象內的元素的值的變化,要手動通知觸發

this.arr[index] = value;
this.$set(this.arr, index, this.arr[index]); // vue監聽不到數組內的元素的值的變化,要手動通知觸發, 或者用compute來得出新的view數組進行處理,或者使用watch來監聽變化從新進行更新
this.$set(this.jsonObj, 'myKey', myValue); // 針對jsonObj

 

解決方案通常以下:php

vue監聽不到數組/json對象內的元素的值的變化,一、要手動通知觸發, 2、或者用compute來得出新的view數組/jsonObj進行處理,3、或者使用watch/deep watch來監聽變化從新進行更新 css

 

2、vue用splice刪除多維數組元素致使視圖更新失敗狀況

      this.arr[i] = null // 能夠把元素設爲null,使用時用compute進行過濾便可
      this.$set(this.arr, i, this.arr[i])
      // this.arr.splice(i, 1)  // 此方法有可能會致使視圖更新錯誤

 

3、vue項目如何部署到php或者java環境的服務器?

可行方案:html

一、能夠把打包出來靜態文件中的index.html改爲.tpl或者.php尾的等模板文件格式,而後能夠在裏面動態輸出一些js變量如token,userinfo等信息供vue應用使用vue

二、也能夠初始化的內容經過接口來請求過來,保存在localstorage或者全局變量供全局使用java

 

4、vue-router各類路由及跳轉

this.$router.go(-1) // 後退 相似 window.history.go(n)

// 字符串
router.push('/home')
 
// 對象
router.push({ path: '/home' })
 
// 命名的路由
router.push({ name: 'user', params: { userId: 123 }})
 
// 帶查詢參數,變成 /register?plan=private
router.push({ path: '/register', query: { plan: 'private' }})
this.$router.replace({ // 替換,但history不會記錄一條新的記錄
    path: '/mypath',
    query: {m: 'model'},
  })
路徑:http://localhost:8081/#/test?name=1
<router-link :to="{path:'/test',query: {name: id}}">跳轉</router-link>(id是參數)

路徑:http://localhost:8081/#/test/1
<router-link :to="'/test/'+id">跳轉</router-link>(id是參數)

params、query是什麼?
params:/router1/:id ,/router1/123,/router1/789 , 這裏的id叫作params, 且路由時必需傳id
params:/router1/:id? ,/router1/123,/router1 , 這裏的id叫作params, 路由時可不傳id
query:/router1?id=123 ,/router1?id=456 , 這裏的id叫作query,路由時可不傳idnode

 

5、vue-router如何取參?

this.$route.params.id
this.$route.query.id

 

6、vue中如何深度watch?

  watch: {
    obj: {
      handler: function (v, o) {
      },
      deep: true
    }
  }

 

7、vue生命週期及全部東西

<template>
  <article class="pageview">
    {{msg}}
  </article>
</template>

<script>
import {mapState, mapMutations} from 'vuex'
export default {
  name: 'Home',
  mixins: [],
  components: {
  },
  data () {
    return {
      msg: 'Home',
    }
  },
  beforeCreate () {
  },
  created () {
  },
  mounted () {
  },
  beforeUpdate () {
  },
  updated () {
  },
  beforeDestroy () {
  },
  destroyed () {
  },
  methods: {
  },
  computed: {
  },
  filters: {
  }
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style lang="scss" scoped>
</style

 

8、vue-router路由攔截中間件

router.beforeEach((to, from, next) => { 
  if (to.meta.title) {
    document.title = to.meta.title // 動態設置meta或者能夠進行其餘路由前的操做
  }
  NProgress.start() // NProgress進度條開始
  next()
})

router.afterEach((transition) => {
  NProgress.done() // NProgress進度條結束
})

 

9、axios請求攔截中間件處理

 

axios.interceptors.request.use((headerConfig)=> {
    // 這裏,發送請求以前能夠設置request header
    return config
  },
  (error) => {
    // 請求錯誤處理
    return Promise.reject(error)
  })

// 添加響應攔截器
axios.interceptors.response.use((response) => {
  let {data} = response
  // 這裏,請求完成後能夠對數據進行攔截處理
  return data
}, (error) => {
  // 響應錯誤處理
  return Promise.reject(error)
})    

 

10、autoprefixer版本設置不能使用默認,browsers: ['last 2 versions']

last 10 versionsreact

 

11、設置反向代理來調用開發環境的接口實現跨域

修改 config/index.js 文件android

寫法1、使用filter統一代理ios

        proxyTable: {
         '**': {
            target: 'https://www.xxxx.com', // 要設置需跨域訪問的接口的baseUrl,dev/qa/production
            changeOrigin: true,
            filter: function(pathname, req) {
              const isApiDev = pathname.indexOf('/api-dev/') == 0; 
              const isApiTest = pathname.indexOf('/api-qa/') == 0; 
              const isApiProduction = pathname.indexOf('/api-production/') == 0; 
              return isApiDev||isApiTest||isApiProduction ;
            }
          }
        }

 寫法2、使用pathRewrite的寫法

    proxyTable: {
        '/api/resource': {
          target: 'https://xxx.xxx.xxx.xxx:7070',
          changeOrigin: true,
          secure: false,
          pathRewrite: {
            '^/api/resource'': '/resource'
          }
        },
    },

 

12、scoped CSS樣式對子組件無效問題

解決方案,使用/deep/

<template>
  <div id="app">
    <el-input v-model="text" class="text-box"></el-input>
  </div>
</template>

<script>
export default {
  name: 'App',
  data() {
    return {
      text: 'hello'
    };
  }
};
</script>

<style lang="less" scoped>
.text-box { // 樣式能夠做用於el-input 組件
  /deep/ input {
    width: 166px;
    text-align: center;
  }
}
</style>

 

十3、路由鑑權邏輯

 簡單的登陸+是否VIP會員的鑑權寫法以下

import router from './router'
import NProgress from 'nprogress' // Progress 進度條
import 'nprogress/nprogress.css' // Progress 進度條樣式

NProgress.inc(0.2)
NProgress.configure({
  easing: 'ease',
  speed: 500,
  showSpinner: false
})
router.beforeEach((to, from, next) => {
  const isLogin = false // 是否登陸
  const isVip= false // 是否VIP會員
  NProgress.start()
  if (isLogin && isVip) {
    if (to.path.indexOf('/login') !== -1 || to.path.indexOf('/order-vip') !== -1) {
      next('/home')
      NProgress.done() 
    } else {
      if (to.meta.title) {
        document.title = to.meta.title
      }
      next()
    }
  } else if (isLogin && !isVip) {
    if (to.path.indexOf('/login') !== -1 || to.path.indexOf('/home') !== -1) {
      next('/order-vip')
      NProgress.done() 
    } else {
      if (to.meta.title) {
        document.title = to.meta.title
      }
      next()
    }
  } else {
    if (to.path.indexOf('/login') !== -1) {
      if (to.meta.title) {
        document.title = to.meta.title
      }
      next()
    } else {
      next('/login') // 不然所有重定向到登陸頁
      NProgress.done()
    }
  }
})

router.afterEach(() => {
  NProgress.done() // 結束Progress
})

 

十4、如何修改Vue打包以後的文件路徑爲相對路徑?

一、修改config目錄下的index.js

  build: {
    // Template for index.html
    index: path.resolve(__dirname, '../dist/index.html'),

    // Paths
    assetsRoot: path.resolve(__dirname, '../dist'),
    assetsSubDirectory: 'static',
    assetsPublicPath: '', // 修改這裏由「/」改成「./」或者「」

二、修改build目錄下的utils.js

    if (options.extract) {
      return ExtractTextPlugin.extract({
        use: loaders,
        fallback: 'vue-style-loader',
        publicPath: '../../' // 增長相對路徑,主要是針對css背景圖
      })

 

十5、在Vue中使用全局變量或者全局掛載

在小型的vue項目當中,其實並不須要使用到vuex,使用全局變量便可,使用方式:直接在main.js裏面定義便可

/**
 * 全局變量定義
 *
 */
global.USER_ID = null
global.USER_NAME = null 
global.USER_MOBILE = null

 固然也能夠在main.js中把常量或者方法掛載到Vue的原型鏈prototype上,而後在頁面中就能夠直接經過this.xxx直接使用,如:

import axios from 'axios'
import {
  Toast,
  MessageBox,
  Indicator,
  DatetimePicker
} from 'mint-ui'

Vue.use(DatetimePicker)

Vue.prototype.SUCCESS_CODE = 0
Vue.prototype.$toast = Toast
Vue.prototype.$messagebox = MessageBox
Vue.prototype.$indicator = Indicator
Vue.prototype.axios = axios

 

十6、舊系統手機及低版瀏覽器出現白屏問題的解決

 解決方式:在main.js引入babel-polyfill

import 'babel-polyfill'

 

十7、在vue的template裏面使用style動態設置圖片背景問題

若是同時使用style及:style去分開設置background:url(xxx)及background-size:xx xx的話後面設置的background-size會失效,可使用下面的方式來設置解決

 

background: url(https://www.xxx.com/xxx.jpg) center center / 100% 100% no-repeat;

 

十8、當配置vue項目打包出來的css/js文件不帶版本號時,如何解決緩存問題?

服務器端可以使用Cache-Control: max-age=xxxx 來控制靜態文件緩存時間,相似以下:

// 服務端代碼
app.get('/xxxx.js', (req, res) => {
  res.setHeader('Cache-Control', 'max-age=3600')
  // ...其餘輸出
})

 

十9、路由頁面不變參數變化狀況,頁面狀態不更新問題

 

watch: {
  '$route' (to, from) {
      // 針對變化進行相應的處理
  }
}

 

二10、Vue中配置反向代理使用localhost:8080時報[HPM] Error occurred while trying to proxy request,請求時報504錯誤

解決方法:把 config/index.js文件中的localhost改成本地IP就好了,而後後面再改回來試試,或者再檢查一下localhost指向不對了(host文件)

 

二11、Vue中node-sass忽然使用不了,報...Run `npm rebuild node-sass` to build the binding...等錯誤

當你在平時的帶有node-sass依賴包的vue項目中執行yarn dev或者npm run dev時,會報錯,大概報錯以下:

Node Sass could not find a binding for your current environment
This usually happens because your environment has changed since running `npm install`
Run `npm rebuild node-sass` to build the binding for your current environment

而後,rebuild就rebuild唄,結果還發現因爲牆的緣由,二進制文件地址(https://github-production-release-asset-2e65be.s3.amazonaws.com/4128353/585e4c80-9c28-11e8-8cdf-78861f5b0424?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAIWNJYAX4CSVEH53A%2F20190220%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20190220T104233Z&X-Amz-Expires=300&X-Amz-Signature=12d9dd3497845f932f0926c62c2c02ace2b12095f8212a70957430c2b706aadb&X-Amz-SignedHeaders=host&actor_id=7983722&response-content-disposition=attachment%3B%20filename%3Dwin32-x64-64_binding.node&response-content-type=application%2Foctet-stream)一直下載失敗,一直rebuild失敗

1)切換到聯通4G把文件下載到本地如(D:\temp\win32-x64-48_binding.node )

2)執行命令:set SASS_BINARY_PATH=D:\temp\win32-x64-48_binding.node

3)執行npm rebuild node-sass 成功啦,最後,執行yarn dev或者npm run dev應該沒問題了。

 

二12、Vue發包上線cache control控制文件緩存策略問題,特別是index.html文件

不作緩存策略會存在的問題:微信下打開總會load到舊包或者會出現白屏狀況

vue項目打包發佈時生成的靜態包文件要發佈上線時可選用的策略:

1)若是用戶訪問量大的,服務器能夠設置cache control及增量發包

2)若是系統用戶數訪問量不大的,能夠設置html添加meta設計cache-control爲no-cache或者其餘,也能夠結合服務器一塊兒配置

 

二十3、document.activeElement.scrollIntoViewIfNeeded()解決iphone輸入框移位或者vue keep-alive頁面後退白屏問題

iphone X系列頁面偶爾會出現因頁面變換而渲染失敗的狀況,引用scrollIntoViewIfNeeded能夠強制滾動頁面讓其從新渲染出來

 

二十4、使用babel-polyfill解決舊版手機白屏或者PC瀏覽器兼容問題

 

npm install --save babel-polyfill

 

在main.js文件頭部引入

import 'babel-polyfill' // 或者require('babel-polyfill')

 

二十5、使用computed的get,set可實時反向更改源數據

  computed: {
    fullname: {
      // getter
      get: function () {
        return this.firstName + this.familyName
      },
      // setter
      set: function (newValue) {
        let names = newValue.split(' ')
        this.firstName = names[0]
        this.familyName = names[1]
      }
    }
  }

  

二十6、在頁面上如何調用組件內的函數?

在template上加上組件引用標識ref,相似於之前的react組件引用方式

            <my-component
                ref="myComponent"
            />

而後在js代碼中直接使用

this.$refs.myComponent.fn() // 好比組件上有fn這個內置方法,直接調用

 

二十7、在Vue中如何突破模版限制遞歸渲染類樹結構視圖內容?

使用render函數即其中的h函數進行處理,可參照:Vue中使用渲染函數render實現無限節點的樹

 

二十8、vue-router路由攔截的寫法坑

router.beforeEach((to, from, next) => {
    // 全部if else條件都必需提供next路由出口,否則會出現死詢環(不停加載)或者路由失敗(白屏的狀況)
})

 

二十9、移動端ios8的坑,路由前頁面沒有滾到頂部,路由後的頁面使用了fixed內容且寬爲100%時,寬度會超過750px/10rem,致使佈局錯亂

解決方式:給路由後的fixed內容加寬度限制

max-width: 10rem; /* 750px; */

 

三10、axios請求formData的方式

 

axios({
            url: '/api',
            method: 'post',
            data: {
              param1:param1,
              param2:param2
            },
            transformRequest: [function (data) {
              let ret = ''
              for (let it in data) {
                ret += encodeURIComponent(it) + '=' + encodeURIComponent(data[it]) + '&'
              }
              return ret
            }],
            headers: {
              'Content-Type': 'application/x-www-form-urlencoded'
            }
          })

 

三11、vue動態設置raw html的方式

<div v-html="message">{{message}}</div>

export default {
  data () {
    return {
      message: "<h2>這裏能夠包含html標籤<h2>"
    }
  }
}

 

三12、組件內部的點擊事件觸發dom結構重畫或者重流時,致使android微信瀏覽器崩潰問題

解決方案:讓事件異步執行

  methods: {
    handleClick () {
      setTimeout(() => {
        this.$router.go(-1) // 或者其餘關閉對話框事件等等
      }, 0)
    }
  }

 

三十3、Vue中子組件如何向父組件傳遞事件?

<script>
// Vue子組件定義事件event1
Vue.component('child-component', {
  methods: {
    emitEvent() {
      this.$emit('event1', 'This is a event.')
    }
  },
  mounted() {
    this.emitEvent()
  }
})
</script> 

// Vue 父組件綁定監聽子組件事件event1
<template>
  <div>
    <child-component @event1="eventHandler" />
  </div>
</template>
 
<script>
  import childComponent from './child-component'
  export default {
    components: {
      childComponent
    },
    methods: {
      eventHandler(event) {
        console.log(event)
      }
    }
  }
</script> 

 

三十4、Vuex中的mutations操做後視圖不更新問題

  mutations: {
    UPDATE_STATE: (state, options) => {
      // state = { ...state, ...options } // 此方式可能會更新失敗
      Object.keys(options).forEach((key) => { // 使用Vue.set強制更新
        Vue.set(state, key, options[key])
      })
    }
  },

 

三十5、ios系統$router.go(-1)後退後頁面圖片不渲染問題

使用 <keep-alive>或者使用scrollIntoView與scrollIntoViewIfNeed

 

三十6、Vue內頁中引入相對路徑build時,實際上是相對於index.html這文件的路徑

好比若是在vue內頁中使用

 

let myUrl = './static/js/a.js' // build出來後是 相對於http://xxx/xx/index.html的,結果爲 http://xxx/xx/static/js/a.js

 

 

三十7、Vue中使用canvas畫布畫圖要注意的問題

1、如何引用本地的圖片?

 

// 若是要使用一張圖片,能夠先把img import進來再畫到canvas上,
import myImg from '../../assets/my-img.png'
// ...
export default {
// ...
  data () {
    return {
      myImg: myImg
    }
  },
// ...
}

 

2、圖片請求時是來源於外域,但canvas最後要使用btoa、canvas.toDataURL()時,瀏覽器是不容許跨域把canvas轉成圖片的。

解決辦法是要,圖片服務器設置容許跨域請求,同時<img >要加上crossOrigin="anonymous"屬性,告訴頁面圖片將要經過跨域請求。

可參考:

https://stackoverflow.com/questions/20424279/canvas-todataurl-securityerror/27260385#27260385

https://www.jianshu.com/p/6fe06667b748

 

三十8、Element-UI日曆date-picker組件在IE下的首次渲染初始值失敗問題

刪除placeholder或者本身額外添加假placeholder

參考:https://blog.csdn.net/siwangdexie_copy/article/details/89947594

 

三十9、Vue中使用css3組合動畫要注意vdom的從新渲染問題

問題:當使用class樣式結合setTimeout進行組合動畫時,若是使用了dom操做來添加或者修改動畫,此時,若是過程當中state值發生了變化,有可能致使動畫失效(dom被從新渲染了)

解決方式:應當儘量使用減小直接對dom的操做,更多的使用直接變動state切換class或者v-if、v-show來結合setTimeout來建立組合動畫

 

四10、axios怎麼獲取到error中的response響應數據

解決方式:在error後面添加error.response

 

四11、element-ui的table表格控件表頭與內容列不對齊問題

/* 解決element-ui的table表格控件表頭與內容列不對齊問題 */
/deep/ .el-table th.gutter {
  display: table-cell !important;
}

 

四12、axios下載excel文件(blob二進制方式/arraybuffer方式)

// blob二進制方式
axios({
        method: 'post',
        url: '/api/exportExcel',
        headers: {
          'Content-Type': 'application/json'
        },
        data: {
          token: 'xxxx',
        }
      }).then((res) => {
        // console.log(res)
        const blob = new Blob([res.data], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8' }) // application/vnd.openxmlformats-officedocument.spreadsheetml.sheet這裏表示xlsx類型
        const downloadElement = document.createElement('a')
        const href = window.URL.createObjectURL(blob) // 建立下載的連接
        downloadElement.href = href
        downloadElement.download = 'xxxx.xlsx' // 下載後文件名
        document.body.appendChild(downloadElement)
        downloadElement.click() // 點擊下載
        document.body.removeChild(downloadElement) // 下載完成移除元素
        window.URL.revokeObjectURL(href) // 釋放掉blob對象
      }).catch((error) => {
        console.log(error.message)
      })

arraybuffer方式也相似,可參考:http://www.javashuo.com/article/p-xvpotevd-ke.html

 

四十3、如何建立一個支持v-model的組件

 

<template> 
  <div>
    <label><input type="checkbox" :checked="value" @click="change" /> 勾選我吧</label>
  </div>
</template>
<script>
export default {
  data() {
  },
 model:{ prop:'value', event:'valueChange' },
  props:{
    value: Number
  },
  methods:{
    change(e) { 
      let number = 0
      if(e.target.checked) { 
          number = 1
      }
      this.$emit('valueChange', number)
    }
  }
}

</script>

 

四十4、dev或者打包時報TypeError: Cannot assign to read only property 'exports' of object '#<Object>'錯誤

問題所在就是代碼段同時出現了import與module.exports

解決方案:去掉module.export,使用統一ES6的方式編寫便可,用export default代替

  1. 本文做者:Nelson Kuang,別名:Fast Mover  歡迎你們留言及多多指教
  2. 版權聲明:歡迎轉載學習 => 請標註信息來源於 http://www.cnblogs.com/fastmover/p/9150159.html
相關文章
相關標籤/搜索