1

I have a language selector view that includes a dropdown component. I want to set a default property (isOpen) in the dropdown component and then include computed data from the language selector, that is then displayed in the dropdown.

Yet I can't seem to find a way to define isOpen in the dropdown component without it being overriden by the new data from the language selector.

Here are the files:

language-selector.js

var model = require('model/language');
var uiDropdown = require('ui/dropdown');
var template = require('./index.html');

var vm = new Vue({
    template: template,
    components: {
        'ui-dropdown': uiDropdown
    },
    created: function() { self = this; },
    ready: init,
    data: function(){ return model; },
    computed: {
        dropdown: {
            get: function(){
                return {
                    options: (function(){
                        return model.options.map(function(option){
                            return { id: option.id, label: option.code }
                        })
                    }())
                ,   currentID: model.currentID
                ,   type: uiDropdown.opt.types.SMALL
                }
            }
        }
    }
});

language-selector template (index.html):

<div v-component="ui-dropdown" v-with="dropdown"></div>

dropdown.js (with isOpen defined in data. I also tried defining it both in the created and the ready hooks, yet it didn't work either):

var template = require('./index.html');

module.exports = {
    template: template,
    created: function() {
        self = this;
    },
    ready: init,
    methods: {
        onSelect: onSelect,
        onOpen: onOpen
    },
    data: function(){
        return {
            isOpen: false,
            type: types.SMALL
        }
    },
    computed: {
        currentLabel: {
            get: function(){
                var selectedModel = filterSelected(self.$data, self.$data.currentID);
                return self.$data.options[self.$data.currentID].label;
            }
        }
    },
    opt: {
        types: types
    }
}

And finally the dropdown template (index.html):

<div class="dropdown {{ isOpen ? 'dropdown__open' : ''}}" v-class="type">
    <a v-on="click: onOpen" href="#" class="dropdown--label">
        {{ currentLabel }} {{ options.isOpen }}
        <span class="icon__dropdown"></span>
    </a>
    <ul class="dropdown--list">
        <li v-repeat="option: options" class="{{ currentID == option.id ? 'dropdown--list__current' : '' }}">
            <a v-on="click: onSelect" href="{{ option.id }}">
                {{ option.label }}
            </a>
        </li>
    </ul>
        </div>

And here the output of the $data of the dropdown component (which lacks the isOpen):

enter image description here

1 Answer 1

2

From the VueJS Guide:

v-with can also be used with an argument in the form of v-with="childProp: parentProp". This means passing down parent[parentProp] to the child as child[childProp]

Basically you're overriding all of the child component's data by using v-with. You should instead specify which properties to override using the second form of the directive.

Sign up to request clarification or add additional context in comments.

2 Comments

Thank you, I came to this after a while. Unfortunately, there doesn't seem to be a clean way to replace the child data with the parent data only where the parent key is the same as the childs and to keep the rest.
Yeah I think I agree with you there. I might suggest this as a feature on GitHub.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.