Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

General FAQ #96

Closed
yyx990803 opened this issue Feb 11, 2014 · 170 comments
Closed

General FAQ #96

yyx990803 opened this issue Feb 11, 2014 · 170 comments

Comments

@yyx990803
Copy link
Member

Use this thread for simple, quick questions to avoid cluttering the issue list. Alternatively you can try the #vuejs IRC channel on freenode.

Also, read the wiki FAQ first.

@yyx990803 yyx990803 added the FAQ label Feb 11, 2014
@cmenke
Copy link

cmenke commented Feb 11, 2014

Hi! Just started toying with vue.js and ran into an issue when nesting 2 data collections using "repeat" directives. Displaying the data is working fine -- however when an Element (with its subordinate VMs) is destroyed, bound data is currently removed as well (by the "hook:afterDestroy" listener).

Example here: http://jsfiddle.net/sAa9X/ (try clicking any of the items.remove(n) buttons).

Is this unintended behaviour, or is there a better approach I can use?

@yyx990803
Copy link
Member Author

interesting... I haven't considered this type of usage before. maybe I should remove that behavior.

@dyu
Copy link

dyu commented Feb 11, 2014

Hey Evan, first off I think you're doing a great job with vue.
In my case, POJOs and composability are the difference maker (also the speed ofc).
So my question, is this done on your 20% or are you doing this full time (like those angular guys .. e.g 100% Google sponsored)

Thanks

@yyx990803
Copy link
Member Author

@dyu Thanks! This is a 20% project at the moment, but we've started using it in new projects here at Creative Lab, so there's potential that I can dedicate a more substantial part of my fulltime bandwidth to this in the future.

@cmenke
Copy link

cmenke commented Feb 11, 2014

I think I'd be in favour of this and handle related data explicitly (if necessary). Thanks for looking into it, I really enjoy using vue so far!

@yyx990803
Copy link
Member Author

@cmenke Thanks. After thinking about it, I think your suggestion makes sense. Originally I added that hook because I wanted to allow users to manually $destroy repeated instances in expressions, but now that I've seen your example, I believe it's problematic and in general a bad practice (not your example, but manually $destroying repeated vms). The proper way is simply manipulate the source data Array. So in the latest v0.8.5b patch I've reverted that behavior.

@Charuru
Copy link

Charuru commented Feb 14, 2014

Can you say a few words about how this is different / better than angular and where it's more suited?

@yyx990803
Copy link
Member Author

@Charuru there are a few reasons to use Vue over Angular, although they might not apply for everyone:

  1. Vue.js is a more flexible, less opinionated solution. That allows you to structure your app the way you want it to be, instead of being forced to do everything the Angular way. It's only an interface layer so you can use it as a light feature in pages instead of a full blown SPA. It gives you bigger room to mix and match with other libraries. This is probably the most important distinction.
  2. Vue.js is much simpler than Angular in general, so you can learn almost everything about it really fast and get productive.
  3. Vue.js has better performance because it doesn't use dirty checking.
  4. Vue.js has a clearer separation between directives and components. Directives are meant to encapsulate DOM manipulations only, while Components stand for a self-contained unit that has its own view and data logic. In Angular there's a lot of confusion between the two.

But also note:

  1. Vue.js is a relatively young project, while Angular is battle-proven and has a larger community. So if you want something for a large, serious production app you might want to pick Angular.
  2. Vue.js only supports IE9 and above while Angular suppots IE8.

@tomByrer
Copy link

The ^ above post would be great in a WiKi FAQ!
BTW, Angular 1.3 will be IE9+ only. Still no beta for it ATT.

@yjeroen
Copy link

yjeroen commented Feb 25, 2014

Hi Evan,

This week I've been evaluating what frontend framework I should use and arrived at Angular and React. Then I found yours, and I must say I really like the clear style of VueJS.

I understand that Angular has the problem that it gets really slow when it creates a lot of watchers with for example ng-repeat. I found a nice article about that which says "The conventional wisdom for AngularJS says that you should keep the number of data-bound elements below 200."

Now I wonder: Does VueJS have a similar problem with scaling of data-bound elements? Or is the fact that VueJS doesn't use dirty checking the winning factor?

Then why does AngularJS use dirty checking at all?

@yyx990803
Copy link
Member Author

@yjeroen Angular gets slow when there are a lot of watchers, because every time anything in the scope changes, all these watchers need to be re-evaluated again. Vue.js doesn't suffer from this because under it uses an event based observing mechanism, so all changes trigger independently unless they have explicit dependency relationships.

I believe Angular uses dirty checking because it had to support IE8. Vue.js is able to get the plain object syntax using ES5 features, which IE8 doesn't support. On the other hand, dirty checking also has the benefit that the original data objects are not modified in anyway (Vue.js converts object properties into getter/setters.)

@yjeroen
Copy link

yjeroen commented Feb 25, 2014

@yyx990803
Thank you for the elaborate response. What can be a disadvantage from using change listeners and changing the original object? And is that something a developer needs to be aware of, or is that 'disadvantage' taken care of by Vue.js?

@yyx990803
Copy link
Member Author

@yjeroen
There are some very minor caveats:

  1. When you console.log observed objects you will only see a bunch of getter/setters. You will have to JSON.stringify them first.
  2. You cannot define your own getter/setters on data objects. This isn't much of a problem because data objects are expected to be obtained from plain JSON and Vue.js provides computed properties.
  3. Vue.js sometimes have to attach hidden properties ($index, $key, $value, $repeater and __emitter__) to data objects in order to observe them. If the developer accidentally overwrite these properties it would break. But it's very rare to run into such situations and they are very easy to avoid (just don't set anything that start with $ on your data objects).

Apart from the above caveats, you can use Vue.js observed objects just like normal objects. JSON.stringify and for ... in ... loops will work as intended. So 99% of the time you don't even need to worry about it.

@adamgd
Copy link

adamgd commented Feb 26, 2014

I am trying to update array items in a Vue data object. I have tried using v-model:

http://jsfiddle.net/obomoboe/HM9rn/1/

and have tried specifying a handler so that I can be specific about what I am assigning from/to:

http://jsfiddle.net/obomoboe/HM9rn/2/

Neither one will update $data. When I look in the debugger at the update method, both values evaluate as I would expect them to, but it still doesn't seem to update the VM. I'm sure I've missed the point, but where?

@yyx990803
Copy link
Member Author

@adamgd sorry, this is one of the gotchas when you interpolate $data - changes that happen inside Array elements do not propagate out of the Array. So the data in fact changed, but the {{$data}} binding was not notified. It is recommended to log the stringified data in console instead of outputting it with {{$data}}.

@ghost
Copy link

ghost commented Feb 26, 2014

@adamgd an example fiddle: http://jsfiddle.net/HM9rn/3/

@mikegioia
Copy link

Hi Evan -

I was wondering if there was anything on the horizon to release a more robust working example of Vue/Component. I saw on the Roadmap that there was some discussion on routing/page.js but I was curious if you or anyone had a sample project incorporating routing, page transitions, etc using component. I really like the way Vue structured, much more so than Angular, but I'm having trouble figuring out how I should structure my app.

@yyx990803
Copy link
Member Author

@mikegioia yes, that's definitely part of the plan. The first step is probably the vue-router module. You should probably watch vue-router and vue-component-example to keep updated.

@adamgd
Copy link

adamgd commented Feb 26, 2014

@yyx990803, @brandonpierce: thank you both. I tested another fiddle with DOM mirroring of the data rather than interpolation: http://jsfiddle.net/obomoboe/HM9rn/4/

I now understand this quirk is to do with the interpolation (rather than something more fundamental to do with the change watching as I had initially thought after the response from @yyx990803). Is this 'gotcha' documented somewhere?

@mikegioia
Copy link

@yyx990803 ok will do. Thanks again!

@yyx990803
Copy link
Member Author

@adamgd No it has not been documented, because interpolating objects is a pretty recent addition and there might be changes later.

@mizchi
Copy link

mizchi commented Mar 2, 2014

I have a question about vue.js's template initialization.
I tried vue.js and svg template(sorry for minor issue!). It almost worked but I have a problem caused by strict svg rules at instatiation.

Template is here.

SvgComponent = Vue.extend({
  template: """
  <svg width=640 height=480>
    <circle
      cx=30 cy=30
      r="{{size}}"
      stroke="grey" stroke-width=1 />
  </svg> 
  """
  data:{size: 25}
})

(sorry for coffeescript. javascript multiline text is bothersome)

It occurs this error at first

Error: Invalid value for <circle> attribute r="{{size}}" 

This is simple reason why svg property circle must be filled with cx,cy, and r at instatiation, strictly(html is not). After this error, template is expanded by injection of $data.size and works well.

What I want to ask is how vue.js can inject data values to template before DOM(SVG) initialization or send defaut value to blaced point. At worst, I want to prepare custom error catcher to grasp it.

This is a same problem with angular/angular.js#1050 of angular but vue.js directive's bind is after DOM initialization.

(I know set r=0 and this.$watch("size", function(val){this.$.r = val}) works but dirty)

Do you have any idea? Sorry for long post...

@bpierre
Copy link

bpierre commented Mar 2, 2014

The directive v-attr is what you are looking for: http://jsfiddle.net/8VtSM/

@mizchi
Copy link

mizchi commented Mar 2, 2014

Ohhhh there was simple solution! I lost it and thought too difficult... anyway thx!

@ayamflow
Copy link

ayamflow commented Mar 4, 2014

Is it possible to use v-component (and other string-based directive) with an interpolated attribute, such as <div v-component="{{the-component}}"></div> ?

@yyx990803
Copy link
Member Author

@ayamflow no, because v-component has higher priority than interpolation, so it is compiled before the attributes are interpolated.

edit: directives that start with the prefix are not interpolated at all.

@marfalkov
Copy link

Would it be hard to implement a new partial behavior to be able to replace the element itself instead of it's innerHTML?

<div>{{> my-partial}}</div>

I think the syntax couldn't be much simpler than this:

<div>{{< my-partial}}</div>

The stripped down version of my problem:
http://jsfiddle.net/marfalkov/Rxxf9/

@yyx990803
Copy link
Member Author

@marfalkov I don't think a replace partial syntax is the solution to your problem - I think something that allows conditional partial is. I'll look into it more later this week.

@marfalkov
Copy link

@yyx990803 Conditional partials sounds really good.

@yyx990803
Copy link
Member Author

@abhijitghogre you can actually safely ignore this warning. You can suppress expression evaluation warnings by setting Vue.config.warnExpressionErrors = false.

Or, initialize your data more specifically (although verbose, this has the benefits that you know what shape the ajax response looks like):

data: {
  college: {
    status: {
      name: ''
    }
  }
}

@ghost
Copy link

ghost commented Jun 25, 2015

Thanks Evan!

@ghost
Copy link

ghost commented Jun 27, 2015

Evan,

I used this to set image src:

<img v-attr="src: coverImagePath">

When I change 'coverImagePath' model, the image doesn't update. Any workaround?

computed: {
            coverImagePath: function () {
                if (typeof this.college.cover_pic !== "undefined" && this.college.cover_pic !== '') {
                    return '/uploads/covers/college/' + this.college.cover_pic
                }
                return '/img/default_cover.jpg';
            }
        },

@mark-hahn
Copy link

That should work. Can you show your code that creates and/or passes
the coverImagePath
value in?

On Sat, Jun 27, 2015 at 11:20 AM, abhijitghogre [email protected]
wrote:

Evan,

I used this to set image src:

When I change 'coverImagePath' model the image doesn't update. Any
workaround?


Reply to this email directly or view it on GitHub
https://github.com/yyx990803/vue/issues/96#issuecomment-116092995.

@ghost
Copy link

ghost commented Jun 27, 2015

coverImagePath should get computed automatically when college changes right?

This is where 'college' model is changed (ajax success).

methods: {
    fetchCollege: function() {
        $.ajax({
            url: $('.showCollegeRoute').val(),
            method: 'GET',
            statusCode: {
                200: function(response) {
                    this.college = response;
                }.bind(this)
            }
        });
    }
}

And this is how it is declared in data:

data: {
    college: {}
},

@yyx990803
Copy link
Member Author

@abhijitghogre Looks like it should work. Open an issue at vuejs/Discussion and make a fiddle reproduction please.

@ghost
Copy link

ghost commented Jun 28, 2015

Here is the fiddle: https://jsfiddle.net/pc2gg27y/5/

I have also created issue on Discussion repo vuejs/Discussion#216

@lusty15
Copy link

lusty15 commented Jul 3, 2015

I'm new to Vue, and attempting to render a JSON object returned by PHP using it's JSON_ENCODE function. Is there a simple way of loading this data into a list?

@azamat-sharapov
Copy link

@lusty15 has 38 participants and is closed, so that people don't spam with questions. I think it's best to ask questions like yours on vuejs/Discussion or in gitter channel of yyx990803/vue repo.

As for you question, there is vuejs/vue-resource plugin for AJAX calls, you can use it to fetch JSON from server.

@lusty15
Copy link

lusty15 commented Jul 3, 2015

Thank you.

@nicklaw5
Copy link

@yyx990803 Hi Evan.

For starters really loving Vue.js. Great job!

To my question: Is it possible to "trigger" jQuery-like events? I posted this question on StackOverflow, then came across this thread and thought it might help others who come across the same situation.

@simplesmiler
Copy link
Member

@nicklaw5 why do you need the event in your method?

If it carries some useful information (target element, or click coordinates), then I'd say it's better to create a dedication method with corresponding signature, and call this method from the click handler.

The most common use case for having the event is to event.preventDefault(), but you don't need that if you call your method from the code, because you don't have the event in the first place.

@temp-name-9956
Copy link

Hi, according to discussion from here my jsfiddle should work, but it looks like those native events don't trigger data sync in vue?

@yyx990803
Copy link
Member Author

@sl-codenine v-model listens to input event by default, and only listens to change in lazy mode: http://jsfiddle.net/yyx990803/g7dteuve/2/

@JosephSilber
Copy link

@yyx990803 I've run into this before.

Any reason the default non-lazy v-model doesn't also listen to change?

@temp-name-9956
Copy link

@yyx990803 Cool, that should work for me, thanks :)

@JosephSilber probably that's because change is getting triggered only after focus being moved to some other input/element, so thanks to listening on input you can see data-binding 'as-you-type'.

But i somewhat agree, that it could by default listen on input and on change, and in lazy mode just on change. It makes sense to me, and one can expect it to listen to change event. At least if there are no technical issues related.

@thecotne
Copy link

is there any way to change several variables without rendering intermediate stages?
it makes UI very slow and some times it is just wrong

@yyx990803
Copy link
Member Author

@thecotne Vue's default behavior buffers the rendering until next event loop, so what you described should never happen. If you are running into problems, create an issue with a reproduction.

@mark-hahn
Copy link

I've never use a prop with an underscore. I'm not sure what it would
convert into for the hyphen-case version. Could that be it?

On Fri, Aug 14, 2015 at 3:57 PM, Jason Daly [email protected]
wrote:

I'm having trouble understanding how a computed property is observed from
a child via props vs. inherit. Given the following parent view:

Parent Vue

var Parent = Vue.extend({

data() {
return {
orders: [].
tab: 'current'
};
}

computed: {

scoped_orders() {
  return this[this.tab];
},

completed() {
  return this.orders;
}

future() {
  return this.orders;
}

},

components: {
child: Child
}

});

why does the following work (using 'inherit')

Child Vue

var Child = Vue.extend({

template: require('some/template/path.mustache'),

inherit: true,

});

but the following does not (using props):

Child Vue

var Child = Vue.extend({

template: require('orders/index.mustache'),

props: [ 'scoped_orders' ]

});

Specifically, I have a template like this for the child

and when using props to fetch the computed scoped_orders property, I get
the following error

[Vue warn]: Error when evaluating expression "scoped_orders.length".
TypeError: Cannot read property 'length' of undefined

Using inherit instead of props, the child view observes changes to
scoped_orders without a problem.

Worth mentioning, orders on the parent is updated via an Ajax response
with a set of data, but is initially empty. The error occurs before the
Ajax has time to finish.


Reply to this email directly or view it on GitHub
https://github.com/yyx990803/vue/issues/96#issuecomment-131263449.

@slmjkdbtl
Copy link

What is the exact difference between vm.$data.prop and vm.prop? Under what circumstances should we use $data?

@yyx990803
Copy link
Member Author

@voyga see http://vuejs.org/guide/#Model

vm.prop is simply a getter/setter proxy to vm.$data.prop.

@chrisvfritz
Copy link
Contributor

Is v-model really supported in IE9? It looks like the input event doesn't work in that browser.

@chenjie-cnooc
Copy link

what's the dirty check using html string? when I use the Vue.Router,I can't change to other hashurl.

@sabrinaluo
Copy link

@bpierre
hi, thanks for your v-attr hint, it works when the attribute is simple.
do you have any idea how to make this work? or do you have any other way to make it work? thank you :)

<g v-for="d in data" transform="translate({{$index}}, 0)">

@curtisblackwell
Copy link

I have an array of data in my Vue instance with Unix timestamps for each element. I'm looping over the data with v-for and trying to filter it with a v-model input.

I want people to be able to specify a range to filter by in plain English, so I'm trying to do this:

  • Send the plain English data to the server where PHP parses it and sends back some JSON.
  • Use that JSON to filter the array sent to the Vue.filter() method.
  • Return the filtered array so that the view updates.

It seems as though it's not possible b/c if I return the array (or part of it) before the AJAX call, the filtering "works." However, if I return within the this.$http.get() request, it seems as though Vue stopped paying attention. I tried playing around with debounce a bit, but to no avail.

Should this work? Is there something I should do instead?

@posva
Copy link
Member

posva commented May 3, 2016

@curtisblackwell
Ask the question on the forums or the gitter chat. This is no longer used

@curtisblackwell
Copy link

@posva will do. Why not close/lock this then?

@vuejs vuejs locked and limited conversation to collaborators May 3, 2016
@blake-newman
Copy link
Member

blake-newman commented May 3, 2016

Locked:

Please ask questions or post information on the forums or the gitter chat. This is issue is no longer in use.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests