我想创建一个由三部分组成的表组件: Package 、头和数据。
虽然它的大部分工作得很好,我挣扎的顺序功能。
当用户点击一个th标签时,数据应该被重新排序,并且应该显示一个小的指示器。排序起作用,但是指示器不起作用。
真正的问题
我知道在父对象中定义了一个属性,但在子对象中改变它是不好的,因为我使用了slot,所以不能使用普通的$emit。
使用这里显示的方法,我得到了Uncaught (in promise) TypeError: parent is null
和Unhandled error during execution of scheduler flush
。
虽然我已经知道我目前的方法是错误的,但我不知道如何做正确的。
在谷歌上搜索,我发现了一些关键词,比如可写的计算道具和作用域插槽,但我不能把它们放在一起。
那么,在一个插槽环境中实现双向绑定的正确方法是什么呢?
我的表.vue文件
<template>
<div class="px-4 sm:px-6 lg:px-8">
<div class="mt-8 flex flex-col">
<div class="-my-2 -mx-4 overflow-x-auto sm:-mx-6 lg:-mx-8">
<Search v-if="searchable" :filters="props.filters"></Search>
<div class="inline-block min-w-full py-2 align-middle">
<div class="overflow-hidden shadow ring-1 ring-black ring-opacity-5 md:rounded-lg">
<table class="min-w-full divide-y divide-gray-300">
<thead class="bg-gray-50">
<tr>
<slot name="table-heads"></slot>
</tr>
</thead>
<tbody class="divide-y divide-gray-200 bg-white">
<slot name="table-body"></slot>
</tbody>
</table>
<Pagination v-if="paginationLinks" :links="paginationLinks"></Pagination>
</div>
</div>
</div>
</div>
</div>
</template>
<script setup>
import Pagination from "@/Components/Tables/Pagination.vue";
import {provide} from "vue";
import Search from "@/Components/Tables/Search.vue";
import {Inertia} from "@inertiajs/inertia";
let name = "Table";
let props = defineProps({
paginationLinks: Array,
dataUrl: String,
filters: Object,
order: Object,
searchable: Boolean
});
provide('dataUrl', props.dataUrl);
provide('order', props.order);
</script>
<style scoped>
</style>
我的TableHead.vue文件
<template>
<th @click="orderByClicked" scope="col"
class="py-3.5 pl-4 pr-3 text-left text-sm font-semibold text-gray-900 sm:pl-6 cursor-pointer">
<div class="flex justify-between">
<slot></slot>
<span v-if="order.orderBy === props.orderKey">
<i v-if="order.orderDirection === 'asc'" class="fa-solid fa-chevron-up"></i>
<i v-if="order.orderDirection === 'desc'" class="fa-solid fa-chevron-down"></i>
</span>
</div>
</th>
</template>
<script setup>
import { inject } from "vue";
import { Inertia } from "@inertiajs/inertia";
let name = "TableHead";
let dataUrl = inject('dataUrl');
let order = inject('order');
let props = defineProps({
orderKey: String,
orderByClicked: Function
});
function orderByClicked() {
if (props.orderKey) {
if (order.orderBy === props.orderKey)
order.orderDirection = order.orderDirection === 'asc' ? 'desc' : 'asc';
else
order.orderDirection = "asc"
order.orderBy = props.orderKey;
Inertia.get(dataUrl, {orderBy: props.orderKey, orderDirection: order.orderDirection}, {
preserveState: true,
replace: true
});
}
}
</script>
<style scoped>
</style>
我的TableData.vue文件(即将完成)
<template>
<td class="whitespace-nowrap py-4 pl-4 pr-3 text-sm font-medium text-gray-900 sm:pl-6">
<slot></slot>
</td>
</template>
<script setup>
let name = "TableData";
</script>
<style scoped>
</style>
"把它放在一起"
<Table :pagination-links="props.users.links" :data-url="'/users'" :searchable="true" :filters="props.filters" :order="props.order">
<template #table-heads>
<TableHead order-key="name">name</TableHead>
<TableHead order-key="email">email</TableHead>
<TableHead>Bearbeiten</TableHead>
</template>
<template #table-body>
<tr v-for="user in users.data" :key="user.id">
<TableData>{{ user.username }}</TableData>
<TableData>{{ user.email}}</TableData>
</tr>
</template>
</Table>
2条答案
按热度按时间oyt4ldly1#
这可能是一个React性问题。您的指标依赖于
order
属性,您在设置时设置了该属性,并且似乎更改正确,但我没有看到任何东西使它对您的模板React。在您提供它的Table.vue中,您可能只需要从Vue导入
ref
以使其具有React性:eqqqjvef2#
我意识到错误只发生在与FontAwesome结合的情况下,所以我看得更远。
通过检查代码,我发现FontAwesome操纵DOM。
事后应该很清楚,但无论如何...
"原因"
关键是,当您插入
<i class="fa-solid fa-sort-up"></i>
这样的标签时,它会转换为<svg class="svg-inline--fa fa-sort-up" aria-hidden="true" focusable="false" data-prefix="fas" data-icon="sort-up" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512" data-fa-i2svg=""><path fill="currentColor" d="M182.6 41.4c-12.5-12.5-32.8-12.5-45.3 0l-128 128c-9.2 9.2-11.9 22.9-6.9 34.9s16.6 19.8 29.6 19.8H288c12.9 0 24.6-7.8 29.6-19.8s2.2-25.7-6.9-34.9l-128-128z"></path></svg>
只要你不把自己的属性附加到
i
标签上就行了,因为它们会被破坏!我的
v-if
也发生了这种情况。不幸的是,它并没有悄无声息地消失,而是导致了一些奇怪的错误。解决方案
将任何由第三方(在本例中为FontAwesome)操作的标签 Package 在一个合适的父标签中。
我想出了以下解决办法:
琐事
有趣的是,由于某些原因,这个错误并没有在https://sfc.vuejs.org中出现。我无法在任何在线工具中重现它。组件只在我的本地开发环境中崩溃。