diff --git a/README.md b/README.md index efa2241..0661cd7 100644 --- a/README.md +++ b/README.md @@ -27,6 +27,14 @@ {{ count }} + + + ``` - Use `v-scope` to mark regions on the page that should be controlled by `petite-vue`. @@ -306,6 +314,35 @@ createApp({ }).mount() ``` +### Use Plugins + +You can write custome directive then distrbute it as a pacage, then add it to create vue, like: + +```html +
+ +
+ + +``` + +A plugin code similar to vue plugins code: + +```js +// inside log.js plugin file +export default { + install: (app, options) => { + app.directive('log', ({exp}) => { + console.log(exp) + }) + } +} +``` + ## Examples Check out the [examples directory](https://github.com/vuejs/petite-vue/tree/main/examples). @@ -317,10 +354,11 @@ Check out the [examples directory](https://github.com/vuejs/petite-vue/tree/main - `v-scope` - `v-effect` - `@vue:mounted` & `@vue:unmounted` events +- `$root` refer to component root element ### Has Different Behavior -- In expressions, `$el` points to the current element the directive is bound to (instead of component root element) +- In expressions, `$el` points to the current element the directive is bound to (instead of component root element which accessed by `$root`) - `createApp()` accepts global state instead of a component - Components are simplified into object-returning functions - Custom directives have a different interface diff --git a/src/app.ts b/src/app.ts index 4a17bbc..e0e2107 100644 --- a/src/app.ts +++ b/src/app.ts @@ -42,6 +42,11 @@ export const createApp = (initialData?: any) => { } }, + use(plugin: any, options = {}) { + plugin.install(this, options) + return this + }, + mount(el?: string | Element | null) { if (typeof el === 'string') { el = document.querySelector(el) diff --git a/src/walk.ts b/src/walk.ts index f996461..426406e 100644 --- a/src/walk.ts +++ b/src/walk.ts @@ -15,6 +15,7 @@ const modifierRE = /\.([\w-]+)/g export let inOnce = false export const walk = (node: Node, ctx: Context): ChildNode | null | void => { + const parentCtx = ctx const type = node.nodeType if (type === 1) { // Element @@ -40,6 +41,7 @@ export const walk = (node: Node, ctx: Context): ChildNode | null | void => { // v-scope if ((exp = checkAttr(el, 'v-scope')) || exp === '') { const scope = exp ? evaluate(ctx.scope, exp) : {} + scope.$root = el ctx = createScopedContext(ctx, scope) if (scope.$template) { resolveTemplate(el, scope.$template) @@ -54,6 +56,9 @@ export const walk = (node: Node, ctx: Context): ChildNode | null | void => { // ref if ((exp = checkAttr(el, 'ref'))) { + if (ctx !== parentCtx) { + applyDirective(el, ref, `"${exp}"`, parentCtx) + } applyDirective(el, ref, `"${exp}"`, ctx) } diff --git a/tests/ref.html b/tests/ref.html index ccb71fa..4885faa 100644 --- a/tests/ref.html +++ b/tests/ref.html @@ -7,9 +7,10 @@ id="root" ref="root" v-scope="{ dynamicRef: 'x', show: true }" - v-effect="console.log({ x: $refs.x, y: $refs.y, input: $refs.input })" + v-effect="console.log({ x: $refs.x, y: $refs.y, input: $refs.input, modal: $refs.modal })" > -

Accessing root el: id is {{ $refs.root.id }}

+

Accessing root el (with ref): id is {{ $refs.root.id }}

+

Accessing root el (with $root): id is {{ $refs.root.id }}

Span with dynamic ref @@ -19,10 +20,10 @@ -
+