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>