组件引用 —— ref、$refs
给子组件或者原始DOM加上ref
特性,就可以为其声明引用标记,添加引用后,可以在Javascript中使用vm|this.$refs.refname
获取子组件或原始DOM。若是原始DOM,则效果如document.querySelector(ele)
;若是子组件,则结果为一个VueComponent
实例对象
Vue.component('component-1', {
props: ['subProp'],
data: function () {
return {
subData: "child\'s data"
}
},
template: '<div>子组件内容</div>'
})
Vue.component('component-2', {
template: '<li>sub component</li>'
})
var vm = new Vue({
el: '#app-1',
data: {
message: "send child\'s props",
subPropVal: "default",
subDataVal: "default",
commonDomVal: "default",
items: [
{ id: '1', case: 'piece' },
{ id: '2', case: '处刑之塔' },
{ id: '3', case: '猎杀联盟行动' }
]
},
methods: {
setVal: function () {
this.subDataVal = this.$refs.child.subData
this.subPropVal = this.$refs.child.subProp
this.commonDomVal = this.$refs.common.value
console.log(this.$refs.child)
console.log(this.$refs.item)
console.log(this.$refs.item2)
},
}
});
<div id="app-1">
<component-1 ref="child" :sub-prop="message"></component-1>
<input type="text" ref="common" value="normal DOM element" />
<button @click="setVal">取值</button>
<br>
<span>获取子组件data属性[{{subDataVal}}]</span>
<br>
<span>获取子组件prop特性[{{subPropVal}}]</span>
<br>
<span>获取普通DOM元素值[{{commonDomVal}}]</span>
<br>
<ul v-for="item in items">
<li ref="item">{{item.case}}</li>
</ul>
<ul v-for="item in items">
<component-2 ref="item2"></component-2>
</ul>
</div>
父组件数据定义:message
、subPropVal
、subDataVal
、commonDomVal
和一个数组items
。
子组件一中定义有:propssubProp
、datasubData
我们在一个组件<component-1>
和一个原始input
上添加了ref
特性,并把父组件的message
通过Prop
传递给子组件的subProp
。
现在,就可以在绑定的按钮单击事件的回调中,通过this.$refs
获取组件和原始DOM的信息了,这些信息包括子组件的props
、data
和input
元素的value
值
如果和v-for
一起使用,那么this.$refs.refname
返回的是一个数组,引用原始DOM为一个原始DOM的数组,引用子组件为一个VueComponent
数组,如在上面的例子中使用v-for&ref
把输出打印在控制台如下:
混入(Mixins)
在Vue中没有通用的API来实现组件继承的,但也有一些手段可以重复利用那些多个组件中相同的功能,比如这里的Mixin。当多个组件有相同属性或方法时,可以抽取相同部分放入一个Mixins对象中。
Vue.mixin({
created: function () {
console.log('全局混入对象')
}
})
var superPowersMixin = {
data: function () {
return {
superPowers: false,
//不会覆盖组件中的`img`
img: require('./angular.png'),
}
},
methods: {
superMe: function () {
this.$el.classList.add("super")
this.superPowers = true
},
goback: function () {
this.$el.firstChild.innerText = 'Forever Stay Here'
}
},
created: function () {
this.$options.template =
'<button class="btn btn-sm btn-primary" @click="goback" v-show="superPowers">Go Back</button>' +
'<button class="btn btn-sm btn-primary" @click="superMe" v-if="!superPowers">Add Filter</button>' +
this.$options.template
}
}
new Vue({
el: '#app-1',
components: {
vueImage: {
data: function () {
return { img: require('./vue.png') }
},
template: "<div><img :src='img' width='80' height='80'></div>",
methods: {
goback: function () {
this.$el.classList.remove("super")
this.superPowers = false
}
},
//同名钩子函数将混合为一个数组,因此都将被调用。混入对象的钩子将在组件自身钩子之前调用。
created: function () {
this.$options.template = '<div>' +
this.$options.template +
'</div>'
},
mixins: [superPowersMixin]
},
reactImage: {
data: function () {
return { img: require('./react.png') }
},
template: "<div><img :src='img' width='80' height='80'></div>",
created: function () {
this.$options.template = '<div>' +
this.$options.template +
'</div>'
},
mixins: [superPowersMixin]
}
}
})
<style>
.super {
filter: hue-rotate(120deg);
}
</style>
<div id="app-1">
<vue-image></vue-image>
<react-image></react-img>
</div>
在以上示例混入对象中,我们使用了属性、模板、方法和钩子函数,对于不同的选项来说,我们有不同的合并规则。
总体上来讲,当选项是一个对象时,我们就合并成一个大的对象,如果对象中有重名的属性时,我们就丢弃混入对象中的属性。比如为组件vueImage
添加混入时,属性img
和方法goback()
就被丢弃。而钩子函数混入和组件中的不合并,而是都执行,先执行混入中的钩子,再执行组件中的。
模拟继承
利用混入可以模拟下继承系统。
var SuperClass = {
template: '<p><button class="btn btn-sm btn-primary" @click="superMethod">Super Method</button>{{message}}</p>',
data() {
return {
message: 'super class data'
}
},
methods: {
superMethod() {
this.message = 'run super class method to change data'
}
}
}
var SubClass = {
mixins: [SuperClass],
template: '<p><button class="btn btn-sm btn-primary" @click="superMethod">Override Super Method</button>\
<button class="btn btn-sm btn-primary" @click="subMethod">Sub Method</button>{{message}}</p>',
methods: {
superMethod() {
this.message = 'override super class method'
},
subMethod() {
this.message = 'run sub class method to change data'
}
}
}
new Vue({
el: '#app-2',
components: { SuperClass, SubClass }
})
<div id="app-2">
<super-class></super-class>
<sub-class></sub-class>
</div>
在这个例子中,为组件subClass
混入了superClass
,并从superClass
那里继承了属性message
,重写了方法superMethod()
,又添加了自己的方法subMethod()
。感觉可以开发开发- -b。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。