วิธีเพิ่มหลายคลาสใน UI วัสดุโดยใช้อุปกรณ์ประกอบฉาก


92

การใช้เมธอด css-in-js เพื่อเพิ่มคลาสให้กับคอมโพเนนต์การตอบสนองฉันจะเพิ่มคอมโพเนนต์หลายรายการได้อย่างไร

นี่คือตัวแปรคลาส:

const styles = theme => ({
 container: {
  display: 'flex',
  flexWrap: 'wrap'
},
 spacious: {
  padding: 10
},
});

นี่คือวิธีที่ฉันใช้:

    return (
     <div className={ this.props.classes.container }>

ข้างต้นใช้งานได้ แต่มีวิธีเพิ่มทั้งสองคลาสโดยไม่ใช้classNamesแพ็คเกจ npm หรือไม่? สิ่งที่ต้องการ:

     <div className={ this.props.classes.container + this.props.classes.spacious}>

3
บางทีฉันอาจจะขาดอะไรไป แต่คุณทำ <div className = "container spacious"> ไม่ได้ทำไมคุณต้องส่งต่อเป็นคุณสมบัติ
Leo Farmer

2
คุณแค่ไม่มีช่องว่างระหว่างสอง classNames
Shanimal

ใช่ตามที่ระบุไว้ข้างต้นคุณเพียงแค่ต้องต่อชั้นเรียนเข้าด้วยกันอย่างถูกต้องโดยเว้นวรรคระหว่าง! ไม่จำเป็นต้องมีแพ็คเกจเพิ่มเติมใด ๆ
Taylor

คำตอบ:


180

คุณสามารถใช้การแก้ไขสตริง:

<div className={`${this.props.classes.container} ${this.props.classes.spacious}`}>

5
และอย่าลืมใส่เครื่องหมายจุลภาคระหว่างชั้นเรียน! ฉันทำโดยไม่ได้ตั้งใจและคนแรกก็เงียบโดยไม่ได้สังเกตสักพัก
Pere

และต้องมีช่องว่างระหว่างชั้นเรียน
Yoel

49

คุณสามารถติดตั้งแพ็คเกจนี้ได้

https://github.com/JedWatson/classnames

แล้วใช้แบบนี้

classNames('foo', 'bar'); // => 'foo bar'
classNames('foo', { bar: true }); // => 'foo bar'
classNames({ 'foo-bar': true }); // => 'foo-bar'
classNames({ 'foo-bar': false }); // => ''
classNames({ foo: true }, { bar: true }); // => 'foo bar'
classNames({ foo: true, bar: true }); // => 'foo bar'

// lots of arguments of various types
classNames('foo', { bar: true, duck: false }, 'baz', { quux: true }); // => 'foo bar baz quux'

// other falsy values are just ignored
classNames(null, false, 'bar', undefined, 0, 1, { baz: null }, ''); // => 'bar 1'

3
นี่เป็นแนวทางที่ Material-UI ใช้ในตัวอย่างบางส่วนและใช้ได้ดีดังนั้นฉันขอแนะนำสิ่งนี้
Craig Myles

2
นี่ควรเป็นคำตอบที่ได้รับการยอมรับ ทำงานได้ตามที่คาดไว้
Howie

2
เคยใช้แนวทางนี้เช่นกัน มีประโยชน์ไม่เพียง แต่สำหรับการมีหลายชื่อคลาสเท่านั้น แต่ยังรวมถึงการกำหนดเงื่อนไขด้วย
mouthzipper

4
@material-ui/coreตอนนี้ขึ้นอยู่กับclsxดังนั้นหากคุณไม่ต้องการเพิ่มขนาดมัดของคุณคุณจะต้องใช้มันแทน - npmjs.com/package/clsx
Wayne Bloss

34

คุณสามารถใช้clsx ฉันสังเกตเห็นว่ามันใช้ในตัวอย่างปุ่ม MUI

ติดตั้งครั้งแรก:

npm install --save clsx

จากนั้นนำเข้าในไฟล์คอมโพเนนต์ของคุณ:

import clsx from 'clsx';

จากนั้นใช้ฟังก์ชันที่นำเข้าในส่วนประกอบของคุณ:

<div className={ clsx(classes.container, classes.spacious)}>


5
clsxแพ็คเกจมีขนาดเล็กกว่าclassnamesดังนั้นฉันจึงชอบวิธีนี้
Hoang Trinh

2
clsx รวมอยู่ใน UI วัสดุดังนั้นจึงเป็นที่ต้องการมากกว่าชื่อคลาส
DBrown

1
ต่อความคิดเห็นของเวย์น Bloss' @material-ui/core now depends on clsx, so if you don't want to increase your bundle size you'll want to use that insteadด้านล่างคำตอบน้อยที่ดีที่สุดมินิ: ดังนั้น +1 สำหรับคำตอบนี้
cssyphus

20

หากต้องการใช้หลายคลาสกับคอมโพเนนต์ให้รวมคลาสที่คุณต้องการใช้ภายใน classNames

ตัวอย่างเช่นในสถานการณ์ของคุณรหัสของคุณควรมีลักษณะเช่นนี้

import classNames from 'classnames';

const styles = theme => ({
  container: {
    display: "flex",
    flexWrap: "wrap"
  },
  spacious: {
    padding: 10
  }
});

<div className={classNames(classes.container, classes.spacious)} />

ตรวจสอบให้แน่ใจว่าคุณนำเข้า classNames !!!

ดูเอกสาร UI วัสดุที่พวกเขาใช้หลายคลาสในองค์ประกอบเดียวเพื่อสร้างปุ่มที่กำหนดเอง


9

คุณยังสามารถใช้คุณสมบัติการขยาย ( ปลั๊กอิน jss-expandถูกเปิดใช้งานโดยค่าเริ่มต้น):

const styles = theme => ({
  container: {
    display: 'flex',
    flexWrap: 'wrap'
  },
  spaciousContainer: {
    extend: 'container',
    padding: 10
  },
});

// ...
<div className={ this.props.classes.spaciousContainer }>

2
น่าเสียดายที่ไม่ได้เปิดใช้งานโดยค่าเริ่มต้นอีกต่อไป ... โหวตเพื่อเปิดใช้ที่นี่
egerardus

7

ฉันคิดว่านี่จะช่วยแก้ปัญหาของคุณได้:

const styles = theme => ({
 container: {
  display: 'flex',
  flexWrap: 'wrap'
},
 spacious: {
  padding: 10
},
});

และในองค์ประกอบปฏิกิริยา:

<div className={`${classes.container} ${classes.spacious}`}>

6

ใช่ jss-composes ให้สิ่งนี้แก่คุณ:

const styles = theme => ({
 container: {
  display: 'flex',
  flexWrap: 'wrap'
},
 spacious: {
  composes: '$container',
  padding: 10
},
});

จากนั้นคุณก็ใช้ class.spacious


ในขณะที่ใช้ชื่อคลาสหลายชื่อโดยใช้การเขียนจะไม่ทำงาน codeandbox.io/s/practical-cohen-l6qt5?file=/src/text.js
user970780

2

classNames แพ็คเกจยังสามารถใช้เป็นขั้นสูงได้เช่น:

import classNames from 'classnames';

var arr = ['b', { c: true, d: false }];
classNames('a', arr); // => 'a b c'

let buttonType = 'primary';
classNames({ [`btn-${buttonType}`]: true }); // => 'btn-primary'

แสดงข้อผิดพลาด webpack build: ไม่พบโมดูล: ข้อผิดพลาด: ไม่สามารถแก้ไข 'classnames' ใน
Pranay Soni

1

คุณสามารถเพิ่มคลาสสตริงและคลาสตัวแปรหรือคลาสอุปกรณ์ประกอบฉากได้พร้อมกันด้วยวิธีนี้

className={`${classes.myClass}  ${this.props.classes.myClass2} MyStringClass`}

สามชั้นเรียนในเวลาเดียวกัน


-1

หากคุณต้องการกำหนดชื่อคลาสหลายชื่อให้กับองค์ประกอบของคุณคุณสามารถใช้อาร์เรย์ใช้อาร์เรย์

ดังนั้นในโค้ดของคุณด้านบนหาก this.props.classes แก้ไขเป็น ['container', 'spacious'] นั่นคือ if

this.props.classes = ['container', 'spacious'];

คุณสามารถกำหนดให้ div เป็น

<div className = { this.props.classes.join(' ') }></div>

และผลลัพธ์จะเป็น

<div class='container spacious'></div>

คุณแน่ใจหรือไม่ว่าชั้นเรียนที่ตั้งชื่อแยกตาม,ผลลัพธ์
Pardeep Jain

8
ไม่แน่ใจว่าทำไมจึงเป็นคำตอบที่ยอมรับ @Glauber Ramos ถูกต้อง UI วัสดุไม่ทำงานเช่นนั้น
timotgl

-1

ดังที่ได้กล่าวไปแล้วคุณสามารถใช้การแก้ไขสตริงได้

className={`${this.props.classes.container}  ${this.props.classes.spacious}`}

และคุณสามารถลองใช้classnamesห้องสมุด https://www.npmjs.com/package/classnames


คำตอบทั้งสองส่วนของคุณได้รับมาก่อนหน้านี้โดยสมาชิกคนอื่น ๆ สิ่งที่คุณทำคือทำซ้ำในคำตอบเดียว -1 (แนะนำให้คุณลบคำตอบนี้และกู้คืน
2pt
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.