vue样式穿透和组件传值
vue样式穿透和组件传值
vue样式穿透(深度作用选择器)
问题产生原因:当前组件A引入一个其他组件B做应用,A组件由于scoped作用,本身的全部html标签都会包含一个 data-v-xxx 的属性名称,使得css样式达到私有效果。被使用的组件B由于某些原因,编译解析后各个html标签不会形成 data-v-xxx 的属性,这样在组件A中给组件B设置样式会导致无效
解决办法:
1、通过深度作用选择器/deep/ 给B组件的某些标签设置样式
.a /deep/ .b { /* ... */ }
a是组件A的选择器,b是组件B的选择器,它们会形成如下效果
.a[data-v-f3f3eg9] .b { /* ... */ }
这样.b的css样式就生效了
注意:
1、某些情况下>>>符号有可能无法正确解析,可以替换为别名 /deep/ 或 ::v-deep
2、深度作用选择器的左边必须是当前组件的css选择器,右边是子组件标签选择器
vue组件传值
一、兄弟(非父子)组件之间传值
实现步骤:
(1)定义模块 src/bus.js,内容就是导入Vue模块并导出一个Vue实例对象
import Vue from 'vue'
export default new Vue()
(2)在各个兄弟组件中,导入 bus.js 模块
import bus from '@/bus.js'
虽然bus.js被各个组件都导入,但是系统中bus只有一份
(3)在接收数据的兄弟组件的 created 生命周期方法里(使得事件及时响应),"大哥"的组件中声明使用 bus.$on(‘事件名称’, (接收的数据) => {}) 定义事件成员方法
created(){
// 定义事件,注意箭头函数应用
bus.$on('xxx', data=>{
console.log(data)
})
}
xxx是事件方法的名称
data是形参,待接收数据,并且可以定义多个
注意:如果$on内部要使用this,请通过"箭头函数"声明方法
(4)在发送数据的兄弟组件中,使用 bus.$emit(‘事件名称’, 要发送的数据) 来向外发送数据
<button @click="sendMsg">给兄弟说话</button>
export default {
methods: {
sendMsg(){
// 触发 绑定的 事件,并向外传递参数
bus.$emit('xxx', '1000元保护费')
}
}
}
xxx 是接收数据组件给bus声明的方法,第二个参数是传递的实参数据
说明:
1、Vue实例可以调用$on()方法进行事件方法创建
实例.$on(名称,(形参,形参,形参……){})
参数根据需要,可以是一个或多个
2、Vue实例可以调用$emit()方法进行事件方法调用
实例.$emit(名称,实参,实参,实参……)
参数 与 $on的形参是一一对应的
注意:虽然各个兄弟组件针对bus.js都有做引入,系统在运行的时候只有一个bus对象,故大哥 给 bus绑定的事件方法,老二可以通过bus调用
**案例应用:**小弟给大哥传值(components里有first.vue和second.vue)
(1)src/bus.js代码:
// 快递员,负责兄弟组件之间传递数据
import Vue from 'vue'
// 导出一个Vue对象
// 注意:这是一个新的对象,与main.js里边的没有关系
export default new Vue()
(2)First.vue代码(created、$on设置事件方法,准备接受数据):
<template>
<div id="one">
<h3>大哥组件</h3>
<span>接收小弟的礼物:{{money}}</span>
</div>
</template>
<script>
// 引入bus.js进来
import bus from '@/bus.js'
export default {
name: 'One',
// 在created中给bus绑定事件,时机最靠前,随时可以响应使用
data () {
return {
// 接收小弟来到数据
money: ''
}
},
created () {
// this:组件实例对象
// 注意:设置为箭头函数
bus.$on('receive', val => {
// val:是其他应用处给传递的数据
// 把获得的数据赋予money
this.money = val
})
}
}
</script>
<style lang="less" scoped>
#one{
width: 300px;
height: 100px;
border:1px solid red;
margin-bottom:20px;
}
</style>
(3)Second.vue代码(bus调用$emit()调动事件进行数据传递):
<template>
<div id="two">
<h3>小弟组件</h3>
<p>
<button @click="say">给大哥说话</button>
</p>
</div>
</template>
<script>
// 引入bus.js进来
import bus from '@/bus.js'
export default {
name: 'Two',
methods: {
// 实现给大哥传递数据的
say () {
// 让bus调用自己的事件
bus.$emit('receive', '1000元保护费')
}
}
}
</script>
<style lang="less" scoped>
#two{
width: 300px;
height: 100px;
border:1px solid greenyellow;
}
</style>
(3)App.vue代码(引入、注册、使用各个兄弟组件):
<template>
<div id="app">
<h2>App根基组件(兄弟之间传值)</h2>
<!--使用两个兄弟组件-->
<first-com></first-com>
<second-com></second-com>
</div>
</template>
<script>
// 对大哥、小弟两个组件做 引入、注册、使用
import FirstCom from '@/components/First.vue'
import SecondCom from '@/components/Second.vue'
export default {
name: 'App',
components: {
FirstCom,
SecondCom
}
}
</script>
<style lang="less" scoped>
#app{
width: 400px;
height: 400px;
border:2px solid blue;
}
</style>
补充:非父子之间也可已通过vuex共享数据
二、父给子传值
父组件可以 引入、使用 子组件,从业务上看,该父组件有可能对子组件有个性化需求,为了体现组件的灵活多变,可以通过传值实现
例如:父组件多次使用按钮组件,每次要求按钮的文字显示不同颜色,就可以通过传值实现
语法:父组件要在子组件标签上通过属性值方式传值
<子组件标签 name=value name=value name=value></子组件标签>
子组件接收并应用值,具体通过props接收
<!--在模板中应用传递来的数据-->
<input :style="{color:xx}">
<script>
export default {
// 通过props接收父传递过来的数据,注意各个名称需要使用单引号圈选
props:['xx','xx','xx'],
props:{
xx:{
type:类型限制
default:默认值
}
}
}
</script>
三、子给父传递
步骤:
(1)、父组件 向子组件 传递一个事件
(2)、子组件 调用 父组件 传递过来的事件,并传递相关的数据
(3)、父组件 通过事件函数参数获得子组件传递过来的数据并使用
父组件操作语法:
父组件通过@符号向子组件传递一个事件方法,并在methods中定义这个方法
<子组件 @func1="show"></子组件>
...
methods:{
show(arg1,arg2){xxxx}
}
其中:
1、func1为事件的名称,给子组件触发使用
2、show为该事件的执行函数,在父组件内部的methods中定义好
3、在事件中可以通过形参(arg1、arg2)接收子组件出来过来的数据 并做近一步处理
子组件操作语法:
子组件中,使用this.$emit()调用 父组件中的方法
this.$emit('func1', 数据, 数据)
this:当前子组件对象
$emit:通过这个关键字可以使得子组件可以调用 父组件 的事件
从第二个位置开始传递实参数据,其可以被父组件methods方法的形参所接受
$emit(名称,数据,数据……) 是组件调用自己方法的固定方式,第一个参数是被调用方法的名称,后续参数都是给方法传递的实参信息
案例应用:子组件Son.vue 给父组件App.vue 传递 ”啤酒“数据
(1)Son.vue具体代码(通过$emit()调用父给声明的btn方法):
<template>
<div id="son">
<h3>我是son子组件</h3>
<p>
<button @click="$emit('btn','啤酒')">给父传递数据</button>
</p>
</div>
</template>
<script>
export default {
name: 'Son'
}
</script>
<style lang="less" scoped>
#son{
width: 200px;
height: 100px;
border:1px solid orange;
}
</style>
(2)App.vue代码(@声明事件,methods定义事件方法,drink接收数据):
<template>
<div id="app">
<h2>App根组件(父组件)</h2>
<span>子给老子传递的信息:{{drink}}</span>
<!--使用子组件-->
<!--@ 是子组件创建(自定义)事件-->
<son-com @btn="buttonHandler"></son-com>
</div>
</template>
<script>
// 对Son.vue做引入、注册、使用
import SonCom from '@/components/Son.vue'
export default {
name: 'App',
components: {
SonCom
},
data () {
return {
// 接收子传递的数据
drink: ''
}
},
methods: {
// 子组件事件方法声明
// val:子给父传递的数据
buttonHandler (val) {
// 把信息赋予给drink
this.drink = val
}
}
}
</script>
<style lang="less" scoped>
#app{
width: 400px;
height: 200px;
border:2px solid blue;
}
</style>