vue-create-logic
v0.0.4
Published
Wrap composable functions into scoped, injectable, and Pinia-enabled logic units
Maintainers
Readme
vue-create-logic
Wrap composable functions into scoped, injectable, and Pinia-enabled logic units.
Features
- Scoped State Sharing: Via provide/inject for local multi-instance state
- No
.value: proxyRefs handles ref access automatically - Pinia Integration: Optional Pinia store for persistence
- TypeScript: Full type support
Installation
npm install vue-create-logicRequires vue@^3.2 and pinia@^2.0.
Complete Examples
1. Singleton Mode (without name)
Share one state across component tree, no global store.
import { defineComponent, reactive, ref } from "vue";
import { createLogic } from "vue-create-logic";
function useUserLogic() {
const name = ref("Zhang San");
const age = ref(25);
const info = reactive({ city: "Beijing" });
return { name, age, info };
}
const UserLogic = createLogic(useUserLogic);
const Parent = defineComponent(() => {
const userLogic = UserLogic.useProvide();
return () => <Child />;
});
const Child = defineComponent(() => {
const userLogic = UserLogic.useInject();
return () => (
<div>
<input v-model={userLogic.name} />
<input v-model={userLogic.age} />
<input v-model={userLogic.info.city} />
<div>Name: {userLogic.name}</div>
<div>Age: {userLogic.age}</div>
<div>City: {userLogic.info.city}</div>
</div>
);
});
export default Parent;2. Local Multi-Instance Mode (without name, with parameters)
Each parent component instance has its own state, children share that parent's state.
import { defineComponent, reactive, ref } from "vue";
import { createLogic } from "vue-create-logic";
function useItemLogic(id: number) {
const title = ref(`Item ${id}`);
const count = ref(0);
return { id, title, count };
}
const ItemLogic = createLogic(useItemLogic);
const ItemList = defineComponent(({ items }: { items: number[] }) => {
return () => (
<div>
{items.map((id) => (
<Item key={id} id={id} />
))}
</div>
);
});
const ItemContent = defineComponent(() => {
const itemLogic = ItemLogic.useInject();
return () => (
<div>
<input v-model={itemLogic.title} />
<button onClick={() => itemLogic.count++}>Count: {itemLogic.count}</button>
</div>
);
});
const Item = defineComponent(({ id }: { id: number }) => {
const itemLogic = ItemLogic.useProvide({ id }); // initializes and returns instance
return () => <ItemContent />;
});
<ItemList items={[1, 2, 3]} />;3. Global Store Mode (with name)
When name is provided, an additional Pinia store is created for persistence and global access.
import { defineComponent, reactive, ref } from "vue";
import { createLogic } from "vue-create-logic";
function useSettingsLogic() {
const theme = ref("light");
const config = reactive({ lang: "en-US", fontSize: 14 });
return { theme, config };
}
const SettingsLogic = createLogic(useSettingsLogic, "settings");
const App = defineComponent(() => {
const settingsStore = SettingsLogic.useStore();
return () => <SettingsPanel />;
});
const SettingsPanel = defineComponent(() => {
const settingsStore = SettingsLogic.useStore();
return () => (
<div>
<select v-model={settingsStore.theme}>
<option value="light">Light</option>
<option value="dark">Dark</option>
</select>
<input v-model={settingsStore.config.lang} />
<input v-model={settingsStore.config.fontSize} type="number" />
</div>
);
});API
createLogic(useHook)
Create a logic unit without Pinia store.
use(...args)- Call composable, return reactive stateuseProvide(...args)- Provide state to descendants, returns the instanceuseInject()- Get ancestor-provided data
createLogic(useHook, name)
Create a logic unit with Pinia store.
| Method | Description |
| --------------------- | ---------------------------------------------------- |
| use(...args) | Call composable, return reactive state |
| useProvide(...args) | Provide state to descendants, returns the instance |
| useInject() | Get ancestor-provided data |
| useStore() | Get Pinia store instance |
License
MIT
