欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

vue样式穿透和组件传值

程序员文章站 2022-07-14 11:11:51
...

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>
相关标签: 小知识点