vue组件开发思路(传值、slot)

组件开发思路:
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 <cart @add="cartADD( emit(add,good)//parent<cart@add="cartADD(event)">

三、兄弟组件传值
通过共同的祖辈组件塔桥, 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、 attrslistener
provide需要是对象,才能响应式
// ancestor 祖宗
data () {
return {
fooObj:{
foo:5
}
}
},
//依赖注入传值
provide(){
return{
newFoo:this.fooObj
}
}
{{fooObj.foo}}

// descendant
inject:[‘newFoo’],或者inject:{newFoo:String}

我是子组件:{{newFoo.foo}}
子组件接收(三种写法): inject: ['parent'], inject: { parent: { default: () => ({}) } }, inject: { newName: { from:'parent', // 如果改名,需要用from表明来源属性 default: () => ({}) } },

五、任意两个组件之间:事件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标签中使用
<template #content>我是main内容

3.作用域插槽
作用域插槽是:父组件可以拿到子组件的数据。
应用场景:多层往上传递数据时,比emit好。
子组件暴露数据给父级 :
父组件获取到数据,判断做出不同操作。

<!DOCTYPE html>
<html>
<head>
    <title></title>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <!-- <script src="./vue.js"></script> -->
    <script src="https://cdn.jsdelivr.net/npm/vue"></script>
    <!-- <script src="http://cdn.staticfile.org/vue/2.6.10/vue.common.dev.js"></script> -->
</head>
<body>
<div id="root">
    <div @click="addmsg">点击加2{{fooObj.foo}}</div>
    <child>
        <!-- 作用域插槽必须是template开头且结尾 -->
        <template slot-scope="props">
           <li v-html="props.value ===2? '<strong style=\'color:red;\'>2</strong>':props.value" ></li>
        </template>
    </child>
</div>
<script type="text/javascript">
    Vue.component("child", {
        data: function() {
            return {
                list: [1, 2, 3, 4, 5, 6]
            }
        },
        inject:['newFoo'],
        mounted(){
            console.log('newFoo', this.newFoo)
        },
        methods:{
            addmsg(){
                this.newFoo.foo --
                console.log(this.newFoo.foo)
            }
        },
        template: `<div>
                        <ul>
                            <li v-for="item of list">{{item}}</li>
                            
                        </ul>
                        -------
                            <div @click="addmsg">addmsg{{newFoo.foo}}</div>
                        <ul>
                            //这种方式的作用是:显示什么,怎么显示不再是子组件决定了,而是父组件调子组件的时候给子组件传递模版:
                            <slot v-for="item of list" :value=item></slot>
                        </ul>
                    </div>`
    });

    var vm = new Vue({
        el: "#root",
        data(){
            return{
                fooObj:{
                    foo:5
                }
            }
        },
        methods:{
            addmsg(){
                this.fooObj.foo ++
                console.log(this.fooObj.foo)
            }
        },
        provide() {
            return {
                newFoo: this.fooObj
            }
        }
    })
</script>
</body>
</html>

vue3,不用new Vue,而用Vue.createApp({}).mount(“#root”)

<!DOCTYPE html>
<html>
<head>
    <title></title>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <!-- <script src="./vue.js"></script> -->
    <script src="https://unpkg.com/vue@next"></script>
    <!-- <script src="http://cdn.staticfile.org/vue/2.6.10/vue.common.dev.js"></script> -->
</head>
<body>
<div id="root">
    <div @click="addmsg">点击加2{{fooObj.foo}}</div>
    <child>
        <!-- 作用域插槽必须是template开头且结尾 -->
        <template slot-scope="props">
           <li v-html="props.value ===2? '<strong style=\'color:red;\'>2</strong>':props.value" ></li>
        </template>
    </child>
</div>
<script type="text/javascript">
    Vue.createApp({
        data(){
            return {
                    hi:'hellow world'
                }
            },
        render() {
            return Vue.h('div', {}, this.hi)
        }
    }).mount("#root");

    // const RootComponent = { 
    //     data(){
    //         return {
    //             hi:'hellow world'
    //         }
    //     },
    //     render() {
    //         return Vue.h('div', {}, this.hi)
    //     } 
    // }
    // const app = Vue.createApp(RootComponent)
    // const vm = app.mount('#root')
</script>
</body>
</html>

在这里插入图片描述

复杂的dom(比如几十个v-if判断的dom)可以用render来简化

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

前端段

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值