vue构造函数(根实例化时和组件实例对象选项)参数:选项详解

实例选项(即传给构造函数的options):数据,DOM,生命周期钩子函数,资源,组合,其余html

数据

data

属性可以响应数据变化,当这些数据改变时,视图会进行重渲染。vue

访问方式:node

一、经过 vm.$data 访问。ajax

var data = { a: 1 }
var vm = new Vue({
  el: '#example',
  data: data
})

vm.$data === data// => true vm.$el === document.getElementById('example') // => true

二、Vue 实例代理(以 _$ 开头的属性 不会 被 Vue 实例代理)了 data 对象上全部的属性。express

// 咱们的数据对象
var data = { a: 1 }

// 该对象被加入到一个 Vue 实例中
var vm = new Vue({
  data: data
})

// 得到这个实例上的属性
// 返回源数据中对应的字段
vm.a == data.a // => true

在组件中:编程

一、data 必须为返回一个初始数据对象的函数,由于组件可能被用来建立多个实例。若是 data 仍然是一个纯粹的对象,则全部的实例将共享引用同一个数据对象!经过函数的return,每次返回的是不一样的对象。api

二、每次建立一个新实例后,调用 data 函数会返回初始数据的一个全新副本数据对象。数组

拷贝原始数据对象:缓存

vm.$data 传入 JSON.parse(JSON.stringify(...)) 获得深拷贝的原始数据对象。app

注意:

一、data做为函数时若是使用了箭头函数,则 this 不会指向这个组件的实例,函数的第一个参数将是实例。

data: vm => ({ a: vm.myProp })

二、只有当实例被建立时 data 中存在的属性才是响应式的。

三、使用Object.freeze()对data对象属性冻结,data再也不是响应式。

使用建议:

一、推荐在建立实例以前,就声明全部的根级响应式属性。

二、后续才须要的某个属性,可是一开始它为空或不存,设置一些初始值,保证它是响应式的。

props

能够是数组或对象,用于接收来自父组件的数据,定义了当前组件有哪些可配置的属性。

当一个值传递给一个 prop 特性的时候,它就变成了那个组件实例的一个属性。

<script>
  var obj = {
    props:{
      parentDataA:Number
    },
    mounted(){
      console.log(this.parentDataA);
    }
  };
    export default obj;
</script>

使用建议:

(1)写通用组件时,props最好用对象的写法,针对每一个属性设置类型、默认值或自定义校验属性的值,是组件比较严谨。当 prop 验证失败的时候,(开发环境构建版本的) Vue 将会产生一个控制台的警告。

//类型检测String、Number、Boolean、Array、Object、Date、Function、Symbol
Vue.component('my-component', {
  props: {
        propA: Number,// 基础的类型检查 (`null` 和 `undefined` 会经过任何类型验证)
        propB: [String, Number], // 多个可能的类型
        propC: {// 必填的字符串
              type: String,
              required: true
        },
         propD: { // 带有默认值的数字
              type: Number,
              default: 100
        },    
        propE: {// 带有默认值的对象
              type: Object,
              default: function () {// 对象或数组默认值必须从一个工厂函数获取
                return { message: 'hello' }
              }
        },
        propF: { // 自定义验证函数
              validator: function (value) {
              // 这个值必须匹配下列字符串中的一个
              return ['success', 'warning', 'danger'].indexOf(value) !== -1
      }
    }
  }
})                            

(2)在dom中,使用短横线分隔命名,在js中使用时是驼峰命名。

(3)是单向数据流,不该该在子组件中更改prop,会报错。能够在data中定义或者在computed中定义对应的属性。注意:对于一个数组或对象类型的 prop 来讲,在子组件中改变这个对象或数组自己将会影响到父组件的状态。

4)prop 会在一个组件实例建立以前进行验证,因此实例的属性 (如 datacomputed 等) 在 defaultvalidator 函数中是不可用的。

propsData

只用于 new 的实例中,用在全局扩展(extend)时进行传递数据。在实例化extend的构造器时,传入属性必须是propsData、而不是props哦。实例中props接收propsData,把props的数据做为测试数据。

不推荐用全局扩展的方式做自定义标签,彻底可使用组件来作,propsData在实际开发中咱们使用的并很少。另外的例子,能够见全局API中的extend部分。

var Comp = Vue.extend({
  props: ['msg'],
  template: '<div>{{ msg }}</div>'
})

var vm = new Comp({
  propsData: {
    msg: 'hello'
  }
})

computed

计算实例的属性,this 上下文自动地绑定为 Vue 实例。箭头函数this不会指向实例,须要显示传入vm。

computed: {
  aDouble: vm => vm.a * 2
}

计算属性的结果会被缓存,除非依赖的响应式属性变化才会从新计算。

var vm = new Vue({
  data: { a: 1 },
  computed: {
    // 仅读取
    aDouble: function () {
      return this.a * 2
    },
    // 读取和设置
    aPlus: {
      get: function () {
        return this.a + 1
      },
      set: function (v) {
        this.a = v - 1
      }
    }
  }
})

计算属性默认只有 getter ,想改变实例属性,能够提供一个 setter。在getter中改变实例属性,eslint开启的状况下会报错。

使用建议:

一、在get中,不要改变实例属性,而是经过set来改变。

二、计算属性依赖响应式属性,注意它的使用场合和methods以及watch区分。

methods

可经过实例访问这些方法或在指令表达式或在模板插值中使用。方法中的 this 自动绑定为 Vue 实例。

注意,不该该使用箭头函数来定义 method 函数this 不会指向 Vue 实例。

经常使用姿式:

methods: {
    greet: function (event) {
      // `this` 在方法里指向当前 Vue 实例
      alert('Hello ' + this.name + '!')
      // `event` 是原生 DOM 事件
      if (event) {
        alert(event.target.tagName)
      }
    },
   say(str,event){
     //...
    },
    console(){
    //...
    }
  }
//直接调用或者传参调用,都有event传入
<button v-on:click="greet">Greet</button> 
<button v-on:click="greet($event)">Greet</button> 

//多个参数时,event事件要显示传入
<button v-on:click="say('what',$event)">Say what</button>

//由实例代理,直接被调用
vm.console()//

事件修饰符

使用修饰符时,顺序很重要;相应的代码会以一样的顺序产生。

所以,用 v-on:click.prevent.self 会阻止全部的点击,而 v-on:click.self.prevent 只会阻止对元素自身的点击。

<!-- 阻止单击事件继续传播 -->
<a v-on:click.stop="doThis"></a>
<!-- 提交事件再也不重载页面 -->
<form v-on:submit.prevent="onSubmit"></form>
<!-- 修饰符能够串联 -->
<a v-on:click.stop.prevent="doThat"></a>
<!-- 只有修饰符 -->
<form v-on:submit.prevent></form>
<!-- 添加事件监听器时使用事件捕获模式 -->
<!-- 即元素自身触发的事件先在此处理,而后才交由内部元素进行处理 -->
<div v-on:click.capture="doThis">...</div>
<!-- 只当在 event.target 是当前元素自身时触发处理函数 -->
<!-- 即事件不是从内部元素触发的 -->
<div v-on:click.self="doThat">...</div>
<!--2.1.4 新增 点击事件将只会触发一次 ,还能被用到自定义的组件事件上-->
<a v-on:click.once="doThis"></a>

<!-- 滚动事件的默认行为 (即滚动行为) 将会当即触发 -->
<!-- 而不会等待 `onScroll` 完成  -->
<!-- 这其中包含 `event.preventDefault()` 的状况 -->
<!--这个 .passive 修饰符尤为可以提高移动端的性能 -->
<!--不要把 .passive 和 .prevent 一块儿使用-->
<div v-on:scroll.passive="onScroll">...</div>

使用建议:

通常使用在事件上面,大部分时候可使用computed代替methods和watch。

watch

key为要观察的表达式,值为对应的回调函数,当表达式的值改变,就触发回调。

回调函数能够是方法名(字符串形式),方法,或者包含配置选项的对象。

注意:Vue 实例将会在实例化时调用 $watch(),遍历 watch 对象的每个属性,此时要是设置了immediate为true,其handle会当即被调用。

watch: {
    a: function (val, oldVal) {
      console.log('new: %s, old: %s', val, oldVal)
    },
       b: 'someMethod', // 方法名
       c: {
      handler: function (val, oldVal) { /* ... */ },
      deep: true // 深度 watcher,当监听的是一个对象的时候,指定deep: true可监听对象内部值的变化

    },
       d: {
      handler: function (val, oldVal) { /* ... */ },
      immediate: true // 该回调将会在侦听开始以后当即以表达式的当前值触发回调
    },
    e: [
      'handle1',
      function handle2 (val, oldVal) { /* ... */ },
      {
        handler: function handle3 (val, oldVal) { /* ... */ },
        /* ... */
      }
    ],
    // watch vm.e.f's value: {g: 5}
    'e.f': function (val, oldVal) { /* ... */ }
  }

更复杂的表达式可使用vm.$watch处理,用一个函数取代,回调函数参数为新值和旧值。

(在变异 (不是替换) 对象或数组时,旧值与新值相同,指向同一个引用)

// 函数
vm.$watch(
  function () {
    // 表达式 `this.a + this.b` 每次得出一个不一样的结果时
    // 处理函数都会被调用。
    // 这就像监听一个未被定义的计算属性
    return this.a + this.b
  },
  function (newVal, oldVal) {
    // 作点什么
  }
)

vm.$watch 返回一个取消观察函数,用来中止触发回调:

var unwatch = vm.$watch('a', cb)
// 以后取消观察
unwatch()

computed,methods,watch的使用场景

一、大部分时候都使用computed

 data: {
    firstName: 'Foo',
    lastName: 'Bar',
    fullName: 'Foo Bar'
  }

computed: {
  fullName: {
    // getter
    get: function () {
      return this.firstName + ' ' + this.lastName
    },
    // setter
    set: function (newValue) {
      var names = newValue.split(' ')
      this.firstName = names[0]
      this.lastName = names[names.length - 1]
    }
  }
}

二、通常在事件里调用methods

三、当须要在数据变化时执行异步或开销较大的操做时,使用watch。

Dom

el

只在 new 实例时传入,不在组件中使用。值为页面上已存在的 DOM 元素,做为 Vue 实例的挂载目标。

能够是 CSS 选择器,也能够是一个 HTMLElement 实例。

template

字符串模板

若是值以 # 开始,则它将被用做选择符,并使用匹配元素的 innerHTML 做为模板。

<template id="myComponent">
            <div>This is a component!</div>
</template>
  Vue.component('my-component',{
            template: '#myComponent'
  })

若是为标签字符串,模板将会 替换 挂载的元素。挂载元素的内容都将被忽略,除非模板的内容有分发插槽。

new Vue({
el: '#app',
components:{App},
template: '<App/>'
})

这里面涉及到一个简写的处理,若是你不在组件上面添加属性或者指令的话,你就能够写成单标签的形式 <App/>其实就是 ‘ <App><App/>’

el: '#app' 是index.html 的<div id="app"></div>

App.vue 的<div id="app">xxxxxxxx</div> 会替换index中的<div id="app"></div> 。

components 是声明有哪些组件,能够放多个组件对象,好比:components:{App,App2,App3}

template 是使用哪一个组件,若是想用App2,则须要设置template: '<App2/>'。

render函数

字符串模板(template)的代替方案,多用于动态生成dom的场景,容许你发挥 JavaScript 最大的编程能力。

createElement 方法做为第一个参数用来建立 VNode

好比:某个组件,经过level这个prop来控制模板里内容的生成

<anchored-heading :level="1">Hello world!</anchored-heading>

使用template写法:

<script type="text/x-template" id="anchored-heading-template">
  <h1 v-if="level === 1">
    <slot></slot>
  </h1>
  <h2 v-else-if="level === 2">
    <slot></slot>
  </h2>
  <h3 v-else-if="level === 3">
    <slot></slot>
  </h3>
......4,5,6...
</script>

使用render:

Vue.component('anchored-heading', {
  render: function (createElement) {
    return createElement(
      'h' + this.level,   // 标签名称
      this.$slots.default // 子元素数组
    )
  },
  props: {
    level: {
      type: Number,
      required: true
    }
  }
})

 vm.$slots查阅博文:slot

createElement函数(能够理解为document.createElement,只是参数不一样而已),用于生成“虚拟节点 (Virtual Node)”,也常简写它为“VNode”。

函数接收三个参数:
参数一: {String | Object | Function}, HTML 标签字符串,组件选项对象,或者解析上述任何一种的一个 async 异步函数。必需参数。
参数二:包含模板相关属性的数据对象
能够在 template 中使用这些特性。可选参数。
参数三:{String | Array},子虚拟节点 (VNodes),也可使用字符串来生成“文本虚拟节点”。可选参数。

[
    '先写一些文字',
    createElement('h1', '一则头条'),
    createElement(MyComponent, {
      props: {
        someProp: 'foobar'
      }
    })
  ]

使用render的经常使用姿式:

一、除了代替上面的v-if和v-for功能(即不要把渲染逻辑写在模板里)

<ul v-if="items.length">
  <li v-for="item in items">{{ item.name }}</li>
</ul>
<p v-else>No items found.</p>

//使用render
props: ['items'],
render: function (createElement) {
  if (this.items.length) {
    return createElement('ul', this.items.map(function (item) {
      return createElement('li', item.name)
    }))
  } else {
    return createElement('p', 'No items found.')
  }
}

二、还能经过数据对象实现v-model:

props: ['value'],
render: function (createElement) {
  var self = this
  return createElement('input', {
    domProps: {
      value: self.value
    },
    on: {
      input: function (event) {
        self.$emit('input', event.target.value)
      }
    }
  })
}

三、使用render 函数渲染屡次重复的元素/组件 。下例渲染了 20 个相同的段落:

render: function (createElement) {
  return createElement('div',
    Array.apply(null, { length: 20 }).map(function () {
      return createElement('p', 'hi')
    })
  )
}

renderError函数

只在开发者环境下工做,当 render 函数遭遇错误时,其错误将会做为renderError函数的第二个参数。这个功能配合 hot-reload 很是实用。

new Vue({
  render (h) {
    throw new Error('oops')
  },
  renderError (h, err) {
    return h('pre', { style: { color: 'red' }}, err.stack)
  }
}).$mount('#app')

生命周期钩子函数

一共十一个函数。

通常实例里有的生命周期钩子函数:beforeCreate,created,beforeMount,mounted,beforeUpdate,updated,beforeDestroy,destroyed,errorCaptured

beforecreated:el 和 data (即实例的属性)并未初始化
created:完成了 data 等属性的初始化(数据观测 (data observer),属性和方法的运算,watch/event 事件回调),el没有。
beforeMount:完成了 el 和 data 初始化 ,相关的 render 函数首次被调用。
mounted :完成挂载,把值渲染进el里。

注意 mounted 不会承诺全部的子组件也都一块儿被挂载。若是你但愿等到整个视图都渲染完毕,能够用 vm.$nextTick 替换掉 mounted

mounted: function () {
  this.$nextTick(function () {
    // Code that will run only after the
    // entire view has been rendered
  })
}

 

beforeUpdate:指view层的数据变化前,不是data中的数据改变前触发。适合在更新以前访问现有的 DOM,好比手动移除已添加的事件监听器。

updated:组件 DOM 已经更新,能够执行依赖于 DOM 的操做。若是要相应状态改变,一般使用计算属性watcher 取代updated。

destroyed:Vue 实例销毁后调用。能够这么理解,执行了destroy操做,后续就再也不受vue控制了。

errorCaptured:当捕获一个来自子孙组件的错误时被调用。

 

activated与deactivated:

在被keep-alive包含的组件/路由中,会多出两个生命周期的钩子: activated 与 deactivated。

activated在组件第一次渲染时会被调用,以后在每次缓存组件被激活时调用。

使用了keep-alive就不会调用beforeDestroy(组件销毁前钩子)和destroyed(组件销毁),由于组件没被销毁,被缓存起来了,再次进入缓存路由/组件时,不会触发这些钩子:

beforeCreate ,created ,beforeMount, mounted

生命周期钩子注意的点:

一、ajax请求最好放在created里面,由于此时已经能够访问this了,请求到数据就能够直接放在data里面。 
二、关于dom的操做要放在mounted里面,在mounted前面访问dom会是undefined。
三、每次进入/离开组件都要作一些事情,用什么钩子:

(1)不缓存:
进入的时候能够用created和mounted钩子,离开的时候用beforeDestory和destroyed钩子,beforeDestory能够访问this,destroyed不能够访问this。
(2)缓存了组件:
缓存了组件以后,再次进入组件不会触发beforeCreate、created 、beforeMount、 mounted,若是你想每次进入组件都作一些事情的话,你能够放在activated进入缓存组件的钩子中。
同理:离开缓存组件的时候,beforeDestroy和destroyed并不会触发,可使用deactivated离开缓存组件的钩子来代替。


将路由导航、keep-alive、和组件生命周期钩子结合起来的触发顺序:

假设是从a组件离开,第一次进入b组件:

1- beforeRouteLeave:路由组件的组件离开路由前钩子,可取消路由离开。
2- beforeEach: 路由全局前置守卫,可用于登陆验证、全局路由loading等。
3- beforeEnter: 路由独享守卫
4- beforeRouteEnter: 路由组件的组件进入路由前钩子。
5- beforeResolve:路由全局解析守卫
6- afterEach:路由全局后置钩子
7- beforeCreate:组件生命周期,不能访问this。
8- created:组件生命周期,能够访问this,不能访问dom。
9- beforeMount:组件生命周期
10- deactivated: 离开缓存组件a,或者触发a的beforeDestroy和destroyed组件销毁钩子。
11- mounted:访问/操做dom。
12- activated:进入缓存组件,进入a的嵌套子组件(若是有的话)。
13- 执行beforeRouteEnter回调函数next。

 资源

directives函数自定义指令

分为全局和局部自定义指令:

//全局
// 注册一个全局自定义指令 `v-focus`
Vue.directive('focus', {
  // 当被绑定的元素插入到 DOM 中时……
  inserted: function (el) {
    // 聚焦元素
    el.focus()
  }
})

//局部,组件中定义一个 directives 的选项
directives: {
  focus: {// 指令的定义
        inserted: function (el) {//指令的钩子函数
      el.focus()
    }
  }
}

自定义指令对象(好比focus这个对象)的钩子函数:

bind:只调用一次,指令第一次绑定到元素时调用。在这里能够进行一次性的初始化设置。

inserted:被绑定元素插入父节点时调用 (仅保证父节点存在,但不必定已被插入文档中)。

update:所在组件的 VNode 更新时调用,可是可能发生在其子 VNode 更新以前。指令的值可能发生了改变,也可能没有。可是你能够经过比较更新先后的值来忽略没必要要的模板更新 (详细的钩子函数参数见下)。

componentUpdated:指令所在组件的 VNode 及其子 VNode 所有更新后调用。

unbind:只调用一次,指令与元素解绑时调用。

 钩子函数参数: el、bindingvnodeoldVnode。

el:指令所绑定的元素,能够用来直接操做 DOM 。

binding:对象,有如下属性:

  • name:指令名,不包括 v- 前缀。
  • value:指令的绑定值,例如:v-my-directive="1 + 1" 中,绑定值为 2
  • oldValue:指令绑定的前一个值,仅在 updatecomponentUpdated 钩子中可用。不管值是否改变均可用。
  • expression:字符串形式的指令表达式。例如 v-my-directive="1 + 1" 中,表达式为 "1 + 1"
  • arg:传给指令的参数,可选。例如 v-my-directive:foo 中,参数为 "foo"
  • modifiers:一个包含修饰符的对象。例如:v-my-directive.foo.bar 中,修饰符对象为 { foo: true, bar: true }

vnode:Vue 编译生成的虚拟节点。移步 VNode API 来了解更多详情。

oldVnode:上一个虚拟节点,仅在 updatecomponentUpdated 钩子中可用。

钩子函数简写:

bindupdate 时触发相同行为,而不关心其它的钩子,directive第二个参数是函数而不是对象。

Vue.directive('color-swatch', function (el, binding) {
  el.style.backgroundColor = binding.value
})

指令函数可以接受全部合法的 JavaScript 表达式,好比binding.value能够是一个对象字面量:

<div v-demo="{ color: 'white', text: 'hello!' }"></div>

Vue.directive('demo', function (el, binding) {
  console.log(binding.value.color) // => "white"
  console.log(binding.value.text)  // => "hello!"
})

使用姿式:

注册局部指令比较多,通常在组件中用来初始化dom。

filters过滤器

分为全局和局部过滤器。

使用场景:用于一些常见的文本格式化(日期格式化,字符转换,金额处理,input输入处理等)

注意:

一、过滤器内是没有this引用的,过滤器内的this是undefined,因此不要在过滤器内尝试使用this引用组件实例的变量或者方法。

二、过滤器函数始终以表达式的值做为第一个参数。带引号的参数视为字符串,而不带引号的参数按表达式计算。

三、能够设置两个过滤器参数,前提是这两个过滤器处理的不冲突

四、全局定义过滤器,在建立 Vue 实例以前

五、直接注册在Vue全局上面,其余不用这个过滤器的实例也会被迫接受,因此要注意区分哪些注册在全局,哪些注册为局部

用法:双花括号插值和 v-bind 表达式 (后者从 2.1.0+ 开始支持),被添加在 JavaScript 表达式的尾部,由“管道”符号指示:

<!-- 在双花括号中,capitalize过滤器函数将会收到  的值做为第一个参数-->
{{ message | capitalize }}

<!-- 在 `v-bind` 中 -->
<div v-bind:id="rawId | formatId"></div>

<!-- 过滤器能够串联 ,filterA 的结果传递到 中-->

{{ message | filterA | filterB }}

<!-- 过滤器是 JavaScript 函数,所以能够接收参数,message 的值做为第一个参数,普通字符串 做为第二个参数,表达式 的值做为第三个参数。-->
{{ message | filterA('arg1', arg2) }}
messagefilterB'arg1'arg2

局部(本地)过滤器:在一个组件的选项中定义本地的过滤器

filters: {
  capitalize: function (value) {
    if (!value) return ''
    value = value.toString()
    return value.charAt(0).toUpperCase() + value.slice(1)
  }
}

在建立 Vue 实例以前全局定义过滤器:

Vue.filter('capitalize', function (value) {
  if (!value) return ''
  value = value.toString()
  return value.charAt(0).toUpperCase() + value.slice(1)
})

new Vue({
  // ...
})

用户从input输入的数据在回传到model以前也能够先处理

<input type="text" v-model="message | change"> <!--用户从input输入的数据在回传到model以前也能够先处理-->

 Vue.filter("change", {
                read: function (value) { // model -> view 在更新 `<input>` 元素以前格式化值
                    return value;
                },
                write: function (newVal,oldVal) { // view -> model  在写回数据以前格式化值
                    console.log("newVal:"+newVal); 
                    console.log("oldVal:"+oldVal);
                    return newVal;
                }
            });

            var myVue = new Vue({
                el: ".test",
                data: {
                    message:12
                }
            });

components组件列表

页面须要用到的组件列表,书写形式以下。

//引入组件
import HelloWorld from "./components/HelloWorld";
//在页面实例注入组件
 components: {
    HelloWorld
  },
//在页面使用组件
<HelloWorld />
或者
<HelloWorld><HelloWorld />

 参考博文:vue学习之组件

$slots

 查阅博文slot

组合

 parent指定父实例

值为父实例实例。parent指定实例的父实例,子实例能够用 this.$parent 访问父实例,子实例被推入父实例的 $children 数组中。

mixins

分为全局混入和局部混入。

 值为成员是对象的数组,对象的key能够是任意的实例选项。可在多组件中复用某些功能。

// 定义一个混入对象
var myMixin = {
  created: function () {
    this.hello()
  },
  methods: {
    hello: function () {
      console.log('hello from mixin!')
    }
  }
}

// 定义一个使用混入对象的组件
var Component = Vue.extend({
  mixins: [myMixin]
})

var component = new Component() // => "hello from mixin!"

当组件和混入对象含有同名选项时,不一样选项的混合规则:

(1)data

 先与data的属性合并,发生冲突时以组件数据优先。

(2)生命周期钩子函数

将混合为一个数组,都将被调用,混入对象的钩子将在组件自身钩子以前调用。

(3)值为对象类型的选项,如methods, components 和directives

混合为同一个对象。两个对象键名冲突时,取组件对象的键值对。

全局注册混入对象:

// 为自定义的选项 'myOption' 注入一个处理器。
Vue.mixin({
  created: function () {
    var myOption = this.$options.myOption
    if (myOption) {
      console.log(myOption)
    }
  }
})

new Vue({
  myOption: 'hello!'
})
// => "hello!"

注意使用! 一旦使用全局混入对象,将会影响到以后建立的全部 Vue 实例(包括第三方模板)。使用恰当时,能够为自定义对象注入处理逻辑。大多数状况下,只应当应用于自定义选项,就像上面示例同样。也能够将其用做 Plugins 以免产生重复应用

extends

mixins 相似,用于扩展(混合)实例,区别大概就在于它是一个对象,mixins是个数组

let baseOptions= {
    created(){
        console.log('onCreated-1');
    }
};

new Vue({
    extends: baseOptions,
    created(){
        //do something
        console.log('onCreated-2');
    }
    //其余自定义逻辑
});
// -> onCreated-1
// -> onCreated-2

 provide/inject

这对选项须要一块儿使用,容许一个祖先组件向其全部子孙后代注入一个依赖,不论组件层次有多深,并在起上下游关系成立的时间里始终生效。

主要为高阶插件/组件库提供用例。并不推荐直接用于应用程序代码中。

provide 和 inject 绑定并非可响应的,若是传入了一个可监听的对象,那么其对象的属性仍是可响应的。

provide 选项:一个对象或返回一个对象的函数,指定想要提供给后代组件的数据/方法。

inject 选项:在任何后代组件里,使用 inject 选项来接收想要添加在这个实例上的属性。

inject 选项值:

  • 一个字符串数组
  • 一个对象,对象的 key 是本地的绑定名,value 是:
    • 在可用的注入内容中搜索用的 key (字符串或 Symbol),或
    • 一个对象,该对象的:
      • from 属性是在可用的注入内容中搜索用的 key (字符串或 Symbol)
      • default 属性是降级状况下使用的 value

使用场景:

  • 祖先组件不须要知道哪些后代组件使用它提供的属性
  • 后代组件不须要知道被注入的属性来自哪里(能够从多个祖先哪里得到)

栗子:

// 父级组件提供 'foo'
var Provider = {
  provide: {
    foo: 'bar'
  },
  // ...
}

// 子组件注入 'foo'
var Child = {
  inject: ['foo'],
  created () {
    console.log(this.foo) // => "bar"
  }
  // ...
}

//使用一个注入的值做为一个属性的默认值,Vue 2.2.1 或更高版本
const Child = {
  inject: ['foo'],
  props: {
    bar: {
      default () {
        return this.foo
      }
    }
  }
}
//使用一个注入的值做为数据入口,Vue 2.2.1 或更高版本
const Child = {
  inject: ['foo'],
  data () {
    return {
      bar: this.foo
    }
  }
}

//在 2.5.0+ 的注入能够经过设置默认值使inject变成可选项,或从一个不一样名字的属性注入
const Child = {
  inject: {
    foo: {
      from: 'bar',
      default: 'foo'
    }
  }
}
const Child = {
  inject: {
    foo: {
      from: 'bar',
      default: () => [1, 2, 3]
    }
  }
}

选项的其余key

name

组件的选项,组件名

delimiters

Vue默认的插值是双大括号{{}},delimiters定义插值符号新的写法:

new Vue({
  delimiters: ['${', '}']//插值形式就变成了${}。代替了{{ }} })

functional

设置为 true 后,就可让组件变为无状态、无实例的函数化组件。由于只是函数,因此渲染的开销相对来讲较小,用一个简单的 render 函数返回虚拟节点使他们更容易渲染。

函数化的组件中的 Render 函数,提供了第二个参数 context 做为上下文,data、props、slots、children 以及 parent 均可以经过 context 来访问。

暂时没搞明白:

Vue学习笔记进阶篇——函数化组件

说说 Vue.js 中的 functional 函数化组件:很好的例子

应用场景

函数化组件不经常使用,它应该应用于如下场景:

  • 须要经过编程实如今多种组件中选择一种。
  • children、props 或者 data 在传递给子组件以前,处理它们。

model

见组件中的:v-model指令用在输入组件上和用直接用在input上的区别。

v-model 默认把 value 用做 prop 且把 input 用做 event,可是一些输入类型好比单选框和复选框按钮可能想使用 value prop 来达到不一样的目的,使用 model 选项来从新定义v-model的value和event

inheritAttrs

在使用自定义组件时,给组件设置一些非props的特性,默认会将这些特性帮到根元素上,经过设置inheritAttrs:false。能够禁止根元素继承这些特性,防止覆盖根元素已有特性。

$attrs存储非prop特性(除style和class外),在撰写基础组件的时候常会用到。

关于实例的目标挂载元素

若是在实例化时存在el选项,实例将当即进入编译过程,不然,须要显式调用 vm.$mount('#app') 手动开启编译。

render 函数若存在,则 Vue 构造函数不会从 template 选项或 el 选项指定的挂载元素中提取出的 HTML 模板编译渲染函数。

若是 render 函数和 template 属性都不存在,挂载 DOM 元素的 HTML 会被提取出来用做模板,此时,必须使用 Runtime + Compiler 构建的 Vue 库。

new Vue({
el: '#app',
components:{App},
template: '<App/>'
})

实例能代理的属性

一、data的属性。

二、props的某个具值属性。

三、计算属性,某属性的get属性被 实例代理,输出get的返回值。

computed: {
    add() {
      return 2;
    }
}
vm.add // 2

三、methods的方法

methods: {
    get_num(num) {
      vm.add_test1(num);
    },
    add_test1(num) {
    //...  
    }}
相关文章
相关标签/搜索