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实现前进刷新,后退不刷新

相关文章
相关标签/搜索