Vue x 2.0 API

實例屬性

vm.$parent

用來訪問組件實例的父實例html

<div id="app2">
    <say-hello></say-hello>
    <my-name :name="username"></my-name>
</div>
<script>
    Vue.component("sayHello",{
        template:"<h2>Hello ${this.$parent.username} !</h2>",    //訪問父實例(app2)數據this.$parent
        delimiters:['${',"}"]  //【1】修改插值語法delimiters
    });
 
    var app2 = new Vue({
        el:"#app2",
        data:{
            month:"September",
            username:"Lily"  // 原來是Lily 
        },
        components:{
            "myName":{
                template:`<div><p>My name is {{ name }} !
                          This month is {{ this.$parent.month }} .</p>
                          <button @click="changeName">changeName</button></div>`, //訪問父實例(app2)數據this.$parent
                props:["name"],
                methods:{
                    changeName:function () {
                        // 【2】更改父組件的數據,this.$parent爲父組件實例
                        // this爲當前實例
                        this.$parent.username = "Jack";
                    }
                }
            }
        }
    });
</script>

$root

用來訪問組件實例的跟實例vue

vm.$children

當前實例的直接子組件。須要注意 $children 並不保證順序,也不是響應式的。若是你發現本身正在嘗試使用 $children 來進行數據綁定,考慮使用一個數組配合 v-for 來生成子組件,而且使用 Array 做爲真正的來源。正則表達式

vm.$data

Vue 實例觀察的數據對象。Vue 實例代理了對其 data 對象屬性的訪問。vue-router

vm.$props

當前組件接收到的 props 對象。Vue 實例代理了對其 props 對象屬性的訪問數組

vm.$el

用來掛載當前組件實例的dom元素緩存

this.$refs.scroll.$el.style ...
// 訪問組件實例的dom元素

vm.$refs

一個對象,持有註冊過 ref 特性 的全部 DOM 元素和組件實例app

vm.$options

獲取vue實例選項dom

new Vue({
  customOption: 'foo',
  created: function () {
    console.log(this.$options.customOption) // => 'foo'
  }
})

vm.$slots

用來訪問被插槽分發的內容。每一個具名插槽 有其相應的屬性 (例如:slot="foo" 中的內容將會在 vm.$slots.foo 中被找到)。default 屬性包括了全部沒有被包含在具名插槽中的節點。函數

在使用渲染函數書寫一個組件時,訪問 vm.$slots 最有幫助。post

vm.$attrs

包含了父做用域中不做爲 prop 被識別 (且獲取) 的特性綁定 (class 和 style 除外)。

當一個組件沒有聲明任何 prop 時,這裏會包含全部父做用域的綁定 (class 和 style 除外),而且能夠經過 v-bind="$attrs" 傳入內部組件——在建立高級別的組件時很是有用。

這是官網給出的,有點繞,咱們仍是從例子來看吧

<template>
  <div class="home">
    <mytest  :title="title" :massgae="massgae"></mytest>
  </div>
</template>
<script>
export default {
  name: 'home',
  data () {
    return {
      title:'title1111',
      massgae:'message111'
    }
  },
  components:{
    'mytest':{
      template:`<div>這是個h1標題{{title}}</div>`,
      props:['title'],
      // 【1】 這裏只註冊了一個
      data(){
        return{
          mag:'111'
        }
      },
      created:function(){
        // 【2】 打印出來是 {message: message111}  
        console.log(this.$attrs)//注意這裏
      }
    }
  }
}
</script>

咱們看到:組件內未被註冊的屬性將做爲普通html元素屬性被渲染,若是想讓屬性可以向下傳遞,即便prop組件沒有被使用,你也須要在組件上註冊。

Vue2.4.0,能夠在組件定義中添加inheritAttrs:false,組件將不會把未被註冊的props呈現爲普通的HTML屬性。可是在組件裏咱們能夠經過其$attrs能夠獲取到沒有使用的註冊屬性,若是須要,咱們在這也能夠往下繼續傳遞。

components:{
    'mytest':{
      template:`<div>這是個h1標題{{title}}</div>`,
      props:['title'],
      inheritAttrs: false,
      // 【3】 這裏爲 inheritAttrs = false
      data(){
        return{
          mag:'111'
        }
      },
      created:function(){
        console.log(this.$attrs)//注意這裏
      }
    }

vm.$listeners

包含了父做用域中的 (不含 .native 修飾器的) v-on 事件監聽器。它能夠經過 v-on="$listeners" 傳入內部組件——在建立更高層次的組件時很是有用。


場景

A 組件與 B 組件之間的通訊: (父子組件)

每每數據在不須要全局的狀況而僅僅是父子組件通訊時,使用第一種方式便可知足。

1. A to B 經過props的方式向子組件傳遞,B to A 經過在 B 組件中 $emit, A 組件中 v-on 的方式實現

2. 經過設置全局Vuex共享狀態,經過 computed 計算屬性和 commit mutation的方式實現數據的獲取和更新,以達到父子組件通訊的目的。

3. Vue Event Bus,使用Vue的實例,實現事件的監聽和發佈,實現組件之間的傳遞。

A 組件與 C 組件之間的通訊: (跨多級的組件嵌套關係)

1. 藉助 B 組件的中轉,從上到下props依次傳遞,從下至上,$emit事件的傳遞,達到跨級組件通訊的效果
2. 藉助Vuex的全局狀態共享
3. Vue Event Bus,使用Vue的實例,實現事件的監聽和發佈,實現組件之間的傳遞。
  • 第一種經過props和$emit的方式,使得組件之間的業務邏輯臃腫不堪,B組件在其中僅僅充當的是一箇中轉站的做用。
  • 使用第二種 Vuex的方式,某些狀況下彷佛又有點大材小用的意味,(僅僅是想實現組件之間的一個數據傳遞,並不是數據共享的概念)
  • 第三種狀況的使用在實際的項目操做中發現,如不能實現很好的事件監聽與發佈的管理,每每容易致使數據流的混亂,在多人協做的項目中,不利於項目的維護。
$attrs以及 $listeners的出現解決的就是第一種狀況的問題
// app.vue
<template>
 <div id="app">
 <child1
      :p-child1="child1"  // 【1】 傳第一個值
      :p-child2="child2" // 【2】 傳第二個值
      v-on:test1="onTest1" //此處監聽了兩個事件,能夠在B組件或者C組件中直接觸發
      v-on:test2="onTest2">
 </child1>
 </div>
</template>
<script>
import Child1 from "./Child1.vue";

export default {
  data() {
    return {};
  },
  components: { Child1 },
  methods: {
    onTest1() {
      // 子組件觸發
      console.log("test1 running...");
    },
    onTest2() {
      console.log("test2 running");
    }
  }
};
</script>
// child1.vue

<template>
 <div class="child-1">
 <p>in child1:</p>
 <p>props: {{pChild1}}</p>
 <p>$attrs: {{$attrs}}</p>
 <hr>
 <!-- C組件中能直接觸發test的緣由在於 B組件調用C組件時 使用 v-on 綁定了$listeners 屬性 -->
 <!-- 經過v-bind 綁定 $attrs 屬性,C組件能夠直接獲取到A組件中傳遞下來的props(除了B組件中props聲明的) -->
 <child2 v-bind="$attrs" v-on="$listeners"></child2>
 </div>
</template>
<script>
import Child2 from "./Child2.vue";
export default {
  // 【1】接受了一個數據
  props: ["pChild1"],
  data() {
    return {};
  },
  inheritAttrs: false,
  // 【2】設置爲false
  components: { Child2 },
  mounted() {
    // 【3】 經過$emit 與父組件通訊
    this.$emit("test1");
  }
};
</script>
// child2.vue

<template>
 <div class="child-2">
 <p>in child2:</p>
 <p>props: {{pChild2}}</p>
 <p>$attrs: {{$attrs}}</p>
 <hr>
 </div>
</template>
<script>
export default {
  props: ["pChild2"],
  data() {
    return {};
  },
  inheritAttrs: false,
  mounted() {
    //  【1】 能夠直接觸發
    this.$emit("test2");
  }
};
</script>

實例方法 | 數據

vm.$watch

// 第一種寫法
watch: {
  text(new, old) {
    console.log(`${new}:${old}`);
  }
}

// 第二種寫法
const unWatch = this.$watch('text',(new,old)=>
  console.log(`${new}:${old}`);
})
// 返回一個取消觀察函數,用來中止觸發回調

// 2秒後銷燬 unWatch
setTimeout(()=> {
  unWatch(); // 取消觀察
},2000)

// 兩種寫法的結果同樣,只是第二種須要在組件銷燬手動銷燬$watch

選項

//  爲了發現【對象內部值的變化】,能夠在選項參數中指定 deep: true
vm.$watch('someObject', callback, {
  deep: true
})

// 在選項參數中指定 immediate: true 將當即以表達式的當前值觸發回調:
vm.$watch('a', callback, {
  immediate: true
})
// 當即以 `a` 的當前值觸發回調

vm.$set

是Vue.set()的別名

vm.$delete

這是全局 Vue.delete 的別名。

實例方法 | 事件

vm.$on(event, callback)

// 接收觸發的函數
vm.$on('test', function (msg) {
  console.log(msg)
})

vm.$emit('test', 'hi')
// => "hi"

vm.$once( event, callback )

監聽一個自定義事件,可是隻觸發一次,在第一次觸發以後移除監聽器。

vm.$off

移除自定義事件監聽器。

vm.$emit(event, [...args])

觸發當前實例上的事件。附加參數都會傳給監聽器回調。

實例方法 | 生命週期

vm.$mount()

掛在到dom

var MyComponent = Vue.extend({
  template: '<div>Hello!</div>'
})

// 建立並掛載到 #app (會替換 #app)
new MyComponent().$mount('#app')


// 同上
new MyComponent({ el: '#app' })

// 或者,在文檔以外渲染而且隨後掛載
var component = new MyComponent().$mount()
document.getElementById('app').appendChild(component.$el)

vm.$forceUpdate

迫使 Vue 實例從新渲染。注意它僅僅影響實例自己和插入插槽內容的子組件,而不是全部子組件。

vm.$nextTick(callback)

將回調延遲到下次 DOM 更新循環以後執行。在修改數據以後當即使用它,而後等待 DOM 更新。它跟全局方法 Vue.nextTick 同樣,不一樣的是回調的 this 自動綁定到調用它的實例上。
//
new Vue({
  // ...
  methods: {
    // ...
    example: function () {
      // 修改數據
      this.message = 'changed'
      // DOM 尚未更新
      this.$nextTick(function () {
        // DOM 如今更新了
        // `this` 綁定到當前實例
        this.doSomethingElse()
      })
    }
  }
})
// 若是你要修改某個dom元素的值或者狀態,當你修改完後,還想要繼續使用改dom去完成接下來的操做。
// 那麼這裏最好只用nextTick等待dom更新完畢以後再操做(這個延時差很少是20ms)
//能夠用下面代替

setTimeOut(() => {
    // 
}, 20)

vm.$destroy()

徹底銷燬一個實例。


propsData

Vue.extend的propsData 用得不多,僅用於開發環境

// vue.extend()主要用於生產組件

<body>
<h1>Vue.extend的propsData 用得不多,僅用於開發環境</h1>
<div id="head2"></div>
<script>
    var CommonHeader = Vue.extend({
        template:"<header>我是網站頭部 {{ message }}  -by {{ username }}</header>",
        data:function () {
            return{
                message:"I am message!"
            }
        },
        props:['username']
    });
    var header = new CommonHeader({
        propsData:{
            username:"wss"
        }
    }).$mount("#head2");
 
</script>
</body>

keep-alive

<keep-alive>是Vue的內置組件,能在組件切換過程當中將狀態保留在內存中,防止重複渲染DOM。

<keep-alive> 包裹動態組件時,會緩存不活動的組件實例,而不是銷燬它們。他是一個抽象組件,不會渲染到DOm中

  • include: 字符串或正則表達式。只有匹配的組件會被緩存。
  • exclude: 字符串或正則表達式。任何匹配的組件都不會被緩存。
1.用在動態組件中
<keep-alive include="test-keep-alive">
  <!-- 將緩存name爲test-keep-alive的組件 -->
  <component></component>
</keep-alive>

<keep-alive include="a,b">
  <!-- 將緩存name爲a或者b的組件,結合動態組件使用 -->
  <component :is="view"></component>
</keep-alive>

<!-- 使用正則表達式,需使用v-bind -->
<keep-alive :include="/a|b/">
  <component :is="view"></component>
</keep-alive>

<!-- 動態判斷 -->
<keep-alive :include="includedVar">
  <router-view></router-view>
</keep-alive>

<keep-alive exclude="test-keep-alive">
  <!-- 將不緩存name爲test-keep-alive的組件 -->
  <component></component>
</keep-alive>
結合router-view
<keep-alive>
    <router-view></router-view>
</keep-alive>
// 再路由跳轉中若是組件沒有變化,則進行緩衝

keep-alive生命週期鉤子函數:activateddeactivated

使用<keep-alive>會將數據保留在內存中,若是要在每次進入頁面的時候獲取最新的數據,須要在activated階段獲取數據,承擔原來created鉤子中獲取數據的任務。

router還增長了meta屬性,具體請看下面兩篇文章了

vue-router 之 keep-alive

vue實現前進刷新,後退不刷新

相關文章
相關標籤/搜索