Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to avoid data duplication in props and data?

I'm new to Vue, but I come from a background of working with Google Polymer 2 for about a year. What I'm trying to achieve is to build a self-contained component with its own mutable internal state, and to pass in the initial state via HTML when the page is first sent to the browser from the server (i.e. not a single page app). I've been messing around with props and data for several days and the consensus seems to be: pass in the initial value using a prop, then copy it to a data field, then mutate the data field.

But this creates a duplication of the value! If I have a "title" value, then I need both a prop and a data for that value if I want to make mutation of the title self-contained within the component. (I can't just bind it to an input box because of other reasons like having to process the entered value first.) And when I do mutate the title data field, the now obsolete title prop is still hanging around like a code smell.

Is there a way to avoid this duplication of information? Or is it something that we just have to live with when using Vue? Or am I looking at Vue components all wrong??

P.S. I've tried all sorts of attempts using .sync, $emit and so on, and they're all great for mutating the data fields of a parent component. But what I want is a single component that can listen to an internal state change, do some JS-based work, and then update a single copy of its state without the duplication problem above.

Edit: As requested, here is a simple example of some code that works (I'm using the custom elements extension, but that doesn't seem to impact the core problem). So my question is: how can I deduplicate title and data_title?

<html xmlns:v-bind="http://www.w3.org/1999/xhtml"  lang="en">
<head>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script src="./vue-custom-element.js"></script>
</head>
<body>

<my-element title="an old title"></my-element>

<script type="application/javascript">
    Vue.customElement('my-element', {
        props: [
            'title'
        ],
        data() {
            return {
                data_title: this.title
            };
        },
        template: `<p @click="handleClick('a new title')">My element's title: <b>{{data_title}}</b></p>`,
        methods: {
            handleClick: function(newTitle) {
                // realistically we would do some work here before setting the new value
                this.data_title = newTitle;
            }
        }
    });
</script>
</body>
</html>
like image 571
Cat Fingers Avatar asked May 04 '26 13:05

Cat Fingers


1 Answers

You can't avoid the duplication if you need a public property (one that a parent can pass values to) that your component could modify. It's a necessary evil for mutable props in a Vue component.

like image 141
tony19 Avatar answered May 06 '26 07:05

tony19



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!