【问题标题】:VueJS click events in compoments组件中的Vue JS点击事件
【发布时间】:2020-06-26 09:34:24
【问题描述】:

我已经制作了一个组件(是不是矫枉过正?)以递归方式调用以呈现树,但似乎无法处理点击事件,因为在组件内呈现的东西看不到我想要的方法Vuemethods;这似乎是关于组件和事件的一些可怕的复杂性。

如何处理这些点击事件? 真的要这么难吗?

    <script type="text/html" id="template-tree">
        <ul>
            <c-tree-item v-for="item in items" v-bind:item="item"></c-tree-item>
        </ul>
    </script>

    <script type="text/html" id="template-tree-item">
        <li v-on:click="clickTreeItem"> <!-- click doesn't work :( -->
            <p> {{ item.Name }}</p>
            <ul v-if="item.Items.length > 0">
                <c-tree-item v-for="i in item.Items" v-bind:item="i"></c-tree-item>
            </ul>
        </li>
    </script>

    <script type="text/javascript">
        var vueApp = undefined;

        var ct = Vue.component('c-tree', {
            template: document.getElementById('template-tree').innerHTML,
            props: ['items']
        });
        var cti = Vue.component('c-tree-item', {
            template: document.getElementById('template-tree-item').innerHTML,
            props: ['item']
        });

        $(document).ready(function () {
            var router = new VueRouter({
                mode: 'history',
                routes: []
            });

            vueApp = new Vue({
                router,
                el: '#vue',
                data: {
                    tree: JSON.parse(document.getElementById('data').innerHTML)
                },
                methods: {
                    clickTreeItem: function(event) {
                        console.log('click');
                        console.log(JSON.stringify(event));
                    }
                }
            });
        });
    </script>

<div id="vue">
    <c-tree v-bind:items="tree"></c-tree>
</div>

【问题讨论】:

  • 你能在 codepen 中重现吗?
  • jsfiddle.net/1mspo85g/1 点击是在 HTML 的第 27 行检测到的。在这里,甚至console.log 也会导致各种错误。如果将其更改为v-on:click="clickTreeItem",则会得到相同的属性或方法“clickTreeItem”未在实例上定义但在渲染期间引用。错误。
  • jsfiddle.net/1mspo85g/2(修复了v-for :key的东西)
  • (从今天起我是 Vue 的新手,但使用过 KnockoutJS、KendoUI 可观察对象和短暂的 React(讨厌它)。我希望用单击项目的数据填充编辑器和当我使用编辑后的名称更新 data 时,列表项文本会更新。)
  • 在这种情况下使用Vuex会更容易。

标签: vue.js vue-component vue-events


【解决方案1】:

组件只能引发事件——这些事件可能有与之关联的数据。

一个组件必须监听它的子组件的事件,并且可以反过来将它们作为自己的事件向上传递。

示例:https://jsfiddle.net/gkch7bnr/1/

StackOverflow 对 JSFiddle 很草率,所以这里有一些代码:

<head>
<script
              src="https://code.jquery.com/jquery-3.4.1.min.js"
              integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo="
              crossorigin="anonymous"></script>

<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.11/vue.common.dev.js" integrity="sha256-soI/D3XnqcarOMK229d8GWs8P+gYViEsbWBeMaRoSPk=" crossorigin="anonymous"></script>

      <script type="application/json" id="data">
        [
          {"Id": 1, "Name": "Name1", "Items": []},
          {"Id": 2, "Name": "Name2", "Items": []},
          {"Id": 3, "Name": "Name3", "Items": [
            {"Id": 31, "Name": "Name31"},
            {"Id": 32, "Name": "Name32"},
            {"Id": 33, "Name": "Name33"}
          ]} 
        ]
    </script>

      <script type="text/html" id="template-tree">
        <ul>
            <c-tree-item v-for="item in items" v-bind:item="item" v-on:click="$emit('click', $event)"></c-tree-item>
        </ul>
    </script>
    <script type="text/html" id="template-tree-item">
        <li>
            <p v-on:click="$emit('click', item)" > {{ item.Name }}</p>
            <ul v-if="item.Items && item.Items.length > 0">
                <c-tree-item v-for="i in item.Items" v-bind:item="i" v-on:click="$emit('click', $event)"></c-tree-item>
            </ul>
        </li>
    </script>
</head>
<body>
  <div id="vue">
    <c-tree v-bind:items="tree" v-on:click="clickTreeItem"></c-tree>
</div>
</body>

var vueApp = undefined;

        var ct = Vue.component('c-tree', {
            template: document.getElementById('template-tree').innerHTML,
            props: ['items'],
            methods: {
                clickTI: function(e) { console.log('clickTI: ' + e.Name);}
            }
        });
        var cti = Vue.component('c-tree-item', {
            template: document.getElementById('template-tree-item').innerHTML,
            props: ['item']
        });

        $(document).ready(function () {
            vueApp = new Vue({
                el: '#vue',
                data: {
                    tree: JSON.parse(document.getElementById('data').innerHTML)
                },
                methods: {
                    clickTreeItem: function(event) {
                        console.log('clickTreeItem: ' + event.Name);
                    }
                }
            });
        });

【讨论】:

  • 你在干什么?
  • 有什么问题?
猜你喜欢
  • 2020-07-23
  • 1970-01-01
  • 2019-03-20
  • 1970-01-01
  • 2019-07-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-05
相关资源
最近更新 更多