经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » HTML/CSS » CSS » 查看文章
利用css var函数让你的组件样式输出规范样式API,可定制性更高;
来源:cnblogs  作者:灰色的蓝猫  时间:2023/5/10 12:39:14  对本文有异议
我们平时在使用Elementui Antdesing这些UI库时,难免会碰到使用deep强行侵入式去修改组件内部样式的情况;
 
比如下列代码,我们需要把ant的分页样式进行高度自定义,就得使用deep去修改;
 
这种实现方式确实能够达到我们的目的,但在开发时确总觉得不太合适:
1、他属于强行入侵组件内部去修改,虽然不会有大问题,但总觉得这种取巧方式有点不可取。
2、每次写deep时需要手动检查DOM元素进行编辑,UI文档中并不会有相关API文档;
 
为了解决心中的这两个结症,趁最近写组件的机会探索了下CSS 的var函数,发现他可以很好的解决以上问题。
 
利用var函数我们可以具体解决组件开发的以下问题:
 
1、组件样式自定义可以更加个性化
 
2、现在很多组件库实现一些样式控制还是依靠props传参的形式,这种var函数结合Style可完全避免props传参的情况,把样式跟props区分开;
 
3、在组件文档中可明确定制样式属性API;使组件样式可以跟Props属性一样以传参概念去进行高度定制,在使用组件样式时不需要像使用deep一样打开f12去一层一层的找
 
4、不会侵入式的改动组件内部样式
 
5、这个方案与deep互不排斥,如果开放的样式API不够用还是可以继续使用deep;
 
看下面需求,是如何利用css var函数实现一个可自定义大小,颜色,以及子元素样式的卡片
 上代码
  1. //Card.vue
  2. <template>
  3. <div class="card">
  4. <img class="card-img" :src="img" />
  5. <p class="card-desc">{{ desc }}</p>
  6. </div>
  7. </template>
  8. <style lang="scss" scoped>
  9. .card {
  10. // 这些以"--"开头的变量就是我们开放可自定义的样式属性了,可以在组件使用文档中明确开放
  11. //卡片根元素样式
  12. --width: 150px;
  13. --height: auto;
  14. --border-size: 1px;
  15. --border-color: #ccc;
  16. --border-radius: 5px;
  17. --bg: #eee;
  18. // 图片可定样式
  19. --img-width: 130px;
  20. --img-height: 130px;
  21. --img-radius: 50%;
  22. // 卡片描述样式
  23. --desc-size: 16px;
  24. --desc-line-height: 32px;
  25. --desc-color: #333;
  26. height: var(--height);
  27. width: var(--width);
  28. border: var(--border-size) solid var(--border-color);
  29. border-radius: var(--border-radius);
  30. background: var(--bg);
  31. padding: 10px;
  32. &-img {
  33. width: var(--img-width);
  34. height: var(--img-height);
  35. border-radius: var(--img-radius);
  36. overflow: hidden;
  37. }
  38. &-desc {
  39. font-size: var(--desc-size);
  40. color: var(--desc-color);
  41. line-height: var(--desc-line-height);
  42. text-align: center;
  43. }
  44. }
  45. </style>

 

这时候我们在API文档则可明确规定样式定制属性了:
组件使用方式:
  1. //demo.vue
  2. <template>
  3. <div >
  4. <Card desc="我是默认的样式我是默认的样式我是默认的样式" :img="img" />
  5. <Card class="card_1" desc="自定义样式,子元素图片变小了" :img="img" />
  6. <Card class="card_2" desc="自定义样式,圆角没了,描述字变小了,高度高了" :img="img" />
  7. </div>
  8. </template>
  9. <script>...</script>
  10. <style lang="scss" scoped>
  11. .card_1 {
  12. --width: 100px;
  13. --height: 200px;
  14. --border-radius: 20px;
  15. --img-width: 80px;
  16. --img-height: 50px;
  17. --img-radius: 10px;
  18. --desc-color: #f00;
  19. --desc-size: 12px;
  20. --desc-line-height: 21px;
  21. }
  22. .card_2 {
  23. --height: 300px;
  24. --border-radius: 0px;
  25. --bg: #fff;
  26. --img-radius: 50px;
  27. --desc-size: 14px;
  28. --desc-line-height: 21px;
  29. }
  30. </style>

 

以上就是一个基本的组件实现;
还种情况我们在使用UI库时也会碰到需要使用Props传过来计算的参数,比如下列代码:

 这种我们也可以把这些全提出来使用style属性。让样式与js参数彻底隔离

  1. //demo.vue
  2. <template>
  3. <card
  4. desc="我是默认的样式我是默认的样式"
  5. :img="img"
  6. :style="hoverStyle"
  7. @mouseout="hoverStyle = {}"
  8. @mouseover="handleHover"
  9. />
  10. </template>
  11. <script setup>
  12. let hoverStyle = ref({});
  13. const handleHover = () => {
  14. hoverStyle.value = { '--bg': '#f0f', '--width': '180px' };
  15. };
  16. </script>

 

我们在组件内

JS可以使用props.style获取到设置的值,
css中可以使用calc变量与var结合去计算你想要的值
  1. //card.vue
  2. <template>
  3. <div class="card" :style="style">
  4. {{ width }}
  5. <img class="card-img" :src="img" />
  6. <p class="card-desc">{{ desc }}</p>
  7. </div>
  8. </template>
  9. <script setup>
  10. const $props = defineProps({
  11. img: {
  12. type: String,
  13. default: '',
  14. },
  15. desc: {
  16. type: String,
  17. default: '',
  18. },
  19. style: {
  20. type: Object,
  21. default: () => ({}),
  22. },
  23. });
  24. //假如你在js中需要用到宽度
  25. let width = computed(() => {
  26. return parseInt($props.style['--width'] || 150);
  27. });
  28. </script>
  29. <style lang="scss" scoped>
  30. .card{
  31. ...
  32. //假如你有个子级元素需要基于宽度计算
  33. .item{
  34. width: calc(var(--width) - 100)
  35. }
  36. ...
  37. }
  38. </style>

 

但是这种实现有命名空间的问题
所以需要稍微注意下变量命名,最好加独有的命名规则。防止变量覆盖;
  1. //比如这样
  2. .ch-card{
  3. --ch-card-width:100px;
  4. --ch-card-height:100px;
  5. }

 

总结下这种方案的优缺点:
优点
1、组件样式自定义可以更加个性化
2、现在很多组件库实现一些样式控制还是依靠props传参的形式,这种var函数结合Style可完全避免props传参的情况,把样式跟props区分开;
3、在组件文档中可明确定制样式属性API;使组件样式可以跟Props属性一样以传参概念去进行高度定制,在使用组件样式时不需要像使用deep一样打开f12去一层一层的找
4、不会侵入式的改动组件内部样式
5、这个方案与deep互不排斥,如果开放的样式API不够用还是可以继续使用deep;
 
缺点:
1、开发组件时会工作量会增大,但是磨刀不误砍柴功
2、命名空间问题导致命名会有点长。
 
欢迎分享更好的解决方案。

原文链接:https://www.cnblogs.com/hrw3c/p/17387649.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号