Vue JS (Vuetify) 用 slot props 实现双向数据绑定和响应式

Posted

技术标签:

【中文标题】Vue JS (Vuetify) 用 slot props 实现双向数据绑定和响应式【英文标题】:Vue JS (Vuetify) Achieve two-way data binding and reactivity with slot props 【发布时间】:2018-04-18 17:16:28 【问题描述】:

我需要从Vuetify data table 中删除一个项目(行)。我正在使用来自vuexmapState 将数据表的items 属性绑定到一个名为screens 的计算变量。

<v-data-table
    ref="dataTable"
    v-bind:headers="headers"
    v-bind:items="screens"
    v-bind:search="search"
    :loading="loading"
>
    <template slot="items" slot-scope="props">
        <tr @click="props.expanded = !props.expanded">
            <td> props.item.name </td>
            <!-- etc -->
        </tr>
    </template>
    <template slot="expand" slot-scope="props">
        <screen-edit-form :screen-data="props.item"></screen-edit-form>
    </template>
    <template slot="pageText" slot-scope=" pageStart, pageStop ">
        From  pageStart  to  pageStop 
    </template>
</v-data-table>
...

来自计算变量的片段

/**
 * Automated the fetching of screen data.
 */
 computed: mapState( 

    screens: state => state.Screens.data

  ),

vuex 中的突变

/**
 * Create an unset function using Lodash
 * @param state
 * @param payload
 */
unsetById: ( state, payload ) => 

    // Remove the item
    _.remove( state.data,  id: payload.id  );

    // Emit an event to the event bus
    EventBus.$emit( 'screen-deleted' );


数据表使用名为items 的模板槽和名为props 的槽范围。但是,每当我改变 screens 时,我可以看到 items 数组被正确更改(我从屏幕数组中删除的项目确实已经消失)但我对 DOM 没有反应。

我从docs 了解到,如果我想要双向绑定,我需要同步道具。我尝试在v-bind:items 上使用.sync 修饰符并使用this.$refs.dataTable.$emit( 'update:items', this.screens ); 发出更改,但无济于事。

任何有关使用插槽道具获得双向绑定的帮助将不胜感激。最终目标是能够从数据表中删除项目并将其立即反映在 DOM 上。

谢谢。

【问题讨论】:

【参考方案1】:

感谢 Vuetify 聊天的 @jacek。原来突变也跟随Vue's Reactivity Rules。我只需要import Vue from 'vue'(如果尚未导入)并在我的 unset 函数中使用 Vue 的删除方法。

/**
 * Create an unset function using Lodash
 * @param state
 * @param payload
 */
unsetById: ( state, payload ) => 

    // Remove the item
    Vue.delete( state.data, _.findIndex( state.data, id: payload.id  ) );

    // Emit an event to the event bus
    EventBus.$emit( 'screen-deleted' );


【讨论】:

【参考方案2】:

如果你想让它立即反映在 DOM 上,你可以尝试拼接或过滤数据所在的数组。

如果我想批量删除和拼接单个删除,我个人会使用过滤。 如果你想拼接,首先你必须用indexOf在一个数组中获取你的对象的索引,所以...

const index = this.items.indexOf(object)
this.items.splice(index, 1)

【讨论】:

以上是关于Vue JS (Vuetify) 用 slot props 实现双向数据绑定和响应式的主要内容,如果未能解决你的问题,请参考以下文章

如何访问深层嵌套父级中的方法 [Vue][Vuetify]

Vuetify 主题设置在 Storybook 中不起作用

单元测试包含带有插槽的 Vuetify 数据表的 Vue 组件

vue 中slot 的具体用法

Vue 3 - Vuetify 3:颜色——文本不起作用

使用 vuetify / Vue.js 控制 svg 的颜色