Vue自定义组件
1.自定义组件的两种方式。
1.1全局定义
全局定义是通过Vue的component方法来实现的,component有两个参数,一是组件名称,二是组件实例。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>TestComponent</title>
</head>
<body>
<div id="app">
<counter></counter>
</div>
<script src="node_modules/vue/dist/vue.js"></script>
<script>
Vue.component('counter',{
template: "<button @click='count++'>计数器,当前数字为{{count}}</button>",
data(){
return {
count: 0
};
}
})
/* const counter = {
template: "<button @click='count++'>计数器,当前数字为{{count}}</button>",
data() {
return {
count: 0
};
}
}*/
const app = new Vue({
el: "#app",
data: {
},
/* components: {
counter: counter
}*/
});
</script>
</body>
</html>
1.2 局部定义
局部定义组件是以const 组件名称 = 组件实例形式来实现的。局部组件定义完之后,要在vue实例的components属性中做一个引用,然后才能在html代码块中使用(vue作用的部分)。
小tips:ES6的语法中,对象的属性键值完全一致,可以直接简写键值中的一个即可
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>TestComponent</title>
</head>
<body>
<div id="app">
<counter></counter>
</div>
<script src="node_modules/vue/dist/vue.js"></script>
<script>
/* Vue.component('counter',{
template: "<button @click='count++'>计数器,当前数字为{{count}}</button>",
data(){
return {
count: 0
};
}
})*/
const counter = {
template: "<button @click='count++'>计数器,当前数字为{{count}}</button>",
data() {
return {
count: 0
};
}
}
const app = new Vue({
el: "#app",
data: {
},
components: {
//ES6的语法中,对象的属性键值完全一致,可以直接简写键值中的一个即可
//counter: counter
counter
}
});
</script>
</body>
</html>
2.父子组件之间的通信。
2.1 父向子通信
首先在子组件的props中定义要传递的数据名称,然后在父组件中通过v-bind来绑定刚才定义的数据名称(可以理解为子组件的一个属性),将父组件要传递的数据传递到刚才绑定的属性即可。
2.2 子向父组件通信。
和父向子通信不同,子向父通信,是在事件发生时,子通知父去做数据的变化,数据变化的实现还是在父组件中(因为若是数据发生在子组件中,会有一个问题,子组件对数据做了变更的同时,父组件也在对该数据做变更,那么父组件的变更会覆盖掉子组件的变更)。
子组件通知父组件,主要是通过$emit来实现的。首先,在父引用子组件的代码块上,用@触发事件名称=“父组件数据变更事件” 定义要触发的方法名称,然后在子组件的事件中用$emit(触发事件名称,参数)来触发事件,这样,当子组件的事件发生时,就会通过触发事件,调用父组件的数据变更事件,来实现数据变更。实际上这个过程中,父组件只是用一下子组件的控件而已,不用子组件的数据,
案例如下
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>父子间通信</title>
</head>
<body>
<div id="app">
<num-controller :init-num="initNum" @c-add="add" @c-reduce="reduce"></num-controller>
</div>
<script src="node_modules/vue/dist/vue.js"></script>
<script>
const numController = {
template: `
<div>
<button @click="doAdd">+</button>
<button @click=doReduce>-</button>
<h1>
Num:{{initNum}}
</h1>
</div>`,
data(){
return {
}
},
//父向子传递数据时,在子组件的props中定义好数据名称,如下方initNum,在父组件调用时,在该组件上通过v-bind:initNum来绑定改数据即可,
//简写:initNum <num-controller :init-num="initNum" ></num-controller>
props: ['initNum'],
methods: {
doAdd(){
//子向父组件传递数据时,首先在父组件调用子组件的程式块中,定义一个回调方法@c-add,并绑定上一个触发后执行得父组件方法add,
// <num-controller :init-num="initNum" @c-add="add" @c-reduce="reduce"></num-controller>
// 然后在子组件的事件上通过$emit来触发之前定义的回调方法,这样子组件的事件发生时,就会触发父组件方法改变父组件的数据,
// 因为原则上是不能在子组件中直接改变父组件的数据,那样父组件中数据更新时,会把子组件的数据变化覆盖掉。
// 通过$emit来触发父组件的事件,$emit中有两个参数,第一个是父组件绑定的事件名称,第二个则是参数数组
this.$emit('c-add');
},
doReduce(){
this.$emit('c-reduce');
}
}
}
const app = new Vue({
el: "#app",
data: {
initNum: 0
},
components: {
numController
},
methods: {
add(){
this.initNum++;
},
reduce(){
this.initNum--;
}
}
})
</script>
</body>
</html>

浙公网安备 33010602011771号