Vue:选中时的样式列表行

时间:2017-12-28 17:49:44

标签: vue.js vuejs2 vue-component

我有一个名为client-row的组件列表,当我选择一个组件时,我想更改样式。在选择新行时尝试从先前选定的行中删除样式时遇到问题。

Vue.component('client-row', {
    template: '#client-row',
    props: {
        client: Object,
    },
    data: function() {
        return {
            selected: false
        }
    },
    methods: {
        select: function() {

            // Does not work properly
            el = document.querySelector('.chosen_row')
            console.log(el)

            if ( el ) {
                el.className = el.className - "chosen_row"
            }
            this.selected = true
            this.$emit('selected', this.client)
        }
    }
})

<script type="text/x-template" id="client-row">
    <tr v-bind:class="{ 'chosen_row': selected }">
        <td>{{ client.name }}</td>
        <td>{{ client.location_name || 'no location found' }}</td>
        <td>{{ client.email || 'no email found' }}</td>
        <td><button class="btn btn-sm btn-awaken" @click="select()">Select</button></td>
    </tr>
</script>

我可以正确设置selected属性,但似乎无法可靠地删除它。

1 个答案:

答案 0 :(得分:1)

手动修改组件中的DOM元素通常是不好的做法。相反,我建议您更改父组件以使其具有数据字段以跟踪选择的行,并将该值传递给行。然后该行将检查其值是否与父选择的行匹配,如果为真则应用样式。

组件中的DOM操作表明你在vue中做错了。

在你的情况下,vue和你的手动DOM操作正在相互争斗。 Vue根据孩子的数据字段chosen_row是否为真,跟踪是否在tr上添加selected课程。在您的代码中,您只能将其设置为true。 Vue将始终尝试为您单击的任何行包含该类。然后,您将手动从之前单击的所有行中删除该类,但是Vue仍会尝试添加该类,因为selected在已单击的子组件中仍然为真。

您需要采用面向数据的方法而不是基于DOM操作的方法。

儿童:

Vue.component('client-row', {
    template: '#client-row',
    props: {
        client: Object,
        selectedClient: Object
    },
    methods: {
        select: function() {
            this.$emit('selected', this.client);
        }
    }
})

<script type="text/x-template" id="client-row">
    <tr v-bind:class="{ 'chosen_row': client === selectedClient }">
        <!-- td's removed for brevity -->
        <td><button class="btn btn-sm btn-awaken" @click="select">Select</button></td>
    </tr>
</script>

<强>父:

Vue.component('parent', {
    template: '#parent',
    data() {
        return {
            clients: [],
            selectedClient: null
        };
    },
    methods: {
        clientSelected(client) {
            this.selectedClient = client;
        }
    }
})

<script type="text/x-template" id="parent">
    <!-- i dont know what your parent looks like, so this is as simple as i can make it -->
    <div v-for="client in clients">
        <client-row :client="client" :selected-client="selectedClient" @selected="clientSelected"></client-row>
    </div>
</script>

此外:

按钮上的点击事件处理程序可以缩短为@click="select",这是绑定方法的推荐方法。