【问题标题】:Make selected item current使所选项目成为当前项目
【发布时间】:2021-09-29 22:02:34
【问题描述】:

编辑:在这里可以找到 3 个最有可能的文件的完整代码。 https://codepen.io/arcticmedia-ryan/project/editor/ZEQwmN

我不确定如何最好地解释这一点,所以如果您需要更多信息,请告诉我。我正在构建一个聊天室应用程序。当一个人打开主 vue 时,他们会看到一个“房间列表”——从那里他们可以点击进入并加入房间。问题是,当他们单击加入时,它会打开房间的选项卡,但不会使其处于活动状态。我觉得我只是在解决一个简单的问题

有一个名为“SelectedRoomID”的道具需要从“未定义”更新为从列表中选择的房间。

RoomList.vue

<!-- This example requires Tailwind CSS v2.0+ -->
<template>
    <TransitionRoot as="template" :show="isOpen">
        <Dialog as="div" class="fixed z-10 inset-0 overflow-y-auto" @close="$emit('onClose')">
            <div class="flex items-end justify-center min-h-screen pt-4 px-4 pb-20 text-center sm:block sm:p-0">
                <TransitionChild as="template" enter="ease-out duration-300" enter-from="opacity-0"
                                 enter-to="opacity-100" leave="ease-in duration-300" leave-from="opacity-100"
                                 leave-to="opacity-0">
                    <DialogOverlay class="fixed inset-0 bg-gray-700 bg-opacity-75 transition-opacity"/>
                </TransitionChild>

                <!-- This element is to trick the browser into centering the modal contents. -->
                <span class="hidden sm:inline-block sm:align-middle sm:h-screen" aria-hidden="true">&#8203;</span>
                <TransitionChild as="template" enter="ease-out duration-300"
                                 enter-from="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
                                 enter-to="opacity-100 translate-y-0 sm:scale-100" leave="ease-in duration-300"
                                 leave-from="opacity-100 translate-y-0 sm:scale-100"
                                 leave-to="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95">
                    <div class="inline-block align-bottom bg-black bg-opacity-20 rounded-lg px-6 pt-5 pb-4 text-left overflow-hidden shadow-2xl transform transition-all sm:my-8 sm:align-middle sm:p-6">

                        <div class="sm:flex sm:items-start">
                            <div class="flex flex-col">
                                <div class="-my-2 overflow-x-auto sm:-mx-6 lg:-mx-8">
                                    <div class="align-middle inline-block min-w-full sm:px-4 lg:px-5">
                                        <div class="shadow overflow-hidden border-8 border-gray-800 dark:border-gray-900 sm:rounded-lg">
                                            <table class="min-w-full divide-y divide-gray-800">
                                                <thead class="bg-gray-800 dark:bg-gray-900">
                                                <tr>
                                                    <th scope="col"
                                                        class="px-6 py-3 text-left text-s font-medium text-gray-50 uppercase tracking-wider">
                                                        Room
                                                    </th>
                                                    <th scope="col"
                                                        class="px-6 py-3 text-left text-s font-medium text-gray-50 uppercase tracking-wider">
                                                        Description
                                                    </th>
                                                    <th scope="col"
                                                        class="px-6 py-3 text-left text-s font-medium text-gray-50 uppercase tracking-wider">
                                                        Type
                                                    </th>
                                                    <th scope="col"
                                                        class="px-6 py-3 text-left text-s font-medium text-gray-50 uppercase tracking-wider">
                                                        Users
                                                    </th>
                                                    <th scope="col" class="relative px-6 py-3">
                                                        <button type="button"
                                                                class="bg-white rounded-md text-gray-400 hover:text-gray-500 "
                                                                @click="$emit('onClose')">
                                                            <div class="hidden sm:block absolute top-0 right-0 pt-4 pr-4">
                                                                <span class="sr-only">Close</span>
                                                                <XIcon class="top-1 right-1 absolute h-6 w-6 text-gray-50 " aria-hidden="true"/>
                                                            </div>
                                                        </button>
                                                        
                                                        <span class="sr-only">Enter</span>
                                                        
                                                    </th>
                                                </tr>
                                                </thead>
                                                <tbody class="bg-white dark:bg-gray-800 divide-y divide-gray-300 dark:divide-gray-600">
                                                <tr v-for="room in $store.state.rooms.rooms" :key="room.id">
                                                    <td class="px-6 py-4 whitespace-nowrap">
                                                        <div class="flex items-center">
                                                            <div class="flex-shrink-0 h-10 w-10">
                                                                <img class="h-10 w-10 rounded-full" :src="room.image"
                                                                     alt=""/>
                                                            </div>
                                                            <div class="ml-4">
                                                                <div class="text-md font-medium text-gray-900 dark:text-gray-50">
                                                                    {{ room.name }}
                                                                </div>
                                                            </div>
                                                        </div>
                                                    </td>
                                                    <td class="px-6 py-4 whitespace-nowrap">
                                                        <div class="text-md text-gray-900 dark:text-gray-50">{{ room.description }}</div>
                                                    </td>
                                                    <td class="px-2 py-4 whitespace-nowrap">
                                                        <span class="px-2 inline-flex text-s leading-5 font-medium rounded-full">
                                                            <div v-if="room.is_private === true" class="rounded-full py-1 px-2 bg-red-100 text-red-800 dark:bg-red-800 dark:text-red-100">
                                                                        <span>Private</span>
                                                                    </div>
                                                                    <div v-else-if="room.is_private === false" class="rounded-full py-1 px-2 bg-green-100 text-green-800 dark:bg-green-800 dark:text-green-100">
                                                                        <span>Public</span>
                                                                    </div>
                                                                    <div v-else-if="room.is_private === 'true'" class="rounded-full py-1 px-2 bg-red-100 text-red-800 dark:bg-red-800 dark:text-red-100">
                                                                        <span>Private</span>
                                                                    </div>
                                                                    <div v-else-if="room.is_private === 'false'" class="rounded-full py-1 px-2 bg-green-100 text-green-800 dark:bg-green-800 dark:text-green-100">
                                                                        <span>Public</span>
                                                                </div>
                                                        </span>
                                                    </td>
                                                    <td class="px-6 py-4 whitespace-nowrap text-center">
                                                        <a class="text-md font-medium text-gray-900 dark:text-gray-50">99</a>
                                                      </td>
                                                    <td class="px-6 py-4 whitespace-nowrap text-right text-md font-medium">
                                                        <div class="flex rounded-full py-2 px-4 bg-indigo-700 hover:bg-indigo-900">
                                                        <a href="#" @click="joinRoom(room)"
                                                           class="text-white">Enter</a>
                                                        </div>
                                                    </td>
                                                </tr>
                                                </tbody>
                                            </table>
                                            <div class="bg-gray-800 dark:bg-gray-900">
                                                <div class="flex justify-end px-4 py-3 text-left text-s font-medium text-gray-50 uppercase tracking-wider">
                                                    <span class=" px-2 pt-2 text-xs leading-5 font-semibold rounded-full">
                                                    <a href="#">
                                                    <div class="flex rounded-full py-1 px-2 bg-green-700 text-green-100 hover:bg-green-800">
                                                        <PlusIcon class="h-5 w-5"/><span class="text-sm font-bold pl-0.5">Create Room</span>
                                                    </div>
                                                    </a>
                                                    </span>
                                                </div>
                                            </div>
                                        </div>
                                    </div>
                                </div>
                            </div>
                        </div>
                    </div>
                </TransitionChild>
            </div>
        </Dialog>
    </TransitionRoot>
</template>

<script>
import {Dialog, DialogOverlay, DialogTitle, TransitionChild, TransitionRoot} from '@headlessui/vue'
import {ExclamationIcon, XIcon, PlusIcon} from '@heroicons/vue/outline'
import {types as RoomTypes} from "../../../Store/modules/rooms/rooms.types";

export default {
    components: {
        Dialog,
        DialogOverlay,
        DialogTitle,
        TransitionChild,
        TransitionRoot,
        ExclamationIcon,
        XIcon,
        PlusIcon,
    },
    props: ['rooms', 'selectedRoomId'],
    emits: ['onSelectRoom', 'onLeaveRoom', 'onClose'],
    methods: {
        joinRoom(room) {
            this.$store.dispatch(RoomTypes.JOIN_ROOM, room);
            this.selectedRoomId = this.room;
            this.$emit('onClose');
        }
    },
    props: {
        isOpen: Boolean,
        usersCount: Boolean
    },
}
</script>

主.vue 代码片段

<section aria-labelledby="primary-heading"
                             class="dark:bg-gray-900 min-w-0 flex-1 h-full flex flex-col overflow-hidden lg:order-last">
                        <room-tabs :selectedRoomId="currentRoom.id" :rooms="joinedRooms"
                                   @onSelectRoom="currentRoom = $event" @onLeaveRoom="leaveRoom($event)"/>
                        <message-container :messages="messages"
                                           class="h-full pb-2 mb-2 pt-0 mt-0 shadow-md overflow-y-auto"/>
                        <input-box
                            :room="currentRoom"
                            v-on:messagesent="getMessages"
                            class="dark:bg-gray-800 px-6 pb-6 pt-4 dark:border-t-2 dark:border-gray-600 bottom-0 sticky"
                        />
                    </section>

我知道它的内部方法:joinRoom 需要更改,并且我知道 this.selectedRoomId 在哪里是错误的 - 我只是不知道我需要更改/修复什么以使其在您单击时将选定的房间变成活动房间加入。

任何帮助将不胜感激!

【问题讨论】:

  • 你使用的是 Vuex 还是其他的 state store?
  • @aroundtheworld 我正在使用 VueX
  • 谢谢,添加了一个潜在的解决方案。未来提示:在您的问题中,请精简代码以帮助审阅者,例如整个 &lt;Dialog 元素代码无关紧要。

标签: laravel vue.js


【解决方案1】:

我会使用mapState 来有效地观察由this.$store.dispatch(RoomTypes.JOIN_ROOM, room); 更新的商店中的值

所以在一个需要知道这个值的组件中:

 computed: {
    ...mapState(['STORE_NAME', 'STORE_VALUE']),
  },

然后您应该可以使用this.STORE_VALUE 作为动态更新的值

【讨论】:

  • 也许是因为我的看法不同,但是当我点击进入房间时,房间打开但它不会使选项卡处于活动状态。对我来说,将“selectedRoomId”更新为正确的选定房间会更有意义。因此,如果我选择“Room 2”,然后选择“selectedRoomId = '2'” - 从您所说的来看,您会使用 mapState 来执行此操作,但这似乎在我脑海中。我错了吗?
  • 如果您已经使用此值更新存储,则无需再次将其复制为组件中的数据值,因为您可以直接从存储中从计算属性中获取它,如上面详述
  • 对不起,我只是不明白你的建议。如果我能从我认为的解决方案中绕过它,我会很高兴地将其标记为正确的。我只是还不明白。主要原因是有人可以进入多个房间,因此房间状态会随之改变。如果我在脑海中看到您的解决方案,我会告诉您
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-07-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-12-08
  • 2014-09-07
  • 1970-01-01
相关资源
最近更新 更多