You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Directus 11.7.2自定义布局扩展搜索功能报错求助

Directus 11.7.2自定义布局扩展搜索功能报错修复

问题场景

使用Directus 11.7.2开发自定义布局扩展,按照官方文档实现后,表格数据能正常加载,但在页面头部搜索输入框输入内容时,控制台抛出错误:

TypeError: Cannot set properties of undefined (setting 'value')

相关代码如下:

index.js

import { toRefs } from 'vue';
import { useItems, useCollection } from '@directus/extensions-sdk';
import LayoutComponent from './layout.vue';

export default {
    id: 'my-custom-layout',
    name: 'Custom Layout',
    icon: 'box',
    component: LayoutComponent,
    slots: {
        options: () => null,
        sidebar: () => null,
        actions: () => null,
    },
    setup(props) {
        const { collection, filter, search } = toRefs(props);
        const { info, primaryKeyField, fields: fieldsInCollection } = useCollection(collection);

        const { items, loading, error } = useItems(collection, {
            sort: primaryKeyField.field,
            limit: '-1',
            fields: '*',
            filter,
            search,
        });

        return {
            info,
            primaryKeyField,
            items,
            loading,
            filter,
            search,
            fieldsInCollection,
            error,
        };
    },
};

layout.vue

<template>
  <div v-if="!loading">
    <p>Collection: {{ collection }}</p>

    <table>
      <thead>
      <tr>
        <th>Name</th>
        <th>Email</th>
        <th>&nbsp;</th>
      </tr>
      </thead>
      <tbody>
      <tr v-for="item in items" :key="item.id">
        <td>{{ item.name }}</td>
        <td>{{ item.email }}</td>
        <td><a :href="`/admin/content/${collection}/${item.id}`">View Details</a></td>
      </tr>
      </tbody>
    </table>
  </div>
</template>

<script>
export default {
  inheritAttrs: false,
  props: {
    collection: {
      type: String,
      required: true,
    },
    items: Array,
    loading: Boolean,
    error: Array,
    search: {
      type: String,
      default: null,
    },
  }
};
</script>

问题原因

Directus的布局框架中,search是一个响应式Ref对象,而非普通字符串。当用户在搜索框输入时,框架会尝试修改search.value来同步状态,但当前代码中layout.vue把search定义为String类型,导致Ref对象被自动解包成字符串,框架找不到value属性从而抛出错误。

修复方案

修改layout.vue中的search属性定义,改为接收Ref对象:

修改后的layout.vue

<template>
  <div v-if="!loading">
    <p>Collection: {{ collection }}</p>

    <table>
      <thead>
      <tr>
        <th>Name</th>
        <th>Email</th>
        <th>&nbsp;</th>
      </tr>
      </thead>
      <tbody>
      <tr v-for="item in items" :key="item.id">
        <td>{{ item.name }}</td>
        <td>{{ item.email }}</td>
        <td><a :href="`/admin/content/${collection}/${item.id}`">View Details</a></td>
      </tr>
      </tbody>
    </table>
  </div>
</template>

<script>
export default {
  inheritAttrs: false,
  props: {
    collection: {
      type: String,
      required: true,
    },
    items: Array,
    loading: Boolean,
    error: Array,
    search: {
      type: Object, // 修改为Object类型,接收Ref对象
      default: () => ({ value: null }),
    },
  }
};
</script>

如果需要在模板中显示当前搜索关键词,可添加:

<p v-if="search.value">当前搜索: {{ search.value }}</p>

说明

index.js中的代码无需修改,toRefs(props)已经正确获取到了search这个Ref对象,只需确保组件正确接收并保留其Ref结构即可。

内容的提问来源于stack exchange,提问作者June

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.12 22:33:11