Supports for define custom macros #531
Replies: 0 comments 13 replies
-
I see the point for a now you can use https://vueuse.org/core/usevmodel/#usevmodel |
Beta Was this translation helpful? Give feedback.
-
I know this function. Even with this I still need to repeatedly declare |
Beta Was this translation helpful? Give feedback.
-
yes, it's quite annoying and it's also quite serious to me :D . The absolute best option seems to me to make support for the composition api (defineProps, defineEmits...) in composuables. Root elemnet <template>
<div>
root
</div>
<c1 v-model="value" />
</template>
<script setup lang="ts">
import c1 from './c1.vue'
const value = ref<string>('example')
</script>
Chidld 1 <template>
<div>
Child 1
</div>
<c2 v-model="value" />
</template>
<script setup lang="ts">
import c2 from './c2.vue'
import { useComposuable } from './composuable'
const {
value
} = useComposuable()
</script> Child 2 <template>
<div class="">
<div>
Child 2
</div>
<input type="text" v-model="value">
</div>
</template> <script setup lang="ts">
import { useComposuable } from './composuable'
const {
value
} = useComposuable()
</script> Composuable import { defineProps, defineEmits } from "vue";
export function useComposuable() {
const props = defineProps<{
modelValue: string;
}>()
/*
* Emits
*/
const emit = defineEmits<{
(e: 'update:modelValue', value: string): void
}>()
const value = computed<string>({
get: (): string => props.modelValue,
set: (value: string): void => emit('update:modelValue', value)
})
return {
props,
emit,
value
}
} (yes, we can use provide/inject with computed value, but that may not be the ideal scenario every time.) Mabey open new feature request from this |
Beta Was this translation helpful? Give feedback.
-
This means the built-in macros need to be used outside a SFC file. That also a solution. I don't know which can be easy to implement. |
Beta Was this translation helpful? Give feedback.
-
In my opinion defining built-in macros outside the SFC file also means that built-in macros can be defined repeatedly, otherwise you won't be able to define other parameters and events. |
Beta Was this translation helpful? Give feedback.
-
That's theoretically possible. The implemention should solve this by combining the outside macros and the those inside SFC files. |
Beta Was this translation helpful? Give feedback.
-
I don't think the Vue compiler need to provide such an API. The custom macros need to modify many places of codes. A general way to process and transform macros is to wrote a bundler plugin, parse and manipulate AST yourself. For example, https://github.com/sxzz/unplugin-vue-macros. I implemented |
Beta Was this translation helpful? Give feedback.
-
It doesn't have to change Vue' s compiler. Can be a feature for vite plugin vue. And it is very disappointing that a proposal is refused base on it will change a lot of source codes. Instead of offering a better solution or try to implement it. |
Beta Was this translation helpful? Give feedback.
-
I mean if you implement a macro, you need to transform a lot of codes, not Vue's code will change a lot. Furthermore, the proposal API you mentioned above is not universal enough. Even if this API is implemented, By the way, if this is a Vite plugin proposal, maybe we should discuss it in vite repo. |
Beta Was this translation helpful? Give feedback.
-
You're misunderstanding what I'm trying to describe. It is precisely because the complexity of implementing custom macros is currently too high. We will need a more easy-to-use API to define custom macros. By the way. The Reactivity Transform is a compile time feature that implemented by vite-plugin-vue and vue-loader. |
Beta Was this translation helpful? Give feedback.
-
I'm thinking about another form of API. Here is an very prototype example: import { isStringLiteral } from '@babel/types'
import type { Node } from '@babel/types'
import type { ComponentObjectPropsOptions, EmitsOptions } from 'vue'
declare function defineMacro(
name: string,
fn: (ctx: {
componentInfo: ComponentInfo
args: Node[]
typeArgs: Node[]
getNodeString: (node: Node) => string
}) => ComponentInfo
): void
interface ComponentInfo {
props: ComponentObjectPropsOptions | string[]
emits: EmitsOptions
}
defineMacro('defineVModel', ({ componentInfo, args }) => {
if (!isStringLiteral(args[0])) throw new Error('prop name must be a string')
const propName = args[0].value
const eventName = `update:${propName}`
if (Array.isArray(componentInfo.props)) {
componentInfo.props.push(propName)
} else {
componentInfo.props[propName] = {
type: null,
required: true,
}
}
if (Array.isArray(componentInfo.emits)) {
componentInfo.emits.push(eventName)
} else {
componentInfo.emits[eventName] = () => true
}
return componentInfo
}) // usage
declare function defineVModel(propName: string): void
defineVModel('modelValue')
// equals ⬇️
defineProps(['modelValue'])
defineEmits(['update:modelValue']) |
Beta Was this translation helpful? Give feedback.
-
It's more implementable and reasonable. 👍 |
Beta Was this translation helpful? Give feedback.
-
It look so cool |
Beta Was this translation helpful? Give feedback.
-
What problem does this feature solve?
For example:
I want implement a component.
It need to provide
v-model
for parent component and may need to usev-model
to child component.Use current features would be like this:
I want to replace the above with a custom
defineModel
And this is just an example. There are lots of different custom macros developers may want to achieve.
Looking forward to an official API to support for defining custom macros.
What does the proposed API look like?
Maybe with the vite plugin vue
It's a preliminary idea.
Beta Was this translation helpful? Give feedback.
All reactions