组件,父子组件的传值
组件化开发
组件化开发,指的是,根据封装的思想,把页面上,可以重用的部分分装成为组件,从而更方便项目开发和维护
一个页面,可以拆分成一个个组件,一个个组件是一个整体,每个组件可以有自己独立的结构,样式,行为
我们创建脚手架的时候,使用的App.vue,这个就是最大的根组件
跟组件存放的位置:src中的components中,(components)翻译成中文为组件的意思
组件的名称,只可以使用英文来命名
组件分为全局组件和局部组件
全局组件是全局都可以使用的,局部组件只有在声明的页面中调用使用
使用组件
我们首先创建出来全局组件(overAll)和局部组件(local)

然后我们去main中引入注册全局组件,使用import关键字创建组件

最后我们使用全局注册的组件

局部组件
我们去需要使用的vue组件中,引入和注册组件

注意点局部组件,在需要调用的文件中引入文件注册组件,只能在改文件中使用
<template> <div> <over-all></over-all> <over-all></over-all> <local></local> <local></local> </div> </template> <script> // 1,引入局部组件 import local from "@/components/local"; export default { // 2,注册局部组件,注意点局部组件要写在 components中 components: { local : local //组件名称:引入的组件名称 } } </script>
组件合并后的样式冲突scoped
全局组件:注册好以后,整个项目里面任何地方都可以直接使用
但是在默认情况下,组件内部会有样式冲突,样式作用在全局,相同class类名,会导致样式冲突,另外一个组件的样式渲染到这个样式中
但是我们往往是只需要当前样式只在当前组件中生效,这个时候我们就需要给style标签中添加scoped
语法:<style scoped></style>
添加scoped以后
组件内部,会给标签身上添加一个自定义属性;每个style样式也会添加上,对应的属性选择器。
只有两个属性选择器对应上的时候,才会显示该样式,如果两个属性选择器样式对应不上的时候,就不会添加该属性,这样实现了样式隔离
父组件和子组件的传值
方法一:
父组件传递给子组件,可以使用自定义属性传值
子组接收,使用props接收,接收到的值,可以直接在子组件中使用

方法二:父组件使用数组的方法传值,子组件动态接收父组件的传值
我们父组件使用v-for,动态绑定数组中的属性值,传递给子组件

方法三:我们直接传递数组过去
我们的父组件直接传递数组过去,让子组件接收

子组件传递给父组件(修改父组件传递过来的内容中的数据)
如果父组件传递过来的是基本组件,子组件是不能随意修改的
如果父组件传递下来的是复杂数据类型,子组件只能修改内部属性;如果传递下来的是复杂数据类型,会把这个数据直接替换掉,会报错
所以子组件从props接收过来的数据,子组件不能随意修改,会报错。如果子组件要修改父组件传递过来的属性,不能直接修改,可以通过触发父组件的自定义方法,让父组件自己修改

子组件代码:
<template>
<!-- 我们在子组件中动态接收传递过来的数值-->
<div class="box">
<div>{{name}}</div>
<div>战力:{{zhanLi}}</div>
<div>描述信息:{{des}}</div>
<div style="display: none">id值{{id}}</div>
<button @click="jia(id)">加战力+10</button>
</div>
</template>
<script>
export default {
name: "local",
props : {
id : {},
name : {},
zhanLi : {},
des : {},
list : {
type : Object, //传递的值必须是对象
list : () => { // 设置一个当默认没有传值的时候,默认传递一个空的对象
return {} //不能直接复制一个对象,需要利用函数方式return出来一个对象
}
}
},
//(1) 我们对子组件的数值进行修改
methods : {
// (2)我们把子组件信息传递给父组件,让父组件自己修改
jia (id) {
// console.log(`点击的${id}`) //确定点击的是选中那一项
// this.list.zhanLi += 10 //子组自己修改会报错
// (3)使用$emit把子组件需求的信息传递给父组件
this.$emit(`parentJia`,+10,this.id) //this.$emit(`按钮的名称`,需求,点击的id)
}
}
}
</script>
<style scoped>
.box {
width: 400px;
height: 100px;
border: 1px solid #0ac2f3;
border-radius: 10px;
margin: 20px;
padding: 20px;
}
</style>
父组件代码:
<template> <div> <!-- 2,我们使用v-for循环传值--> <!-- 动态传递属性值--> <!-- (4)我们给父组件添加一个事件,接收子组件传递的事件@parentJia="parentJia"--> <local v-for="(item,index) in list" :id="item.id" :name="item.name" :zhanLi="item.zhanLi" :des="item.des" :list="item" @parentJia="parentJia" ></local> </div> </template> <script> // 引入组件 import local from "@/components/local"; export default { // 注册组件 components: { local : local }, data () { return { // 1,父组件向子组件传值,可以使用自定义属性传值 list : [ {id : 1, name : `王路飞🧩`,zhanLi : 2000, des : "5挡战神"}, {id : 2, name : `黑胡子🧩`,zhanLi : 3000, des : "有野心"}, {id : 3, name : `红发🧩`,zhanLi : 2900, des : "属实屌"}, {id : 4, name : `巴基🧩`,zhanLi : 1000, des : "舒适拉跨"}, ] } }, methods : { //我们在父组件身上进行修改 parentJia(num,id) { //接收子组件的穿过来的需求和id this.list.forEach(i => { if (i.id === id) { i.zhanLi += 10 //给对应的数据加10 } }) } } } </script>
总结:父组件和子组件
父组件传递给子组件数值,需要通过自定义属性传值。子组件接收,使用props接收,接收的值可以直接在子组件中使用
一共有三种方法传值:(静态传值,动态传值,传递数组,子组件进行解构接收)
子组件传递给父组件,因为子组件不能直接自己修改数据,需要把自己的需求传递给父组件,父组件进行接收
传递方法:
子组件创建一个方法,使用 this.$emit(`传递的名称`,需求,对应的id值进行准确修改)
父组件通过自定义事件进行接收
接收以后,在方法中提供一个方法对数据进行修改,返回给子组件
所以:如果子组件要修改父组件传递下来的基本值,或者替换对象地址,需要通过自定义方法进行实现

浙公网安备 33010602011771号