1. 组件传值
- 组件化编码流程:
- 拆分静态组件:组件要按照功能点拆分,命名不要与
html
元素冲突 - 实现动态组件:考虑好数据的存放位置,数据是一个组件在用,还是一些组件在用:
- 一个组件在用,放在组件自身即可
- 一些组件在用,放在他们共同的父组件上(状态提示)
- 实现交互:从绑定事件开始
- 拆分静态组件:组件要按照功能点拆分,命名不要与
props
适用于:- 父组件 ===> 子组件 通信
- 子组件 ===> 父组件 通信(要求父先给子一个事件)
- 组件接收形式
1. props: ['xxx']2. props:{xxx:{type: String,required: true // 必传},xxx:{type: Number, // 类型default: 20 // 默认值...自定义校验等等}}3. props:{xxx: Number, // 设置类型xxx:{type: Number, // 类型default: 20 // 默认值...自定义校验等等}}
props
接收的值不可以修改
示例: 我们只需要四个组件,父组件APP.vue
,子组件SelectInput.vue
、SelectList .vue
、SelectMulDel.vue
,需求:子组件操作数据改变父组件内的列表数据,实现增删
1. 文件目录:components
文件夹内创建子组件文件
2. 在父组件APP.vue
中:引入3个子组件
因为所有的子组件共同需要用到列表的数据,所以数据写在父组件内
因为操作的数据在父组件内部。所以和操作方法都写在父组件内
<template><div><SelectInput :addDataList="addDataList"></SelectInput><SelectList :daList="dataList" :delDataList="delDataList"/><SelectMulDel :mulDelDataList="mulDelDataList"></SelectMulDel></div>
</template>
<script>
import SelectList from './components/SelectList.vue'
import SelectInput from './components/SelectInput.vue'
import SelectMulDel from './components/SelectMulDel.vue'
export default {name: 'App',components:{SelectList,SelectInput,SelectMulDel},data(){return {// 数据创建在父组件内dataList:[{ name: '小红', checked: false},{ name: '小绿', checked: false},]}},methods:{// 添加数据addDataList(val){this.dataList.push(val)},// 删除数据delDataList(index){this.dataList.splice(index, 1) },// 批量删除mulDelDataList(){console.log(this.dataList);this.dataList = this.dataList.filter(item=> !item.checked)}}
}
</script>
- 子组件
SelectInput.vue
中:
编写添加数据和添加按钮功能
通过props
传入的添加方法实现添加功能
<template><div class="container"><input type="text" v-model="value"><button @click="add">添加</button></div>
</template>
<script>
export default{props:['addDataList'],data(){return {value: '小美丽'}},methods:{add(){console.log(this.value);this.addDataList({ name: this.value, checked: false })}}
}
</script>
- 子组件
SelectList.vue
中:
展示列表数据和行内删除
通过props
传入的删除方法实现行内删除功能
<template><div class="container"><ul><!-- 批量删除, key为唯一值, 假设name不可以重复 --><li v-for="(item, index) in daList" :key="item.name"><!-- v-model双向绑定,直接改变值,就相当于改变props传入的值,引起错误 --><!-- <input type="checkbox" v-model="item.checked" @change="item.checked = !item.checked"> --><input type="checkbox" :value="item.checked" @change="item.checked = !item.checked">{{ item.name }}<button @click="del(index)">删除</button></li></ul></div>
</template><script>
export default{props:['daList', 'delDataList'],methods:{del(index){// props 传入的值不允许改变// this.daList.splice(index, 1) this.delDataList(index, 1) }}
}
</script>
<style scoped>
.container{background-color: antiquewhite;
}
ul{list-style: none;
}
</style>
- 子组件
SelectMulDel.vue
中:
展示列表数据的选择行为
通过props
传入的批量删除方法实现批量删除功能
<template><div><button @click="mulDelete">批量删除</button></div>
</template>
<script>
export default{props:['mulDelDataList'],methods:{mulDelete(){this.mulDelDataList()},}
}
</script>
- 展示效果:点击功能ok
2. 组件的自定义事件
- 一种组件间通信的方式,适用于:子组件=>父组件
- 使用场景:A是父组件,B是子组件,B想传给A,那么就要在A中给B绑定自定义事件(事件的回调在A中)
- 绑定自定义事件:
- 第一种方式:在父组件中:
<Demo @my-event="test"></Demo>
- 第二种方式:在父组件中:
<Demo ref="demo"></Demo> .... mounted(){this.$refs.xxx.$on('my-event', this.test) }
- 若想让自定义事件只能触发一次,可以使用
once
修饰符,或$once
方法
- 第一种方式:在父组件中:
- 触发自定义事件:
this.$emit('my-event', 数据)
- 解绑自定义事件:
this.$off('my-event')
- 组件上也可以绑定原生DOM事件,需要使用
native
修饰符
示例:上述的props案例
是父组件将数据和操作方法统一已props
形式传入子组件,子组件还需接收才可使用,现在我们将自定义事件编写,在此已SelectInput.vue
为例
- 第一种:自定义事件
@
方式
App.vue
内修改为:@addDataList
接收子组件传过来的自定义事件
<SelectInput @addDataList="addDataList"></SelectInput>
- 子组件内
SelectInput.vue
修改为:
<template><div class="container"><input type="text" v-model="value" /><button @click="add">添加</button></div>
</template><script>
export default {data() {return {value: "小美丽",};},methods: {add() {this.$emit("addDataList", { name: this.value, checked: false });// 可emit提交多个自定义事件},},
};
</script>
- 第二种:自定义事件
ref
方式
App.vue
内修改为:
SelectInput
标签上添加ref属性,- 生命周期
mounted
中,通过$on
绑定事件- 生命周期
beforeDestroy
中,通过$off
移除自定义事件
<SelectInput ref="MyInput"></SelectInput>
...
mounted() {this.$refs.MyInput.$on("addDataList", this.addDataList);},beforeDestroy() {this.$refs.MyInput.$off("addListInput");// this.$refs.MyInput.$off(); // 可以不传参数,移除所有自定义事件},
- 子组件内
SelectInput.vue
修改和@
一样