当前位置: 首页 > 知识库问答 >
问题:

前端 - Vue 如何实现一个 `v-let` 指令?

颜嘉福
2023-11-07

情景

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-let 来简化代码?

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

<div v-for="item of items">    <template v-let="data = item.a.b.c">        {{ data.d1 }}        <MyComponent :data="data.d2"></MyComponent>    </template></div>
<MyComponent>    <template #default="{ message }" v-let="[ header, ...tail ] = message.split(' ')">        <span class="header">{{ header }}: </span>        <span v-for="item of tail">...</span>    </template></MyComponent>

我想得到的帮助

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

共有1个答案

路裕
2023-11-07
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;  }}
 类似资料:
  • https://play.vuejs.org/#eNp9UctuwyAQ/BXKqZXyUJSb5UR9KIf20FZt1... 问题来源:https://stackoverflow.com/questions/41944054/reference-element-property-within-another-property 想要解决这个问题,又不想用v-for封装大改

  • vue实现动态按钮借助iview的Button,由于这些按钮是配置出来的,目前没有代码,还不清楚怎么写,所以麻烦大佬们了 如图 期望能在各个vue组件使用的,然后通过不同的点击来触发事件,希望大佬们,给个思路

  • 本文向大家介绍Vue循环中多个input绑定指定v-model实例,包括了Vue循环中多个input绑定指定v-model实例的使用技巧和注意事项,需要的朋友参考一下 Vue.js中提供了v-model可以双向绑定表单元素,这个方法可以非常方便的获得输入的值,但是有时候表单元素需要循环生成,在循环中要怎样获得指定输入框的值呢 这里介绍两种: 一种是v-for中循环生成的输入框, 一种是在eleme

  • 本文向大家介绍利用Vue v-model实现一个自定义的表单组件,包括了利用Vue v-model实现一个自定义的表单组件的使用技巧和注意事项,需要的朋友参考一下 功能描述: 通过点击按钮,可以增减购物数量 组件名称是 CouterBtn 最终效果如下 我们使用 vue-cli搭建基本的开发环境,这也是最快的进行 .vue组件开发的方式 对于入口组件  App.vue (可以暂时忽略其他细节,我们

  • 本文向大家介绍VUE+node(express)实现前后端分离,包括了VUE+node(express)实现前后端分离的使用技巧和注意事项,需要的朋友参考一下 vue作为前端的框架,node(express)作为后端的框架。无数据库,使用端口保存数据。 VUE: 使用vue-cli构建vue项目(vueapp)。 axios:(与ajax相似) axios没安装的记得装一下。(安装不细说) nod

  • 本文向大家介绍如何区分vue中的v-show 与 v-if,包括了如何区分vue中的v-show 与 v-if的使用技巧和注意事项,需要的朋友参考一下 1. v-show 不管初始的条件是什么,元素总是会被渲染,并且只是简单的基于 CSS display: none 或者 display: block 的属性进行切换。 2. v-if 会根据初始的条件(data里自己的定义的数据)来进行真正的渲染