Run the following to create a workspace for your Vue components:
The generated workspace includes workspace-level configuration and some other configuration files for your IDE.
The only unique part of this generated workspace is:
"teambit.generator/generator": { "envs": ["org.scope-name/envs/my-vue-env"] }
inworkspace.json
for creating new components without specifying the env aspect manually.If your workspace was generated in other ways, you can still manually add it on.
To learn how to initialize a Bit workspace on an existing project, see Add Bit to an existing project.
Run the following to create a component using your env's vue-composable
template:
Component compilation
Run Bit's development server (bit start
) or watch mode (bit watch
) to compile modified components.
The main implementation file is use-counter.ts
, which is a Vue composable. You can modify it to your needs.
/* @filename: use-counter.ts -*/ // the by-default generated code is actually an existing Vue composable // from VueUse (https://vueuse.org/useCounter) import { ref } from "vue"; export interface UseCounterOptions { min?: number; max?: number; } /** * Basic counter with utility functions. * * @see https://vueuse.org/useCounter * @param [initialValue=0] * @param {Object} options */ export function useCounter(initialValue = 0, options: UseCounterOptions = {}) { const count = ref(initialValue); const { max = Infinity, min = -Infinity } = options; const inc = (delta = 1) => (count.value = Math.min(max, count.value + delta)); const dec = (delta = 1) => (count.value = Math.max(min, count.value - delta)); const get = () => count.value; const set = (val: number) => (count.value = Math.max(min, Math.min(max, val))); const reset = (val = initialValue) => { initialValue = val; return set(val); }; return { count, inc, dec, get, set, reset }; }
Verify that your component behaves as expected by rendering it in various relevant contexts and variations. For example, you can see another file named use-counter-basic.fixtures.vue
as a basic composition which utilize useCounter
in multiple buttons and the output of count.
<!-- @filename: use-counter-basic.fixtures.vue --> <script setup lang="ts"> import { useCounter } from "./use-counter"; const { count, inc, dec, set, reset } = useCounter(); </script> <template> <div> <p>Count: {{ count }}</p> <button @click="inc()">Increment</button> <button @click="dec()">Decrement</button> <button @click="inc(5)">Increment (+5)</button> <button @click="dec(5)">Decrement (-5)</button> <button @click="set(100)">Set (100)</button> <button @click="reset()">Reset</button> </div> </template>
And this file is gathered and exported by use-counter.composition.ts
.
// @filename: use-counter.composition.ts import BasicMyCounter from "./use-counter-basic.fixtures.vue"; export { BasicMyCounter };
You can add other compositions by aurhoring additional components in *.fixtures.vue
and exporting them from use-counter.composition.ts
or other *.composition.*
files.
Head to the component's 'Compositions' tab, to see your rendered compositions (run bit start
if you don't have the workspace UI running, already).
Head over to your component's .spec.ts
file to add automated testing.
We recommend using your compositions as the base for your testings, with Vue Testing Library as the test utils.
For example:
// @filename: use-counter.spec.ts import { render } from "@testing-library/vue"; import { BasicUseCounter } from "./use-counter.composition"; describe("BasicUseCounter", () => { it("should render", async () => { const { getByText, findByText } = render(BasicUseCounter); expect(getByText("Count: 0")).toBeTruthy(); getByText("Increment (+5)").click(); expect(await findByText("Count: 5")).toBeTruthy(); }); }); // ... more tests
Also see Testing docs for more information.
You can modify use-counter.docs.md
to document your component's API and usage. To learn Markdown syntax, see Markdown Guide.
For example:
--- labels: ['vue'] description: A useCounter composable. --- Basic counter with utility functions. ## Basic Usage ```ts import { useCounter } from "${componentId}"; const { count, inc, dec, set, reset } = useCounter(); ``` ## Usage with options ```ts import { useCounter } from "${componentId}"; const { count, inc, dec, set, reset } = useCounter(1, { min: 0, max: 16 }); ```
Import the Vue composable into a Vue component using its package name (whatever it is maintained in the same workspace or installed from a remote scope):
<!-- @filename: my-counter.vue --> <script setup lang="ts"> import { useCounter } from "@my-org/my-scope.composables.use-counter"; defineProps({ title: { type: String, default: "", }, }); const { count, inc } = useCounter(); </script> <template> <button @click="inc()"> {{ title }}: {{ count }} </button> </template> <style scoped> button { color: blue; } </style>
There is an open source project called VueUse which is a comprehensive collection of Vue composables you can refer to before building your own composables.
To use it in your component, run the following command:
Then, import the composable from @vueuse/core
:
import { useLocalStorage, useMouse, usePreferredDark } from '@vueuse/core' export default { setup() { // tracks mouse position const { x, y } = useMouse() // if user prefers dark theme const isDark = usePreferredDark() // persist state in localStorage const store = useLocalStorage( 'my-storage', { name: 'Apple', color: 'red', }, ) return { x, y, isDark, store } }, }