#web #前端框架 # #proc-macro #前端 #class-list

class_list_macro

一个反应式辅助工具,确保在前端框架如Leptos中类列表字符串规范化

7个版本

0.1.7 2023年8月23日
0.1.6 2023年8月23日

#前端框架中排名第26

每月下载量46
class_list中使用

MIT许可协议

14KB
279

class_list

GitHub Badge crates.io Badge docs.rs Badge Build Status Badge

一个反应式辅助工具,确保在前端框架如Leptos中的类列表字符串规范化。

使用方法

提供的示例将为Leptos框架在{上下文移除}之后使用,但它在{上下文移除}之前也能工作,可能在其他类似框架中也能工作。

这个库旨在保持通用性,没有运行时依赖项,但只与Leptos进行了测试。

cargo add class_list

示例

class_list![]默认将其自身包裹在一个移动闭包中,这意味着它默认是反应式的。

let (count, set_count) = create_signal(0);

set_interval(
	move || {
		set_count.update(|count| *count += 1);
	},
	Duration::from_millis(100),
);

let count_class = move || format!("count-{}", count());
let count_is_even = move || count() % 2 == 0;

view! {
	<div class=class_list![
		"default-class-names",
		// Closures get called automatically.
		count_class,
		// Closures can be written directly into the macro.
		move || format!("count-{}", count()),
		// Both Option and Result can be used as values.
		// None and Err result in no class name.
		Some("option"),
		None::<String>,
		// More conveniently, class names can be bound to reactive toggles.
		// "even" will only be applied when `count_is_even()` is true.
		// You also don't need to call closures here.
		"even" <=> count_is_even
	] />
}

选项

每个选项之后必须跟一个;

原始

要生成一个非反应式的String,请在开头添加raw选项。

class_list![
	raw;
	"default-class-names",
]

克隆

很少,你可能需要在传递之前克隆一些东西。

宏通过clone选项使其变得容易,这个选项在将变量移动到闭包之前克隆它。

尽可能避免最初就需要这个选项。

class_list![
	clone[count_class];
	"default-class-names",
]

这通常是不需要的,因为它是通过包装器macro_rules!自动提供的。

在无法解决特性导入的情况(例如,在另一个库内部使用时),可以重新定义路径。

路径应指向此库的根目录。

__class_list![
	crate = ::your_lib::class_list;
	"default-class-names",
]

实现特性

如果你想直接传递类型给宏而不是每次都转换,可以实现ClassListClassToggle类型。

查看traits.rs以了解默认实现,它们是实现它们的良好示例。

// If you're using a type you don't own,
// you must wrap it in a new struct.
struct Bool(bool);

impl ClassList for Bool {
	fn to_class_list(&self, normalize: bool) -> String {
		// If the string could contain multiple class names
		// you should use `normalize` to determine whether
		// or not to call `.to_class_list()` on it before
		// returning.
		// If you're lazy you could always normalize, but
		// then the string will be normalized multiple
		// times for every update in the macro.
		if self.0 {
			"true".into()
		} else {
			"false".into()
		}
	}
}
impl ClassToggle for Bool {
	fn to_class_toggle(&self) -> bool {
		self.0
	}
}

// Option, Result, and Fn are implemented in a way which
// allows any new type you implement to be automatically
// passed through.
assert_eq!(
	class_list![
		// ClassList
		move || Bool(false),
		Bool(true),
		"class",
		// ClassToggle
		"hidden" <=> move || Bool(false),
		"list",
	](),
	"false true class list".to_string()
);

依赖项

~265–710KB
~17K SLoC