NervJS / taro

开放式跨端跨框架解决方案,支持使用 React/Vue/Nerv 等框架来开发微信/京东/百度/支付宝/字节跳动/ QQ 小程序/H5/React Native 等应用。 https://taro.zone/
https://docs.taro.zone/
Other
35.09k stars 4.75k forks source link

taro 3.0 + Vue 中scoped在h5下生效,在微信小程序中无效 #6662

Open XboxYan opened 4 years ago

XboxYan commented 4 years ago

问题描述

taro 3.0 + Vue 中scoped在h5下生效,在微信小程序中无效

复现步骤

Vue 引入了组件作用域的概念,通过在style标签上添加scoped属性,让这一部分 CSS 只在该组件内有效

<style scoped>
  .red {
      color: red
  }
</style>

内部原理是,这个可选 scoped 属性会自动添加一个唯一的 属性 (比如 data-v-21e5b78) 为组件内 CSS 指定作用域,编译的时候 .red 会被编译成类似 .red[data-v-21e5b78]

H5模式下dom生成了[data-v-xxx]属性

image

微信小程序模式下没有生成[data-v-xxx]属性

image

期望行为

在微信小程序中正常

系统信息

Taro v3.0.0-rc.4

如果您有功能上的建议,可以提到 FeatHub

使用上的问题,欢迎在「Taro 社区」一起交流

Chen-jj commented 4 years ago

@XboxYan 使用 cssModules 吧,小程序不支持给节点动态添加属性

XboxYan commented 4 years ago

@Chen-jj cssModules也有问题,只能设置global

// config/index.js
const config = {
  // ...
 h5: {
    //...
      cssModules: {
        enable: true, // 使用 css modules 功能,设为 true
        config: {
          namingPattern: "global", // 转换模式
          generateScopedName: "[name]__[local]___[hash:base64:5]"
        }
      }
    }
  }
}

同时,在module样式表中,引入其他样式在 H5 中无效,小程序中却生效

<style module>
@import 'index.scss'; /* 在 H5 中无效,小程序中生效 */
.red{
  color: red;
}
</style>
cat-walk commented 3 years ago

遇到了类似的问题。

taro版本

3.0.2

目前的生效方式

postcss下配置css module不生效。 通过cssLoaderOption配置为global才能生效。

    cssLoaderOption: {
      modules: {
        mode: 'global',
        localIdentName: '[name]__[local]___[hash:base64:5]'
      }
    },

一点小建议

mpvue里实现了scoped style,如果taro也能直接通过scoped style实现的话,就更好了~

gsy13213009 commented 3 years ago

瞬间不香了

ab690257072 commented 3 years ago

同问,是否有解决方法

luoway commented 3 years ago

@XboxYan 使用 cssModules 吧,小程序不支持给节点动态添加属性

微信小程序不支持属性选择器,添加了也没用。

为什么不参考mpvue、uni-app动态添加class实现支持?

MrLeihe commented 3 years ago

@XboxYan 使用 cssModules 吧,小程序不支持给节点动态添加属性

微信小程序不支持属性选择器,添加了也没用。

为什么不参考mpvue、uni-app动态添加class实现支持?

确实,可以考虑动态添加 class 实现支持

15380831711 commented 3 years ago

手动添加class方案:

<template> <view class="content-view page-index"> </view> </template>

<script></script>

<style lang="scss"> .page-index { @import "./index.scss"; } </style>

JiaLe1 commented 3 years ago

参考:https://taro-docs.jd.com/taro/docs/css-modules/

  1. 配置 config/index.js 里的 h5minicssModules 属性
    const config = {
    ...
    mini: {
        postcss: {
            cssModules: {
                enable: true, // 默认为 false,如需使用 css modules 功能,则设为 true
                config: {
                namingPattern: 'module', // 转换模式,取值为 global/module
                generateScopedName: '[name]__[local]___[hash:base64:5]'
        }
      }
        }
    }
    }

2.将 index.scss 重新命名 index.module.scss 3.以 import styles from './index.module.scss' 引入,className 取值 styles[key]

// index.module.scss
.everybody-using {
  margin: 0 15PX;

  .title {
    margin: 22PX 0;
    font-size: 18PX;
    font-weight: 500;
    color: #222222;
  }

  .header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 10PX;
    border-radius: 6PX 6PX 0 0;
    background: linear-gradient(135deg, rgba(251, 208, 7, .45), rgba(255, 156, 0, .45));

    .icon {
      display: flex;
      align-items: flex-end;

      .apple-icon-fill {
        display: block;
        width: 15PX;
        height: 17PX;
        margin-right: 8PX;
      }

      .name {
        font-size: 14PX;
        font-weight: 500;
        color: #242121;
      }
    }

    .right {
      display: flex;
      align-items: center;

      .arrow-right {
        margin-left: 8PX;
        width: 5PX;
        height: 10PX;
      }
    }
  }

  .list {
    display: flex;

    .list-item {
      padding: 0 10PX;

      .image {}
    }
  }
}

@media screen and (max-width: 414PX) {
  .list-item {
    width: (100% / 3);
  }
}

@media screen and (min-width: 415PX) {
  .list-item {
    width: 105PX;
  }
}
// index.tsx
import React, { useState, useEffect } from 'react'

import styles from './index.module.scss'
import { View, Image, Text } from '@tarojs/components'

export default function EverybodyUsing() {

  return (
    <View className={styles['everybody-using']}>
      <View className={styles['title']}>大家都在用</View>
      <View className={styles['header']}>
        <View className={styles['icon']}>
          <Image className={styles['apple-icon-fill']} lazyLoad src={require('./assets/apple.png')}></Image>
          <View className={styles['name']}>苹果专区</View>
        </View>
        <View className={styles['right']}>
          <View>全部</View>
          <Image className={styles['arrow-right']} lazyLoad src={require('./assets/arrow-right.png')}></Image>
        </View>
      </View>
      <View className={styles['list']}>
        <View className={styles['list-item']}>
          <View>【京东95新】iPhone 11</View>
          <View>到手价 <Text>¥3788</Text></View>
          <View>指导价¥5299</View>
        </View>
        <View className={styles['list-item']}>
          <View>【京东95新】iPhone 11</View>
          <View>到手价 <Text>¥3788</Text></View>
          <View>指导价¥5299</View>
        </View>
        <View className={styles['list-item']}>
          <View>【京东95新】iPhone 11</View>
          <View>到手价 <Text>¥3788</Text></View>
          <View>指导价¥5299</View>
        </View>
      </View>

    </View>
  )

}
nyrf commented 3 years ago

@XboxYan 使用 cssModules 吧,小程序不支持给节点动态添加属性

uni-app是可以的,不知道能不能参考 实现?

xiebiao360 commented 3 years ago

@JiaLe1 taro 3.0 + Vue中怎么使用?

Developer27149 commented 3 years ago

taro + vue3

  1. 开启 mini cssModules
  2. import styles from './xx.module.scss'
  3. script setup 最后返回 style
  4. template中动态设置选择器,例如::class="style.btn-primary"
SJanJan commented 2 years ago

有解决方案了吗

wangrongding commented 2 years ago

蹲一个~

Chen-jj commented 2 years ago

同时,在module样式表中,引入其他样式在 H5 中无效,小程序中却生效

<style module>
@import 'index.scss'; /* 在 H5 中无效,小程序中生效 */
.red{
  color: red;
}
</style>

备注:是因为小程序环境启用了 postcss 插件 postcss-import,而 H5 没有启用它,从而导致

hu-qi commented 2 years ago

taro + vue3

  1. 开启 mini cssModules
  2. import styles from './xx.module.scss'
  3. script setup 最后返回 style
  4. template中动态设置选择器,例如::class="style.btn-primary"

蹲一波更新

yijinc commented 1 year ago

taro + vue3

  1. 开启 mini cssModules
  2. import styles from './xx.module.scss'
  3. script setup 最后返回 style
  4. template中动态设置选择器,例如::class="style.btn-primary"

大佬,我也觉得Css Module 很香 但是请问有什么智能识别的插件吗,比如 输入 styles.的时候 自动识别classname, 这个CSS Modules插件 只在 JSX 中有效

femaimi9527 commented 1 year ago

从性能上考虑来说,在小程序里面,能用css解决的问题,最好不要用js的方式,希望大佬们能攻克css的难题,发展更完美的css方式

XieJiSS commented 1 year ago

Gently pinging on this issue

zgliubo commented 1 year ago

微信小程序现已支持data-*属性选择器, 可否考虑实现