组件开发思路:
1.定义一个form表单,提交全局校验,数据的传递
provide(){return{}},下面的子孙组件可以inject获取数据
2.formItem校验、label、错误显示、插槽
3.数据收集v-model,通知校验
4.校验
4.1不能用孙组件通知校验,可以通知子组件formItem校验
this. p a r e n t . parent. parent.emit(‘validate’)
4.2 formItem组件里面监听
mounted(){
this.$on(‘validate’,()=>{
this.validate()
})
}
methods:{
validate(){
// 做校验
// 1.获取数值和规则
const value = this.form.model[this.prop]
const rule = this.form.rules[this.prop]
// 2.创建校验
// import Schema from 'async-validator'
const schema = new Schema({[this.prop]:rule})
schema.validate({[this.prop]:value}, errors=>{
if(errors){
this.error = erros[0].message;
}else{
this.error = ''
}
})
}
}
4.3安装npm i async-validator -S
4.4 设置当前的 prop=“username” // 做校验必须的prop
4.5 form.vue
validate(cb){
const tasks = this.$children
.filter(item=>item.prop)
.map(item => item.validate()) // 返回的是promise
Promise.all(tasks)
.then(()=>cb(true))
.catch(()=>cb(false))
}
5.抽离公共组件数据可方法到mixin
一、父子组件通信
0。
父子组件通讯:
父组件:
子组件:
props: {
myvisible: {
type: Boolean,
default: false,
},
},
btnClose(){
this.$emit(‘update:myvisible’, false)
}
1.props
//child
props:{msg:String}
//parent
2.特性 a t t r s . 父级字段名, attrs.父级字段名, attrs.父级字段名,listener监听事件
//child
{{$attrs.foo}}
//parent
3.refs
//parent
mounted(){
this.$refs.hw.xx = ‘xxx’
}
4.children
//parent
this.$children[0].xx = ‘xxx’ // 下标是无序的
二、子传父
// child
this. e m i t ( ′ a d d ′ , g o o d ) / / p a r e n t < c a r t @ a d d = " c a r t A D D ( emit('add', good) //parent
三、兄弟组件传值
通过共同的祖辈组件塔桥, p a r e n t 或者 parent或者 parent或者root
//brother1
this. p a r e n t . parent. parent.on(‘foo’,handle)
//brother2
this. p a r e n t . parent. parent.emit(‘foo’)
mounted(){
this. o n ( ′ f o o ′ , ( ) = > c o n s o l e . l o g ( ′ f o o ′ ) ) t h i s . on('foo', ()=>{ console.log('foo~~~~') }) this. on(′foo′,()=>console.log(′foo ′))this.emit(‘foo’);
}
四、祖孙组件传值
a t t r s 、 attrs、 attrs、listener
provide需要是对象,才能响应式
// ancestor 祖宗
data () {
return {
fooObj:{
foo:5
}
}
},
//依赖注入传值
provide(){
return{
newFoo:this.fooObj
}
}
{{fooObj.foo}}
// descendant
inject:[‘newFoo’],或者inject:{newFoo:String}
五、任意两个组件之间:事件eventBus或者 vuex
1.eventBus
//main.js
import Vue from ‘vue’
const eventBus = new Vue()
export {eventBus}
// child1
eventBus.KaTeX parse error: Expected '}', got 'EOF' at end of input: …troy() { Bus.off(“onSearchwordKey”);
}
// child2
eventBus.$emit(‘foo’)
插槽slot
1.匿名插槽
// child comp
//parent
hello
2.具名插槽
// child comp
//parent
匿名插槽
匿名插槽
//v-slot:===> 缩写#,只能在template标签中使用
我是main内容
3.作用域插槽
作用域插槽是:父组件可以拿到子组件的数据。
应用场景:多层往上传递数据时,比emit好。
子组件暴露数据给父级 :
父组件获取到数据,判断做出不同操作。
点击加2{{fooObj.foo}}
vue3,不用new Vue,而用Vue.createApp({}).mount(“#root”)
点击加2{{fooObj.foo}}
复杂的dom(比如几十个v-if判断的dom)可以用render来简化