组件化开发的好处:提高开发效率、方便重复使用、便于协同开发、更容易被管理和维护。
vue中把一个自定义标签看成一个组件。
组件命名规则:
1.不能是W3C规定的标准标签如div、p等
2.组件名小写,多个单词用“-”连接
父子组件之间数据传递
父传子:父亲 -> 儿子 -> 孙子 (属性传递)
子传父:孙子 -> 儿子 -> 父亲 (事件传递)
//child.$on('change-m',change)//订阅事件
//child.$emit("change-m",val)//发布事件,并传参val
父传子流程:
1) 首先在父组件中引用、注册、使用子组件;
2) 给子组件的标签增加自定义属性并动态绑定父组件中的数据;//属性名和data、methods等其他对象中的名字不能相同,否则会冲突。
3) 然后在子组件中,使用props属性获取子组件标签增加的自定义属性,两种形式:数组或对象,数组使用方便,但不能校验;对象可以校验:但校验只是警告,并不会阻断代码的运行。
4) 此时在子组件模板中就可以使用获取的属性值了。
子传父流程:
1) 首先在父传子的基础上,给子组件标签添加一个自定义事件,自定义事件的方法来自于父亲的methods;
2) 在子组件的methods中定义一个方法,发射上一步子组件标签中的自定义事件,第一个参数是自定义事件名,第二个参数是给自定义事件的方法传递的值;
3) 当子组件中的方法被触发(点击、双击等)时,父组件的方法就收到了子组件发射事件中传递的值,然后更新自己的数据;
4) 最后通过父传子,更新子组件的数据。
示例:利用父子传递切换男/女生列表
根据父组件的female属性,子组件li标签的选中状态在男生精选和女生精选之间切换;
female默认为true,给女生精选li添加激活样式;
当点击男生精选所在的li时,触发子组件的changeMale方法,子组件发射"change-male"事件,触发父组件中子组件标签上的"change-male"事件,执行事件绑定的父组件中的方法"changeMale",方法将female值变为false,再通过属性female传到子组件上,此时female值为false,男生精选li动态绑定的样式被激活。
子组件:headerNav .vue
<template>
<div class="header">
<ul class="nav">
<li :class="{active:!female}" @click="changeMale">
<a>男生精选</a>
</li>
<li :class="{active:female}" @click="changeFemale">
<a>女生精选</a>
</li>
</ul>
</div>
</template>
<script>
export default {
props: ["female"],
methods: {
changeFemale(){
this.$emit("change-female")
},
changeMale(){
this.$emit("change-male")//发射"change-male"事件
}
}
}
</script>
<style scoped >
li.active {
color: #ffffff;
background-color: #fc8c84;
}
</style>
父组件:home.vue
<template>
<div>
<!--3.使用-->
<headerNav class="header" :female="female"
@change-female="changeFemale"
@change-male="changeMale"></headerNav>//相当于订阅事件headerNav.$on('change-female',changeFemale)
</div>
</template>
<script>
//1.引入headerNav
import headerNav from "../base/headerNav.vue"
import {getBrandList} from "../api"
export default {
created(){
this.getData();
},
data(){
return {
brandList: [],
female: true,
}
},
mounted(){
this.$nextTick(() => {
})
},
methods: {
//当男女列表切换时,判断并重新加载数据
changeFemale(){
if (this.female) {
return
} else {
this.female = true
}
},
changeMale(){
if (!this.female) {
return
} else {
this.female = false
}
}
},
components: {headerNav}//2.注册
}
</script>