Discussion icon indicating copy to clipboard operation
Discussion copied to clipboard

Same data, multiple uses

Open paglias opened this issue 9 years ago • 12 comments

Hi,

I would like to keep my data in a single place, let's say an object that is external to Vue:

var data = {
    items: [{n: 1}, {n:2}, {n:3}],
    ....
}

and use it concurrently using different directives at the same time, like:

Vue,component('component1', {data: data});
Vue,component('component2', {data: data});
<div v-component="component1"><span v-repeat="item:items">{{item.n}}</span></div>
<div v-component="component2"><span v-repeat="item:items filterBy...">{{item.n}}</span></div>

Is this going to be work in every sitaution? I mean, vue is going to add its own magic properties to items of array from two different directives that may have different needs, I imagine it could led to bugs.

If it's not supported, what is the best way to do this? And the same problems could arise when passing data to more than one child at the same time from a parent component?

Thanks

paglias avatar Jun 10 '15 12:06 paglias

Vue was designed to work properly in such use cases. What you do need to be aware of is:

  1. You are really sharing the same object across instances, so changes made to the data from one instance can affect all the other instances observing the same object.
  2. If one of your components changes its reference to the object, it will lose that connection.

You might want to consider adopting a Flux-like architecture and only mutate the data inside a centralized store, and let different components talk to the store instead of mutating the object themselves.

If you run into any bug, do let me know!

yyx990803 avatar Jun 10 '15 13:06 yyx990803

You might want to consider adopting a Flux-like architecture and only mutate the data inside a centralized store, and let different components talk to the store instead of mutating the object themselves.

So, i would register a listener on each component and get a new representation of the data each time it changes in the store?

It won't be slow? Replacing the whole object every time. If it's not what you meant, could you provide an example?

Thanks for the help :)

paglias avatar Jun 10 '15 14:06 paglias

No, something like this: http://jsfiddle.net/xk3wekw7/

yyx990803 avatar Jun 10 '15 14:06 yyx990803

So child components' data should always come from root, not directly from the store?

2015-06-10 16:02 GMT+02:00, Evan You [email protected]:

No, something like this: http://jsfiddle.net/xk3wekw7/


Reply to this email directly or view it on GitHub: https://github.com/vuejs/Discussion/issues/183#issuecomment-110765980

Matteo Pagliazzi - paglias.net

paglias avatar Jun 10 '15 14:06 paglias

It can be directly from the store too, it depends on your component needs. I'm just demonstrating a possible approach here.

yyx990803 avatar Jun 10 '15 14:06 yyx990803

@yyx990803 thanks, it's working very well so far, I just released a small app using this approach :)

I would have another question, it's possible to use a method inside a v-text directive or mustache binding? I would like to print a string from a method without setting up observables or anything else, just a plain function call where the output is used as a one time binding. I would prefer not to use something like this:

{
    data: {
        string: this.methodName()
    }
}

but directly:

{
    methods: {
        outputString: function(){ return ...}
    },
    template: `{{outputString('param')}}`
}

paglias avatar Jun 18 '15 15:06 paglias

Yeah, it should work. Let me if it doesn't (and that would be a bug!)

yyx990803 avatar Jun 18 '15 15:06 yyx990803

@yyx990803 it's working http://jsfiddle.net/ukremupp/1/ but if you open the console root._watchers has created a watcher for it. My use case is to print i18n version of strings and they would have to be performant since there'll be hundres of them. Is there a way not to create a watcher and at the same time use a mustache binding? I don't want to create an element directive as it or have templates preprocessed

paglias avatar Jun 21 '15 10:06 paglias

The correct link is http://jsfiddle.net/ukremupp/1/

paglias avatar Jun 21 '15 10:06 paglias

root._watchers.length shows 0 for me.

yyx990803 avatar Jun 21 '15 20:06 yyx990803

You're right, probably I saw the element in the array in a previous version of the code. I'm sorry and thanks again

paglias avatar Jun 22 '15 16:06 paglias

@yyx990803 shouldn't this be closed?

lifeiscontent avatar Feb 24 '18 07:02 lifeiscontent