Vue 3 如何实现一个 `v-const` 指令?

情景

Vue 模板中我们经常会用到一些中间量,比如

<div v-for="item of items">

{{ item.a.b.c.d1 }}

<MyComponent :data="item.a.b.c.d2"></MyComponent>

</div>

中的 item.a.b.c

<MyComponent>

<template #default="{ message }">

<span class="header">{{ message.split(' ')[0] }}: </span>

<span v-for="item of message.split(' ').slice(1)">...</span>

</template>

</MyComponent>

中的 message.split(' ')

问题

由于 v-for<slot> 等的包裹,我们难以利用 computed 简单地提出这些中间量(当然我知道都有普通的解决方案)

我想到 Vue 既然有 v-if / v-for 等和 JavsScript 关键字风格类似的内建指令,能不能实现一个 v-const 来简化代码?

设想中这个指令是这样用的:

<div v-for="item of items">

<template v-const="data = item.a.b.c">

{{ data.d1 }}

<MyComponent :data="data.d2"></MyComponent>

</template>

</div>

<MyComponent>

<template #default="{ message }" v-const="[ header, ...tail ] = message.split(' ')">

<span class="header">{{ header }}: </span>

<span v-for="item of tail">...</span>

</template>

</MyComponent>

我想得到的帮助

  • 较简单的实现方案 / 思路
  • Vue 和其它框架如 Svelte 不提供类似指令出于什么原因?性能 / 歧义 / 历史原因?
  • 指令实现后,与 Volar 兼容的可能性 / 相关资料(指的是可以获得补全,而不仅仅是不报错)


回答:

Vue.directive('let', {

bind(el, binding, vnode) {

const ComponentConstructor = Vue.extend({

render(createElement) {

// render函数可以访问this.$slots.default

return createElement('div', this.$slots.default);

},

});

const componentInstance = new ComponentConstructor({

// 使用data函数来定义响应式数据

data() {

return typeof binding.value === 'function'

? binding.value()

: { value: binding.value };

},

});

// 挂载到一个临时元素上

const mountNode = document.createElement('div');

componentInstance.$mount(mountNode);

// 替换绑定元素的内容

el.innerHTML = '';

el.appendChild(componentInstance.$el);

},

});

自定义指令的类型声明:

declare module 'vue' {

interface ComponentCustomProperties {

'v-let': any;

}

}

以上是 Vue 3 如何实现一个 `v-const` 指令? 的全部内容, 来源链接: utcz.com/p/935114.html

回到顶部