VueJS событий кликов в комплементах - PullRequest
0 голосов
/ 14 марта 2020

Я сделал компонент (это перебор?) Для рекурсивного вызова, чтобы отобразить дерево, но кажется невозможным обрабатывать события щелчка, потому что вещи, отображаемые внутри компонента, не могут увидеть нужный мне метод Vue х methods; это кажется чудовищным осложнением для компонентов и событий.

Как я могу обработать эти события щелчка? Неужели это так сложно?

    <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>

1 Ответ

0 голосов
/ 15 марта 2020

Компонент может вызывать только события - с которыми могут быть связаны данные.

Компонент должен прослушивать события своих подкомпонентов и может, в свою очередь, передавать их вверх как свои собственные события .

Пример: 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);
                    }
                }
            });
        });
...