vue--组件间传值的常用方式总结(后续还须补充)

父向子传值

通过标签属性传值
    如果子组件的props接收了 那这个标签属性就具有props特性
    如果子组件的props没有接收 那这个标签属性就是一个普通的自定义属性

父组件如何向子组件传值
父组件通过标签属性的形式向子组件传值。
子组件可以通过props属性正常接收到来自父组件的值。
但值得注意的是 子组件接收到父组件的值后不应该修改接收到的值,
因为该值果然是一个对象,而且被几个子组件共同引用着。那很有可能会导致脏数据

       非得改这数据,应该怎么办?
           转存一份,再改

在vue中组件间传值是要单向数据流的,子组件不能随意修改来着父组件的值。

<body>
    <div id="app">
        <v-count class="count" :count="count"></v-count>
        <v-count class="count" :count="count"></v-count>
    </div>
</body>
<script src="https://cdn.bootcdn.net/ajax/libs/lodash.js/4.17.21/lodash.min.js"></script>
<script src="../../js/vue.js"></script>
<script>
    Vue.config.productionTip=false;
    new Vue({
        el:"#app",
        data:{
            count:{
               flag:0
            }
        },
        components:{
            "v-count":{
                props:["count"],
                data(){
                  return {
                      //转存!!! 不是存地址值!! 而是存实际的数据!!!
                      // myCount:JSON.parse(JSON.stringify(this.count))
                      myCount:_.cloneDeep(this.count) //引入第三方库来深度复制
                  }
                },
                template:`<span @click="add">{{myCount.flag}}</span>`,
                methods:{
                    add(){
                        //子組件直接修改了父组件的数据  不可取!!!
                        //在大型项目中 会造成代码难以维护!
                        this.myCount.flag++
                    }
                }
            }
        }
    })
</script>

props

    props特性
        最终不会表现在dom节点中
        子组件拿到props之后就等于是拿到了一个data
    非props特性
        会表现在dom节点中

    props验证:
        我们可以为组件的 prop 指定验证要求,例如你知道的这些类型。如果有一个需求没有被满足,
        则 Vue 会在浏览器控制台中警告你。这在开发一个会被别人用到的组件时尤其有帮助

        验证方式:
            props:[] 数组;数组的每一项表示接受父组件传过来的哪些属性(无法做验证)
            props:{} 对象;通过键值对的形式表示接受父组件传过来的哪些属性
                key :哪些属性
                value:验证规则
                    key:type
                    key:[type1,type2]
                    key:{
                        type: String,
                        required: true,
                        //default: 100
                        // 对象或数组默认值必须从一个工厂函数获取
                        default: function () {
                            return { message: 'hello' }
                        }
                       //自定义验证
                          validator: function (value) {
                            // 这个值必须匹配下列字符串中的一个
                            return ['success', 'warning', 'danger'].indexOf(value) !== -1
                          }
                    }
                type: String Number Boolean Array Object Date Function Symbol

子向父传值

1.子组件通过触发一个方法(该方法触发的是vue自定义事件)
2. 通过vue自定义事件
<body>
    <div id="app">
        <v-count class="count" :count="count" @add="add"></v-count>
        <v-count class="count" :count="count" @add="add"></v-count>
    </div>
</body>
<script src="https://cdn.bootcdn.net/ajax/libs/lodash.js/4.17.21/lodash.min.js"></script>
<script src="../../js/vue.js"></script>
<script>
    Vue.config.productionTip=false;
    new Vue({
        el:"#app",
        data:{
            count:{flag:0}
        },
        methods:{
          add({name,step}){
              if(name==="v-count"){
                  this.count.flag+=step
              }
          }
        },
        components:{
            "v-count":{
                props:["count"],
                template:`<span @click="add">{{count.flag}}</span>`,
                methods:{
                    add(){
                        //子向父的数据传递(通过vue自定义事件)
                        this.$emit("add",{name:"v-count",step:2})
                    }
                }
            }
        }
    })
</script>

非父子

总线机制(on是绑定(接收值),emit是执行(给值))
<body>
    <div id="app">
        <v-a></v-a>
        <v-b></v-b>
    </div>
</body>
<script src="../../js/vue.js"></script>
<script>

    //Object.create 实现对象级别的继承
    //vue源码: VueComponent.prototype = Object.create(Vue.prototype)
    //         VueComponent.prototype.__proto__ = Vue.prototype


    // 对象的隐式原型 指向其构造函数的 显示原型
    // 原型链: 隐式原型链
    /*vue组件的原型链:
        vue组件.__proto__
            VueComponent.prototype.__proto__
                Vue.prototype.__proto__
                    Object.prototype.__proto__
                        null*/

    Vue.config.productionTip=false;
    Vue.prototype.$bus=new Vue()
    new Vue({
        el:"#app",
        components:{
            "v-a":{
                template:`<span @click="clickFn">v-a组件</span>`,
                data(){
                  return {
                      msg:"msg from v-a"
                  }
                },
                methods:{
                    clickFn(){
                    //第一个参数时需要执行的on的事件名,第二个参数是传递的参数
                        this.$bus.$emit("msg",this.msg)
                    }
                }
            },
            "v-b":{
                template:`<span>{{msg}}</span>`,
                data(){
                  return {
                      msg:"v-b组件"
                  }
                },
                mounted(){
                    //this.$bus.$emit("msg")
                    //第一个参数是名称(emit时需要),第二个参数时回调函数(让这个组件的msg等于传过来的msg)
                    this.$bus.$on("msg",(msg)=>{
                        this.msg = msg
                    })
                }
            }
        }
    })
pubsub
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值