组件是Vue比较核心的概念,可以定义一个公共组件在其他页面复用,下面介绍一下组件的基本语法。
1、比如我们想定义一个按钮,并显示出点击了多少次。
<template>
<button @click="count++">You Clicked me {{ count }} times</button>
</template>
<script>
export default{
name: 'bbb',
data () {
return {
count: 0,
}
}
}
</script>
我们在导出这个组件的时候,要注意data 一定 要定义成函数的形式,否则会报错。这样其他组件导入时,直接调用data以取出参数。
2、在我们想引入这个按钮的文件中,把这个组件导入进来。
import myCounterButton from './components/ButtonCount.vue'
3、在components处进行注册。
export default {
name: 'app',
components:{
myCounterButton
},
}
4、然后就可以使用啦,在这里每一个标签都对应一个单例,他们之间的数据互不影响
<myCounterButton></myCounterButton>
<myCounterButton></myCounterButton>
<myCounterButton></myCounterButton>
以上只是最简单的组件使用,
一般我们把原始组件称为子组件;把引用组件的文件称为父组件。
假如我们想在使用父组件的数据来构建组件,那么就需要向子组件传值。
这时,我们需要了解props这个东西。
● 在子组件中定义props,他往往以数组的形式呈现,就相当于子组件的data。
像这样,就告诉父组件,在使用子组件的时候,要通过 count_1 这个属性,来把子组件所需要的数据传进来。
export default{
name: 'bbb',
props: ['count_1'],
data () {
return {
}
},
}
● 子组件就像用 data 中的数据一样, 使用 props 定义的参数
<button @click="count_1 ">You Clicked me {{count_1 }} times</button>
● 父组件在引用时, 子组件 props定义的参数,就作为该组件的自带属性值。
<buttoncounter :count_1="11" ></buttoncounter>
以上都是我根据文档,试着用了一下Props。然而在实际使用时,点击子组件,会报错:
Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders.
Instead, use a data or computed property based on the prop's value. Prop being mutated: "count_1"
大概意思就是 不建议子组件内部修改props中的count_1的值。
那么继续读文档,看到了一个 vm.$emit。
在子组件中使用 vm.$emit(methodName,...args) 方法,来完成子组件告知父组件的动作。(暴露一个事件接口,父组件可以监听)
那在我们这个样例代码中,我的理解就是:需求是子组件要更改props的值,我们又不能在子组件中更改,但是我们可以在该事件触发的时候,去通知父组件,让父组件去修改参数,再通过props值来告知子组件变更。
刚开始看语法的时候,有点难懂,详细解读一下!
● 在子组件按钮发生点击事件时,触发一个方法:
<button @click="counter">You Clicked me {{count_1 }} times</button>
● 在这个事件内部,我们调用 this.$emit 来设置一个通知。这个方法的参数,可以看做是子组件自定义的一个DOM事件
<script>
export default{
...
methods:{
counter() {
this.$emit('fatherCount')
}
...
}
</script>
<style>
● 在父组件 通过 @*** 来定义该事件触发时我们调用的方法。
看到了吗? 之前子组件 this.$emit('fatherCount') 就相当于给<buttoncounter> 定义了一个内置DOM事件 fatherCount
<buttoncounter :count_1="count_1" @fatherCount="myCount"></buttoncounter>
所以在父组件中我们直接用 @fatherCount 来监听
在fatherCount触发时,我们做props的自增
methods:{
myCount: function(){
this.count_1++
}
}
最后总结一下
我的理解就是:父组件在触发子组件的事件时,想要修改子组件的内容,就需要子组件创建一个自定义事件,在子组件事件触发时,将自定义事件当做this.emit()的参数导出。这个事件就成为子组件的内置事件。
父组件在引用子组件时可以通过 @自定义事件来监听 子组件是否触发事件。
注意:this.$emit是可以传参数的,比如子组件是一个选择器,那么发生change事件时,我们可以把选中的下标或者实际值通过参数传给父组件:
子组件
<script>
onChange (val){
console.log("子组件选中的下标"+val.target.selectedIndex);
console.log("子组件实际选中的值"+val.target.options[val.target.selectedIndex].value);
this.$emit('mySelectChange',
val.target.options[val.target.selectedIndex].value);
}
</script>
父组件
getSelected :function(val) {
console.log("父组件拿到的参数"+val)
this.count++;
}