<style>的scope属性

这几天做一个忘记密码的功能,vue的项目,因为涉及到弹框组件,所以用vue封装了一个弹框组件,在需要的地方去引入,下面是组件的代码:

<!--
isShow type : object
key : 父组件中控制弹框显示和隐藏的属性名
value : 父组件中控制弹框显示和隐藏的属性值
title  type : string 弹框的title
titleImgSrc type : string url 弹框顶部的图片
width type : number||string 弹框的宽度 支持百分比
closeClickModel : boolean 点击遮罩层是否关闭弹框 默认true 关闭
showCloseBtn : boolean 是否显示关闭弹框按钮,默认不显示
-->
<template>
    <div v-show="isShow.value" class="vkd-dialog-box" @click.self="clickModelClose" >
        <div class="dialog" :style="style">
            <div @click="closeDialog" class="close-btn" v-if="showCloseBtn"></div>
            <div class="dialog-img" v-show="titleImgSrc">
                <img :src="titleImgSrc" alt="title image">
            </div>
            <div class="dialog-content">
                <h4 class="dialog-title">{{title}}</h4>
                <div class="dialog-body">
                    <slot></slot>
                </div>
                <div class="dialog-footer">
                    <slot name='footer'></slot>
                </div>
            </div>
        </div>
    </div>
</template>
<script>
  export default {
    name:'vkd-Dialog',
    props:{
      'isShow':{
        type:Object,
        default:()=>{
          return{
            key:'key',
            value:false
          }
        }
      },
      'title':{
        type:String,
        default:''
      },
      'titleImgSrc':{
        type:String
      },
      'width':{
        type:[Number,String],
        default:300
      },
      'closeClickModel':{
        type:Boolean,
        default:true
      },
      'showCloseBtn':{
        type:Boolean,
        default:false
      }
    },
    methods:{
      clickModelClose(){
        this.closeClickModel&&(this.$parent[this.isShow.key]=!this.$parent[this.isShow.key]);
      },
      closeDialog(){
        this.$parent[this.isShow.key]=!this.$parent[this.isShow.key];
      }
    },
    computed:{
      style(){
        return {
          width:/^-?\d+%$/.test(this.width)?this.width:this.width+'px'
        }
      }
    }
  }
</script>
<style lang="scss" scoped>
    .vkd-dialog-box{
        position: absolute;
        z-index: 10000;
        width:100%;
        height:100%;
        top:0;
        left:0;
        background:rgba(0,0,0,0.5);
        .dialog{
            position: fixed;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
            background: #fff;
            width:300px;
            .close-btn{
                width:24px;
                height:24px;
                background: url('../assets/closeBtn.png') no-repeat;
                position: absolute;
                right:15px;
                top:15px;
                cursor: pointer;
            }
            .dialog-img{
                img{
                    width: 100%;
                }
            }
            .dialog-content{
                padding:12px 30px 30px 30px;
                text-align: left;
                .dialog-title{
                    margin:0;
                    line-height: 26px;
                    font-size: 24px;
                }
                .dialog-body{
                    padding-top:12px;
                    font-size: 14px;
                    color: #767676;
                    line-height:18px;
                }
                /*.email-icon{*/
                /*display: inline-block;*/
                /*margin-right:10px;*/
                /*width:15px;*/
                /*height:10px;*/
                /*background: url("../../assets/img/login/email.png") no-repeat 0 0;*/
                /*background-size: 100% 100%;*/
                /*}*/
                /*.email{*/
                /*color:#03a9f4*/
                /*}*/
                /*.text{*/
                /*padding-top:12px;*/
                /*line-height:18px;*/
                /*color: #767676;*/
                /*}*/
                .dialog-footer{
                    margin-top:30px;
                    overflow: hidden;
                    text-align: right;
                    button{
                        text-align: center;
                        width: 65px;
                        height: 20px;
                        border-radius: 3px;
                        background-color: #fdb62b;
                        color:#fff;
                        border: none;
                        margin-left:10px;
                        font-size:14px;
                        cursor: pointer;
                    }
                    span{
                        color: #767676;
                        font-size:14px;
                    }
                }
            }
        }
    }
</style>

  在需要的组件中引入弹框组件,然后需要修改一些个性化的样式,比如title的字体颜色,发现无论怎样增加权限都没办法覆盖子组件中的样式,后来发现了问题,因为子组件和父组件的style中都使用了scope属性,浏览器渲染后,给每个组件中的元素增加了自定义属性,如图

而浏览器渲染样式的时是这样的

 

这也是scoped的工作原理,所以在子组件中写的元素,只有子组件中的自定义属性,而父组件中加的样式,最终浏览器渲染时是找不到对应的元素的,(因为父组件中样式给出的自定义属性是不一致的),所以子组件中.dialog-title的样式没办法在父组件中修改,而.dialog-footer中的button的样式是可以修改的,因为button是写在父组件中,以slot的方式插入在子组件中的,而dialog-title是通过设置props属性传递给子组件的。明白了原因后,对子组件做出了修改

如此,弹框中的header,body,footer都可以愉快地个性化样式了,但是弹框整体的风格还是需要公共组件控制的,这也是公共组件的用处吧。

另外查了下原生的scope属性,已经不支持了,所以现在只能在这些.vue的模版文件中使用,等等

 

完了,有点啰嗦。

posted @ 2018-08-15 17:07  如斯~  阅读(1682)  评论(0编辑  收藏  举报