I got a case where I need to update the $parent binding inside the component that is using it with v-with
You can pass down an object and changes to that object will reflect on parent.
I have a component like this:
<div v-with="current_date: current_date">
<input type="text" v-model="current_date">
</div>
Changes to current_date inside the component doesn't reflect on the parent, forcing me to do this:
created: function() {
this.$watch("current_date", function(value) {
this.$parent.current_date = value;
});
}
The reason it doesn't reflect to parent is because if a component has isolated scope, it should avoid modifying its parent's state (and just take whatever data the parent gives it, so it's a unidirectional data flow). If it needs to access and modify parent state, then just make it inherit parent scope.
But then it would inherit too much, why this is a good pattern?
I'm not sure how big is your component - if that input field is all it's doing, why make it a component at all?
I would love to keep the behavior of v-with consistent with how arguments are passed into functions in JavaScript: you can't modify the original variable outside the function from within, you can only mutate an object that's been passed in.
makes sense
I used to create custom components behaving like form inputs using v-with.
E.g. I would have a switch component I could use like this:
<switch-input v-with='model: some.parentProperty' />
<file-uploader v-with='model: some.parentProperty' />
So the concept of keeping parent scopes untouched makes sense, except there seems no way to reproduce input-type behaviours using components.
I didn't find another way of doing this, would be great to have a way of using v-model on custom components. Any suggestions on how to do this with v0.11?
You can do v-with="model: some" then inside do v-model="model.someProperty", although maybe there could be a v-bind that does what the old v-with does...
If I use v-model="model.someProperty" inside the component template it's still gonna reference to the child property, which is only a clone.
Right now I'm manually watching for a value change and operating on the parent using this.$parent, which is quite a dirty one.
I'm not sure I understand the reasoning behind this change - the whole point of a VM* library that performs bi-directional binding is - to me - maintaining an accurate representation of decoupled data, not imposing hierarchical flow in the architecture.
...in JavaScript: you can't modify the original variable outside the function from within, you can only mutate an object that's been passed in...
Not sure I understand what you mean, E.g.:
// Root scope
var rootVariable = 'foo';
// Parent scope
(function () {
var parentVariable = 'a';
rootVariable = 'bar';
// Child scope
function foo () {
parentVariable = 'b';
}
console.log(parentVariable); // 'a'
foo();
console.log(parentVariable); // 'b'
}());
console.log(rootVariable); // 'bar'
By that I mean this:
var rootVar = 1
var rootObj = { a: 1 }
function child (parentVal) {
parentVal.a = 2
parentVal = 2
}
child(rootVar)
console.log(rootVar) // 1
child(rootObj)
console.log(rootObj.a) // 2
So if you pass model down as an object, you can indeed mutate it from a child component. It's just you can't change the parent's reference to model.
Ok the example makes sense but I think in the context of a VM* library handling bi-directional binding is key, if you allow form inputs to manipulate the source of data components should have the same access to parent scopes.
I don't see a big difference between the semantics of a form input (Which comes as a pre-existing component of the library, which applies custom behaviour to a HTML tag) and a custom UI component - they should have the same level of access, right?
After some thinking I tend to agree the one-way restriction on v-with is unnecessary - this will likely be reverted in the next point release.
看到v-with重新支持双向实在太好了,我写了一些通用的component,比如日期选择,在一个form里可能多次调用,如果不能双向绑定的话,实在是不好处理。
<div class="form-control date" v-component="date" v-with="date:model.startDate"></div>
<div class="form-control date" v-component="date" v-with="date:model.endDate"></div>
@yyx990803 I had hugely appreciated that being reverted when this discussion took place, although I've noticed in has been reverted back again in newer versions.
The thing is, while the v-model directive is still escaping this logic (And not made re-adaptable to custom components), it's impossible now to create custom components that behave like form inputs by manipulating a referenced value in the parent scope.
Let's take the example of someone wanting to create an On / Off switch or a multiple choice with different markdown from a select.
Why is this:
<select v-model='myTwoWayValue'></select>
possible using default HTML inputs, while nothing like this:
<my-custom-switch value='myTwoWayValue'></my-custom-switch>
is not allowed?
I do understand the reasoning and philosophy behind a one directional data flow - but again, this approach doesn't really allow anyone to adopt different patterns, with the only exception of form inputs which still behave like two-way binding custom components and sort of escape this rule.
I don't mean to be annoying by re-opening this conversation, but since I'm still using Vue.js as I've been for very long time and I'm a great supporter, one of the things I always appreciated of it is its aspect of being unopinionated and versatile.
Vue.js presented from the start as a lightweight VM class that doesn't try to enforce upon you a monolithic architecture - allowing you to be truly modular in however you wish to structure tour application and escaping the framework hell / feature war.
This feels a bit like a step back into trying to impose a philosophy by limiting choice, which is really not what I'd expect from Vue.js.
Custom components can use v-model to work as native inputs. See the docs here: http://vuejs.org/guide/components.html#Form-Input-Components-using-Custom-Events
In essence:
value propinput event with the new value: this.$emit('input', newValue)Then, when the parent uses v-model on the component, the value updates.
Oh - I didn't spot that - guess I've pulled such an elaborate rant all for nothing - sorry @yyx990803 , this is actually quite a nice implementation (Still really liked the two way data binding syntax that has been present for a few sub versions, though).