vue构造函数(根实例化时和组件实例对象选项)参数:选项详解
实例选项(即传给构造函数的options):数据,DOM,生命周期钩子函数,资源,组合,其他
数据
data
属性能够响应数据变化,当这些数据改变时,视图会进行重渲染。
访问方式:
1、通过 vm.$data
访问。
- var data = { a: 1 }
- var vm = new Vue({
- el: '#example',
- data: data
- })
- vm.$data === data// => true
- vm.$el === document.getElementById('example') // => true
2、Vue 实例代理(以 _
或 $
开头的属性 不会 被 Vue 实例代理)了 data 对象上所有的属性。
- // 我们的数据对象
- var data = { a: 1 }
- // 该对象被加入到一个 Vue 实例中
- var vm = new Vue({
- data: data
- })
- // 获得这个实例上的属性
- // 返回源数据中对应的字段
- vm.a == data.a // => true
在组件中:
1、data 必须为返回一个初始数据对象的函数,因为组件可能被用来创建多个实例。如果 data
仍然是一个纯粹的对象,则所有的实例将共享引用同一个数据对象!通过函数的return,每次返回的是不同的对象。
2、每次创建一个新实例后,调用 data
函数会返回初始数据的一个全新副本数据对象。
拷贝原始数据对象:
将 vm.$data
传入 JSON.parse(JSON.stringify(...))
得到深拷贝的原始数据对象。
注意:
1、data作为函数时如果
使用了箭头函数,则 this
不会指向这个组件的实例,函数的第一个参数将是实例。
- data: vm => ({ a: vm.myProp })
2、只有当实例被创建时 data
中存在的属性才是响应式的。
3、使用Object.freeze()对data对象属性冻结,data不再是响应式。
使用建议:
1、推荐在创建实例之前,就声明所有的根级响应式属性。
2、后续才需要的某个属性,但是一开始它为空或不存,设置一些初始值,保证它是响应式的。
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 会在一个组件实例创建之前进行验证,所以实例的属性 (如 data
、computed
等) 在 default
或 validator
函数中是不可用的。
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开启的情况下会报错。
使用建议:
1、在get中,不要改变实例属性,而是通过set来改变。
2、计算属性依赖响应式属性,注意它的使用场合和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的使用场景
1、大部分时候都使用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]
- }
- }
- }
2、一般在事件里调用methods
3、当需要在数据变化时执行异步或开销较大的操作时,使用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的常用姿势:
1、除了代替上面的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.')
- }
- }
2、还能通过数据对象实现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)
- }
- }
- })
- }
3、使用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
生命周期钩子注意的点:
1、ajax请求最好放在created里面,因为此时已经可以访问this了,请求到数据就可以直接放在data里面。
2、关于dom的操作要放在mounted里面,在mounted前面访问dom会是undefined。
3、每次进入/离开组件都要做一些事情,用什么钩子:
进入的时候可以用created和mounted钩子,离开的时候用beforeDestory和destroyed钩子,beforeDestory可以访问this,destroyed不可以访问this。
缓存了组件之后,再次进入组件不会触发beforeCreate、created 、beforeMount、 mounted,如果你想每次进入组件都做一些事情的话,你可以放在activated进入缓存组件的钩子中。
同理:离开缓存组件的时候,beforeDestroy和destroyed并不会触发,可以使用deactivated离开缓存组件的钩子来代替。
将路由导航、keep-alive、和组件生命周期钩子结合起来的触发顺序:
假设是从a组件离开,第一次进入b组件:
资源
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、binding
、vnode
和 oldVnode。
el:指令所绑定的元素,可以用来直接操作 DOM 。
binding:对象,有以下属性:
name
:指令名,不包括v-
前缀。value
:指令的绑定值,例如:v-my-directive="1 + 1"
中,绑定值为2
。oldValue
:指令绑定的前一个值,仅在update
和componentUpdated
钩子中可用。无论值是否改变都可用。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:上一个虚拟节点,仅在
update
和 componentUpdated
钩子中可用。
钩子函数简写:
在 bind
和 update
时触发相同行为,而不关心其它的钩子,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输入处理等)
注意:
1、过滤器内是没有this引用的,过滤器内的this是undefined,所以不要在过滤器内尝试使用this引用组件实例的变量或者方法。
2、过滤器函数始终以表达式的值作为第一个参数。带引号的参数视为字符串,而不带引号的参数按表达式计算。
3、可以设置两个过滤器参数,前提是这两个过滤器处理的不冲突
4、全局定义过滤器,在创建 Vue 实例之前
5、直接注册在Vue全局上面,其他不用这个过滤器的实例也会被迫接受,所以要注意区分哪些注册在全局,哪些注册为局部
用法:双花括号插值和 v-bind
表达式 (后者从 2.1.0+ 开始支持),被添加在 JavaScript 表达式的尾部,由“管道”符号指示:
- <!-- 在双花括号中,capitalize过滤器函数将会收到
message
的值作为第一个参数-->- {{ message | capitalize }}
- <!-- 在 `v-bind` 中 -->
- <div v-bind:id="rawId | formatId"></div>
- <!-- 过滤器可以串联 ,filterA 的结果传递到
filterB
中-->
{{ message | filterA | filterB }}- <!-- 过滤器是 JavaScript 函数,因此可以接收参数,message 的值作为第一个参数,普通字符串
'arg1'
作为第二个参数,表达式arg2
的值作为第三个参数。-->
{{ message | filterA('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.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/>'
- })
实例能代理的属性
1、data的属性。
2、props的某个具值属性。
3、计算属性,某属性的get属性被 实例代理,输出get的返回值。
- computed: {
- add() {
- return 2;
- }
- }
- vm.add //
3、methods的方法
- methods: {
- get_num(num) {
- vm.add_test1(num);
- },
- add_test1(num) {
- //...
- }
}
vue构造函数(根实例化时和组件实例对象选项)参数:选项详解的更多相关文章
- Vue使用Ref跨层级获取组件实例
目录 Vue使用Ref跨层级获取组件实例 示例介绍 文档目录结构 安装vue-ref 根组件自定义方法[使用provide和inject] 分别说明各个页面 结果 Vue使用Ref跨层级获取组件实例 ...
- Vue实例对象的数据选项
前面的话 一般地,当模板内容较简单时,使用data选项配合表达式即可.涉及到复杂逻辑时,则需要用到methods.computed.watch等方法.本文将详细介绍Vue实例对象的数据选项 data ...
- Vue实例对象的数据选项(火柴)
前言 一般地,当模板内容比较简单的时候,使用data选项配合表达式即可.涉及到复杂逻辑时,则需要用到methods.computed.watch等方法.本文将详细介绍Vue实例对象的数据选项. dat ...
- 解决C#程序只允许运行一个实例的几种方法详解
解决C#程序只允许运行一个实例的几种方法详解 本篇文章是对C#中程序只允许运行一个实例的几种方法进行了详细的分析介绍,需要的朋友参考下 本文和大家讲一下如何使用C#来创建系统中只能有该程序的一个实例运 ...
- python 单例模式,一个类只能生成唯一的一个实例,重写__new__方法详解
单例:一个类只能生成唯一的一个实例 每个类只要被实例化了,他的私有属性 '_instance'就会被赋值,这样理解对吗 对 #方法1,实现__new__方法 #并在将一个类的实例绑定到类变量_inst ...
- VUE自学日志02-应用与组件实例
准备好了吗? 我们刚才简单介绍了 Vue 核心最基本的功能--本教程的其余部分将更加详细地涵盖这些功能以及其它高阶功能,所以请务必读完整个教程! 应用 & 组件实例 创建一个应用实例创建一个应 ...
- Vue.js 源码分析(二十六) 高级应用 作用域插槽 详解
普通的插槽里面的数据是在父组件里定义的,而作用域插槽里的数据是在子组件定义的. 有时候作用域插槽很有用,比如使用Element-ui表格自定义模板时就用到了作用域插槽,Element-ui定义了每个单 ...
- java入门---对象和类&概念详解&实例
Java作为一种面向对象语言.支持以下基本概念: 多态 继承 封装 抽象 类 对象 实例 方法 重载 这篇文章,我们主要来看下: 对象:对象是类的一个实例(对象不是找个女朋友),有状态 ...
- Vue.js 源码分析(二十四) 高级应用 自定义指令详解
除了核心功能默认内置的指令 (v-model 和 v-show),Vue 也允许注册自定义指令. 官网介绍的比较抽象,显得很高大上,我个人对自定义指令的理解是:当自定义指令作用在一些DOM元素或组件上 ...
随机推荐
- 如何解决一个从SkylineGlobe5版本升级到7版本遇到的小问题
前些天,有朋友问,用Skyline5版本开发的WinForm程序,升级到7版本的时候,工程提示下面这样“创建组件AxHost失败”的错误,该如何解决呢? 后来经过百度搜索,找到了这样的答案, 测试发现 ...
- PWC6345: There is an error in invoking javac. A full JDK (not just JRE) is required
今天在使用jetty运行一个项目的时候报这个错误,仔细看了下,应该是eclipse配置的jdk或者jre出错. 看了下环境变量,发现有些配置没有配置完全. 我个人的解决方法: 在path中,添加%JA ...
- Elastic Stack-Elasticsearch介绍
一.前言 前篇写了好像没有多少人去看,但是还是要继续,我猜想可能是很多人接触的这块比较少吧,Elasticsearch这块有很多要说的,开始吧. 二.数据库.Elasticsearch选择 ...
- 遍历CheckBox根据指定条件做筛选js
$('#del').click(function(){ var checkeds=$('input[name=cid]:checked') checkeds.each(function() { var ...
- 系统IO
系统IO:Linux系统提供给应用程序操作文件的接口 Everything is a file ,in Unix 在Unix/Linux下,万物皆文件 打开文件函数原型: #include< ...
- 07-JavaScript之常用内置对象
JavaScript之常用内置对象 1.数组Array 1.1数组的创建方式 // 直接创建数组 var colors = ['red', 'blue', 'green']; console.log( ...
- Photoshop调出外景婚片蓝色小清新艺术效果
春季婚纱旺季来了,好多童鞋给我抱怨说客片太难转色了,春天的小清新感都转不了,其实并不难,运用好互补色来进行加减色,能很快调整好照片的偏色,互补色也可称为对比色,后期调色的加也可称为减,如加蓝=减黄.加 ...
- Ubuntu软件的安装与删除
- 控制结构(11): Continuation passing style(CPS)
// 上一篇:控制结构(10)指令序列(opcode) [注释]: 这个笔记系列需要告一个段落了,收尾部分整理下几个时髦(The New Old Things)结构. 后面打算开一个算法方面的,重新学 ...
- 4月10日java上机任务
1. 一维数组的创建和遍历. 声明并创建存放4个人考试成绩的一维数组,并使用for循环遍历数组并打印分数.要求: (1) 首先按“顺序”遍历,即打印顺序为:从第一个人到第四个人: (2) ...