VUE 相關問題積累

VUE問題積累

一、組件三種掛載方式

  • 自動掛載
var app3 = new Vue({
  el: '#app-3',
  data: {
    seen: true
  }
})
  • 手動掛載
// 能夠實現延遲按需掛載
<div id="app"> {{name}} </div> 
<button onclick="test()">掛載</button> 
<script> 
 var obj= {name: '張三'} 
 var vm = new Vue({ 
  data: obj
 }) 
 function test() { 
  vm.$mount("#app"); 
 }
// Vue.extend()建立沒有掛載的的子類,可使用該子累建立多個實例
var app= Vue.extend({ 
 template: '<p>{{message}}</p>', 
   data: function () { 
    return { 
        message: 'message'
     } 
    } 
   }) 
 new app().$mount('#app') // 建立 app實例,並掛載到一個元素上

二、路由傳遞參數的方式

<p>
    <!-- query要用path來引入,params要用name來引入,故不能寫爲 :to="{path:'/login',params: {isLogin: true}} -->
    <!-- 跳轉路由時用this.$router: this.$router.push({name:"login",params:{isLogin:true}});this.$router.push({path: '/login', query: {isLogin : true}}); -->
    <!-- 接收參數時用this.$route: this.$route.query.isLogin 和 this.$route.params.isLogin; -->
    <router-link :to="{name:'login',params: {isLogin: true}}">親,請登陸</router-link>
    <router-link :to="{name:'login',params: {isLogin: false}}">免費註冊</router-link>
  </p>
  <!-- 路由出口, 路由匹配到的組件將渲染在這裏 -->
  <router-view></router-view>

三、render:h=>h(App)的理解

render:h=>h(App)是ES6中的箭頭函數寫法,等價於render:function(h){return h(App);}.css

1.箭頭函數中的this是 指向 包裹this所在函數外面的對象上。html

2.h是creatElement的別名,vue生態系統的通用管理vue

3.template:‘<app/>’,components:{App}配合使用與單獨使用render:h=>h(App)會達到一樣的效果
  前者識別<template>標籤,後者直接解析template下的id爲app的div(忽略template的存在)react

new Vue({
  el: '#app', //  至關於 new Vue({}).$mount('#app');
  template: '<App/>', // 一、能夠經過在 #app 內加入<app></app>替代 二、或者 經過 render: h => h(App) 渲染一個視圖,而後提供給el掛載
  components: { // vue2中能夠經過 render: h => h(App) 渲染一個視圖,而後提供給el掛載
    App
  }
});

四、Vue.nextTick()的理解

與DOM相關操做寫在該函數回調中,確保DOM已渲染
nextTick的由來:
    因爲VUE的數據驅動視圖更新,是異步的,即修改數據的當下,視圖不會馬上更新,而是等同一事件循環中的全部數據變化完成以後,再統一進行視圖更新。
    
nextTick的觸發時機:
    在同一事件循環中的數據變化後,DOM完成更新,當即執行nextTick(callback)內的回調。
    
應用場景:
    須要在視圖更新以後,基於新的視圖進行操做。git

  1. 在Vue生命週期的created()鉤子函數進行的DOM操做必定要放在Vue.nextTick()的回調函數中。緣由是什麼呢,緣由是在created()鉤子函數執行的時候DOM 其實並未進行任何渲染,而此時進行DOM操做無異於徒勞,因此此處必定要將DOM操做的js代碼放進Vue.nextTick()的回調函數中。與之對應的就是mounted鉤子函數,由於該鉤子函數執行時全部的DOM掛載和渲染都已完成,此時在該鉤子函數中進行任何DOM操做都不會有問題 。
  2. 在數據變化後要執行的某個操做,而這個操做須要使用隨數據改變而改變的DOM結構的時候,這個操做都應該放進Vue.nextTick()的回調函數中。

簡單總結事件循環:
    同步代碼執行 -> 查找異步隊列,推入執行棧,執行callback1[事件循環1] ->查找異步隊列,推入執行棧,執行callback2[事件循環2]...即每一個異步callback,最終都會造成本身獨立的一個事件循環。結合nextTick的由來,能夠推出每一個事件循環中,nextTick觸發的時機:github

        

五、動態屬性添加

https://cn.vuejs.org/v2/guide...

受現代 JavaScript 的限制 (以及廢棄 Object.observe),Vue 不能檢測到對象屬性的添加或刪除。因爲 Vue 會在初始化實例時對屬性執行 getter/setter 轉化過程,因此屬性必須在 data 對象上存在才能讓 Vue 轉換它,這樣才能讓它是響應的。例如:vue-router

var vm = new Vue({
  data:{
  a:1
  }
})

// `vm.a` 是響應的

vm.b = 2
// `vm.b` 是非響應的

Vue 不容許在已經建立的實例上動態添加新的根級響應式屬性 (root-level reactive property)。然而它可使用 Vue.set(object, key, value) 方法將響應屬性添加到嵌套的對象上:vuex

Vue.set(vm.someObject, 'b', 2)

您還可使用 vm.$set 實例方法,這也是全局 Vue.set 方法的別名:npm

this.$set(this.someObject,'b',2)

有時你想向已有對象上添加一些屬性,例如使用 Object.assign() 或 _.extend() 方法來添加屬性。可是,添加到對象上的新屬性不會觸發更新。在這種狀況下能夠建立一個新的對象,讓它包含原對象的屬性和新的屬性:緩存

// 代替 `Object.assign(this.someObject, { a: 1, b: 2 })`
this.someObject = Object.assign({}, this.someObject, { a: 1, b: 2 })

六、樣式滲透到子組件

你能夠在一個組件中同時使用有做用域和無做用域的樣式:

深度做用選擇器 https://vue-loader.vuejs.org/...
<style>
/* 全局樣式 */
</style>

<style scoped>
/* 本地樣式 */
</style>

子組件的根元素:使用 scoped 後,父組件的樣式將不會滲透到子組件中。不過一個子組件的根節點會同時受其父組件有做用域的 CSS 和子組件有做用域的 CSS 的影響。這樣設計是爲了讓父組件能夠從佈局的角度出發,調整其子組件根元素的樣式。

深度做用選擇器:若是你但願 scoped 樣式中的一個選擇器可以做用得「更深」,例如影響子組件,你可使用 >>> 操做符:

<style scoped>
.a >>> .b { /* ... */ }
</style>
// 上述代碼將會編譯成:
.a[data-v-f3f3eg9] .b { /* ... */ }

有些像 Sass 之類的預處理器沒法正確解析 >>>。這種狀況下你可使用 /deep/ 操做符取而代之——這是一個 >>> 的別名,一樣能夠正常工做。


七、路由控制title及權限

import Vue from 'vue';
import Router from 'vue-router';
import store from 'src/vuex/store.js';
Vue.use(Router);

const router = new Router({
  routes: [
    {
      path: '/login', /* 登陸界面 */
      name: 'login',
      component: login/* ,hidden: true, // 自定義屬性,在組件中能夠經過 this.$route.hidden 獲取值 */
    },
    {
      path: '/sysSetting', /* 首頁 */
      component: sysSetting,
      name: 'sysSetting', /* this.$route.matched.filter(item => item.name) */
      meta: {
        keepAlive: false, /* 用於在 <keep-alive> 中使用,判斷是否須要進行緩存 */
        auth: true, /* 自定義屬性,用於判斷是否進行校驗,在router.beforeEach中使用 */
        title: '系統設置' /* 能夠經過$route.meta.title 後取當前的描述信息、菜單信息 */
      }
    },
    {
      path: '*', /* 默認跳轉到登陸界面 */
      redirect: {path: '/sysSetting'}
    }
  ]
});

router.beforeEach((to, from, next) => {// 註冊一個全局前置守衛
  if (to.meta.title) { // 路由發生變化修改頁面title
    document.title = to.meta.title;
  }
  
  if (to.matched.some(m => m.meta.auth)) {// 判斷是否須要校驗
    if (store.state.isLogin) {// 獲取
      next();// 校驗經過,正常跳轉到你設置好的頁面
    } else {
      next({// 校驗失敗,跳轉至登陸界面
        path: '/login',
        query: {
          redirect: to.fullPath
        }// 將跳轉的路由path做爲參數,用於在登陸成功後獲取並跳轉到該路徑
      });
    }
  } else {
    next();// 不須要校驗,直接跳轉
  }
});

export default router;

八、嵌套路由及命名視圖

https://router.vuejs.org/zh-c...

九、頁面路由進度條

http://hilongjw.github.io/vue...

十、靜態資源路徑

問題描述<img v-bind:src="imgUrl"/> 綁定的資源請求失敗

<template>
 <div class="content"
   <!-- 界面中引入 -->
   <img v-bind:src="imgUrl"/>
</div>
</template>

// js中設置的路徑
<script type="text/ecmascript-6">
  export default {
    data () {
      return {
        imgUrl : './logo.png' // 此處路徑引入錯誤
      };
    }
 }

緣由分析:在上面代碼中文件的路徑是相對於項目文件目錄的,而網頁把根域名做爲相對路徑的根目錄(npm run build 生成),而且全部的文件名後都被添加上了一個隨機字符串。結構目錄以下以下:

圖片描述

解決辦法:圖片一類的靜態文件,應該放在這個static文件夾下,這個文件夾下的文件(夾)會按照本來的結構放在網站根目錄下。這時咱們再去使用/static絕對路徑,就能夠訪問這些靜態文件了。

相關文章
相關標籤/搜索