子组件和父组件

child

<template>

    <div id="child">

        <button @click="changeFu">子组件1改变父组件</button>

        <h1>子组件1的值:{{cmsg}}</h1>

        <ul>

            <li v-for="(item,i) in childList" :key="i" @click="changeList(i)">

                姓名:{{item.name}}

                年龄:{{item.age}}

            </li>

        </ul>

        <h2>汽车品牌:{{cobj.car}} 价格:{{cobj.price}}</h2>

        <h3>{{cfn()}}</h3>

    </div>

</template>

<script>

export default {

    /* keep alive 判断需要用组件的name */

    /* 递归组件自己调用自己 也需要使用name */

    /* vue devtools 你看到组件名就是name值 */

    name:"child",

    /* props接收值第一种方式 数组 数组里面是字符串类型的传过来的参数*/

    /* props:['cmsg'] */

    /* props接收值第二种方式 对象 属性名是传过来的参数 属性值是规定的类型 */

    /* props:{

        cmsg:String

    } */

    /* props接收值第三种方式 对象里面再写对象 属性名是传过来的参数

    里面的对象 有规定类型 和 默认值 */

    /* 默认值的意思是当你不传参数的时候默认显示的值 */

    props:{

        cmsg:{

            type:String,

            default:"默认值"

        },

        childList:{

            type:Array,

            default:()=>[]

        },

        cobj:{

            type:Object,

            /* 这样写 会报错 因为默认导出一个对象,

            会把里面写的内容当成表达式并没有当成对象里面的key和value */

            /* default:()=>{

                car:"大众",

                price:"10w"

            } */

            default:()=>{

                return {

                    car:"大众",

                    price:"10w"

                }

            }

        },

        cfn:{

            type:Function,

            default:()=>()=>{}

        }    

    },

    methods:{

        /* vue中组件传值有个规定

        需要保持单向数据流

        父组件可以直接传给子组件

        子组件不可以直接修改父组件的值 */

        changeFu(){

            /* 不可以 */

            /* this.cmsg = '我以后工作在硅谷' */

            /* 子组件传给父组件使用$emit */

            /* this.$emit(自定义的事件名,需要传给父组件的值) */

            this.$emit('childChange','我以后工作在硅谷')

        },

        changeList(i){

            this.$emit('childListC',i,'德利',89)

        }

    }

}

</script>

<style scoped>

/* style没有加上scoped的作用域的情况下,是全局的  */

/* scoped作用的就是防止自己写的样式 给全局带来污染 设置的作用域

加了scoped当前的样式 只对当前的组件管用 */

    /* .red{

        background:red;

    } */

</style>

child2

<template>

<!--  template里面的内容 node会解析

../assets/logo.png 这句话在node会当成普通的字符串

而编译后的开发环境是找不到对应的地址的 -->

 <!-- style="background:url(../assets/logo.png)" -->

<!-- 解决方案需要使用node的require方法,把相对路径转成node解析后的地址 -->

<!-- 这个路径是脚手架 打包后的图片的地址

background: url("/img/logo.82b9c7a5.png") no-repeat;

是开发环境中打包编译出来的,实际上没有img这个文件 -->

<!-- :style="{background:'url('+imgurl+') no-repeat'}" -->

<!-- 图片在根路径下这样写是可以被识别的 -->

<!-- style="background:url(/images/logo.png) no-repeat" -->

  <div id="child2">

      <!-- <h1

        class="red"

        :style="{background:`url(${img}) no-repeat`}"

      >child2</h1> -->

      <h1>子组件2的值:{{cmsg2}}</h1>

      <ul>

            <li v-for="(item,i) in childList" :key="i">

                姓名:{{item.name}}

                年龄:{{item.age}}

            </li>

        </ul>

  </div>

</template>

<script>

export default {

    name:"child2",

    props:['cmsg2','childList'],

    data(){

        return {

            /* 根路径下的图片可以直接使用 */

            img:'/images/logo.png',

            /* 如果图片是src资源路径下的assets文件夹里面的必须使用require */

            imgurl:require('../assets/logo.png')

        }

    }

}

</script>

<style scoped>

    h1{

        /* width: 400px;

        height: 400px; */

        /* 在style里面是不可以使用@ 只能使用相对路径或者根路径 */

        /* background: url(../assets/logo.png) no-repeat; */

        /* background: url(/images/logo.png) no-repeat; */

    }

</style>

childnew

<template>

  <div id="ChildNew">

    <h1 @click="changeTit">{{ctitle.name}}</h1>

    <ul>

      <li v-for="(item, i) in cList" :key="i">

        姓名:{{ item.name }} 年龄:{{ item.age }}

        <button @click="del(i)">删除</button>

      </li>

    </ul>

    <button @click="dian">点我</button>

  </div>

</template>

<script>

export default {

  name: "ChildNew",

  /* props:['cList'], */

  props: {

    cList: {

      type: Array,

      /* 要求必须传参数,否则会给与vue警告 */

      required: true,

      /* default: () => [{ name: "默认A", age: 100 }], */

    },

    ctitle:{

      type:Object,

      required:true

    }

  },

  data(){

    return {

      aa:"我被获取了",

      childA:"childA",

      busAVal:"我好辛苦的发送出去了"

    }

  },

  /* 在vue3里面取消了created的钩子函数,但是mounted依然存在 */

  mounted(){

    /* 通过父组件去传值 */

    this.$emit('childAHandle',this.childA)

    /* 在mounted里面涉及一个问题 组件加载的先后顺序问题

    B组件先加载了,但是A组件还没有发送,所以触发不了$on事件 */

    console.log('我是组件1');

    /* this.$bus.$emit('busAHandle',this.busAVal) */

  },


  methods: {

    dian(){

      this.$bus.$emit('busAHandle',this.busAVal)

    },


    changeTit(){

      /* 不可以违反了单向数据流的原理 */

      /* 必须通过$emit的形式去修改 */

     /*  this.ctitle = '子组件' */

      /* this.$emit('changett','子组件') */

      this.$emit('update:ctitle',{name:"lisi"})

    },

    del(i) {

        this.$emit('delItem',i)

    },

    toast(){

      alert('我被触发了')

    }

  },

};

</script>

<style scoped>

#ChildNew {

  text-align: center;

}

</style>

childnew2

<template>

  <div id="ChildNew2">

      <h1>ChildNew2</h1>

      <h2>{{childval2}}</h2>

      <h2>{{msg}}</h2>

  </div>

</template>

<script>

export default {

    name:"ChildNew2",

    props:['childval2'],

    data(){

        return {

            msg:""

        }

    },

    created(){

        console.log('我是组件2');

        /* 先监听事件 再触发发送事件 */

        this.$bus.$on('busAHandle',(val)=>{

            console.log(val)

            this.msg = val

        })

    },

    mounted() {

        /* console.log('我是组件2'); */

    },

}

</script>

<style scoped>

#ChildNew2{

    text-align: center;

}

</style>

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容