atm vue treats the data coming from the instance as the only truthy source https://vuejs.org/v2/guide/forms.html#Basic-Usage which is fine in most of the time, but what if am using something like Laravel or any backend where we could send something to the view file.
but why not get those data through ajax ?
because when we use the inline-template feature, we can then use the code we are already used to in blade while using the full power of vue 💃
@extends('layouts.app')
@section('content')
<auth-form inline-template>
{{ Form::open(['route' => 'post.resetpassword', 'class'=>'form-horizontal','@submit.prevent'=>'FormSubmit']) }}
{{-- Token --}}
<form-input inline-template>
<input type="hidden" name="token" value="{{ $token }}">
</form-input>
{{-- Email --}}
<form-input inline-template :has-errors="errors.email">
<div :class="[{'has-error': hasErrors}, 'form-group']">
{{ Form::label('email', 'E-Mail Address', ['class'=>'col-md-4 control-label']) }}
<div class="col-md-6">
{{ Form::email('email', $email, ['class'=>'form-control','autofocus','v-model'=>'input']) }}
<form-errors :errors="hasErrors"></form-errors>
</div>
</div>
</form-input>
...
{{ Form::close() }}
</auth-form>
@endsection
but the problem starts to raise when we want to add a pre-init value to the v-model like
<form-input inline-template>
<input type="hidden" name="token" value="{{ $token }}" v-model="input" >
</form-input>
which is sadly is not available for the input fields https://vuejs.org/v2/guide/forms.html#Value-Bindings
however, we can still achieve that through a dirty hacky fix, like
<form-input inline-template>
<input type="text" name="token" data-token="{{ $token }}" @blur="hiddenValue" autofocus style="opacity: 0;height: 0;width: 0">
</form-input>
methods: {
hiddenValue() {
this.input = event.target.dataset.token
}
},
md5-d7a9070273db899dd25cafe0c528df6b
```js
created(event) {
this.input = event.target.dataset.token
},
You can listen on the mounted event for your inline component. Inside that handler, you can access the rendered DOM tree in this.$el.
Dracula is on the right path, but if you print your initial data before invoking your Vue script, it should already be available to your data callback. Something like:
public function someControllerAction(Request $request) {
return view('some.view', [
'initialData' => [
'token' => 'super secret crypty thing'
]
]);
}
```blade
@section('content')
@stop
```html
// some-component.vue
<script>
export default {
data() {
return {
...initialData, // from window.initialData
other: 'stuff'
}
}
}
</script>
Provided a more complete example.
@sirlancelot thanx for the suggestion, but it returns the dom elem itself, is which case its not exactly what am after.
@hector-humberto thanx for hacky way around, but again not what i was after
Hi, I think @sirlancelot 's approach is good enough for server-side rendered form.
Example: http://jsfiddle.net/gjwL7byz/
Also @hector-humberto 's approach is a standard way for SSR. See https://github.com/vuejs/vue-hackernews-2.0 for example.
IMHO, the OP's suggestion is probably impossible for some lifecycle. When created is called, Vue has not yet found the dom element, thus no event.target.
@ctf0:
@sirlancelot thanx for the suggestion, but it returns the dom elem itself, is which case its not exactly what am after.
created(event) {
this.input = event.target.dataset.token
},
You are contradicting yourself here.
@hector-humberto thanx for hacky way around, but again not what i was after
Not sure how you interpret my code as hacky. Seems pretty clean to me.
@HerringtonDarkholme:
Also @hector-humberto 's approach is a standard way for SSR. See https://github.com/vuejs/vue-hackernews-2.0 for example.
It's not exactly what SSR does. I'm only prerendering the JSON data. It's essentially the same as initially doing an AJAX call before rendering the component. The actual html is still generated client-side.
@sirlancelot 's suggestion does exactly what your proposed solution does:
mounted () {
this.input = this.$el.dataset.token
}
The created hook by definition is called before the component's DOM is rendered.
@HerringtonDarkholme thanx for the clarification example 👍 .
@hector-humberto hacky in a way that we first bind the value to the window, then we call it from vue.
where instead i was looking more into binding the data to the input itself and call it from vue, which as you & @yyx990803 said its @sirlancelot solution is the correct one which for some strange reason last night was giving me error :cold_sweat: when trying this.$el.dataset.token and now its working.
still am more than thankful for all your help ❤️ .
No problem, brother.
on a sidenote, if anyone could plz tell me why when using watch() with mounted() it gives an error ?
here is the code
export default {
props:['hasErrors'],
components: {
'FormErrors': require('./Errors.vue')
},
data() {
return {
input: ''
}
},
mounted () { // get the hidden inputs value
if (this.$el.type == 'hidden') {
this.input = this.$el.value
}
},
watch: { // send data to the central storage to be picked up by the parent
input(val, oldVal) {
storage.data.userInfo[event.target.name] = val;
}
},
}
and the error Cannot read property 'target' of undefined
there's no event
@posva but if i commented out the mounted() it works without any issues, unfortunately i dont know how to replicate that in the fiddle, but try commenting out that part mounted() and the error will vanish.
@posva here are a couple of gifs of the problem
without mounted()
https://cl.ly/3V3p3U2L2I3j/Screen%20Recording%202017-02-01%20at%2007.59%20PM.gif
with
https://cl.ly/3H3p3j3H3n2J/Screen%20Recording%202017-02-01%20at%2008.01%20PM.gif
maybe its a bug or is it intended, not sure
There's no event variable in
input(val, oldVal) {
storage.data.userInfo[event.target.name] = val;
}
That's the js error
i understand, but why when mounted() is left off , the event is magically available ?
Because you set value input in mounted, so watch is executed. If you comment mounted out, watch will not run. It just hides the error, not magically cures the error.
If you have extended problem. Asking on gitter is more suitable. GitHub issue is for bug reporting and feature request.
@HerringtonDarkholme i know about gitter but you are wrong about the mounted & watch
@ctf0 Sorry, but @HerringtonDarkholme is right.
in your watch, you try to acess a variable called event, which is globally available only during a browser(!) event callback, (i.e. started by a click event - but only in some browsers, so generally a bad idea to use it).
So when the watch is called because of a change that was initiated by the user (i.e. by clicking on some button), then it is available.
But in the code you provided above, the watch method is triggered by the data change that is resulting from the code in mounted(), there is no event, or in other words: event is undefined - hence: Cannot read property 'target' of undefined.
And that makes sense of course. Since there was no user event, what type of event is event supposed to contain?