用来访问组件实例的父实例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>
用来访问组件实例的跟实例vue
当前实例的直接子组件。须要注意 $children 并不保证顺序,也不是响应式的。若是你发现本身正在尝试使用 $children 来进行数据绑定,考虑使用一个数组配合 v-for 来生成子组件,而且使用 Array 做为真正的来源。正则表达式
Vue 实例观察的数据对象。Vue 实例代理了对其 data 对象属性的访问。vue-router
当前组件接收到的 props 对象。Vue 实例代理了对其 props 对象属性的访问数组
用来挂载当前组件实例的dom元素缓存
this.$refs.scroll.$el.style ... // 访问组件实例的dom元素
一个对象,持有注册过 ref
特性 的全部 DOM
元素和组件实例
。app
获取vue实例选项dom
new Vue({ customOption: 'foo', created: function () { console.log(this.$options.customOption) // => 'foo' } })
用来访问被插槽分发的内容。每一个具名插槽 有其相应的属性 (例如:slot="foo"
中的内容将会在 vm.$slots.foo
中被找到)。default
属性包括了全部没有被包含在具名插槽中的节点。函数
在使用渲染函数书写一个组件时,访问 vm.$slots
最有帮助。post
包含了父做用域中不做为 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)//注意这里 } }
包含了父做用域中的 (不含 .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的实例,实现事件的监听和发布,实现组件之间的传递。
$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>
// 第一种写法 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` 的当前值触发回调
是Vue.set()的别名
这是全局 Vue.delete 的别名。
// 接收触发的函数 vm.$on('test', function (msg) { console.log(msg) }) vm.$emit('test', 'hi') // => "hi"
监听一个自定义事件,可是只触发一次,在第一次触发以后移除监听器。
移除自定义事件监听器。
触发当前实例上的事件。附加参数都会传给监听器回调。
挂在到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)
迫使 Vue 实例从新渲染。注意它仅仅影响实例自己和插入插槽内容的子组件,而不是全部子组件。
将回调延迟到下次 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)
彻底销毁一个实例。
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>
是Vue的内置组件,能在组件切换过程当中将状态保留在内存中,防止重复渲染DOM。
<keep-alive>
包裹动态组件时,会缓存不活动的组件实例,而不是销毁它们。他是一个抽象组件,不会渲染到DOm中
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生命周期钩子函数:activated
、deactivated
使用<keep-alive>会将数据保留在内存中,若是要在每次进入页面的时候获取最新的数据,须要在activated阶段获取数据,承担原来created钩子中获取数据的任务。
router还增长了meta属性,具体请看下面两篇文章了