Vue js применяет фильтр к v-модели в поле ввода
Надеюсь, кто-то может мне помочь! Я сделал директиву, вставляя Jasny Bootstrap Plugin более конкретно в маску ввода-маски, и все идет хорошо!
Теперь я создал настраиваемый фильтр, поддерживаемый моментом, чтобы отформатировать поле даты!
Формат даты, который я получаю от моего бэкэнд-приложения, - это YYY-MM-DD, и я должен показать его в виде DD/MM/YYYY... Я пробовал v-model="date | myDate"
, но это не сработало!
JS
Vue.directive('input-mask', {
params: ['mask'],
bind: function() {
$(this.el).inputmask({
mask: this.params.mask
});
},
});
Vue.filter('my-date', function(value, formatString) {
if (value != undefined)
return '';
if (formatString != undefined)
return moment(value).format(formatString);
return moment(value).format('DD/MM/YYYY');
});
var vm = new Vue({
el: 'body',
data: {
date: '2015-06-26',
}
});
HTML
<label>Date</label>
<input type="text" class="form-control" v-input-mask mask="99/99/9999" v-model="date">
<p>{{ date | myDate 'dd/mm/yyyy' }}</p>
Существует JSBin, если кто-то заинтересован!
Спасибо заранее!
РЕДАКТИРОВАТЬ: лучше объяснять, что я ожидаю =)
Когда на первой странице загрузки вход получает значение 2015-06-26, и я хотел бы показать это значение как DD/MM/YYYY, так 26/06/2015! Он работает правильно только после того, как я начну вводить что-то!
Ответы
Ответ 1
Я понимаю, что вы пытаетесь сделать, однако из-за двухстороннего связывания при использовании v-модели может быть лучше просто отформатировать дату, когда вы получаете ее с сервера, а затем использовать ее в нужном формате в ваше внешнее приложение ('DD/MM/YYYY'
).
Отправляя данные обратно на сервер, вы просто форматируете их обратно в нужный формат сервера ('YYYY-MM-DD'
).
В вашем приложении Vue рабочий процесс будет выглядеть примерно так:
new Vue({
el: 'body',
data: {
date: null,
},
methods: {
getDataFromServer: function() {
// Ajax call to get data from server
// Let pretend the received date data was saved in a variable (serverDate)
// We will hardcode it for this ex.
var serverDate = '2015-06-26';
// Format it and save to vue data property
this.date = this.frontEndDateFormat(serverDate);
},
saveDataToServer: function() {
// Format data first before sending it back to server
var serverDate = this.backEndDateFormat(this.date);
// Ajax call sending formatted data (serverDate)
},
frontEndDateFormat: function(date) {
return moment(date, 'YYYY-MM-DD').format('DD/MM/YYYY');
},
backEndDateFormat: function(date) {
return moment(date, 'DD/MM/YYYY').format('YYYY-MM-DD');
}
}
});
Это хорошо работает для меня, надеюсь, это поможет.
Вот скрипка для этого:
https://jsfiddle.net/crabbly/xoLwkog9/
Синтаксис ОБНОВЛЕНИЕ:
...
methods: {
getDataFromServer() {
// Ajax call to get data from server
// Let pretend the received date data was saved in a variable (serverDate)
// We will hardcode it for this ex.
const serverDate = '2015-06-26'
// Format it and save to vue data property
this.date = this.frontEndDateFormat(serverDate)
},
saveDataToServer() {
// Format data first before sending it back to server
const serverDate = this.backEndDateFormat(this.date)
// Ajax call sending formatted data (serverDate)
},
frontEndDateFormat(date) {
return moment(date, 'YYYY-MM-DD').format('DD/MM/YYYY')
},
backEndDateFormat(date) {
return moment(date, 'DD/MM/YYYY').format('YYYY-MM-DD')
}
}
})
Ответ 2
У меня была аналогичная проблема, когда я хотел загладить введенное значение.
Вот что я сделал:
// create a directive to transform the model value
Vue.directive('uppercase', {
twoWay: true, // this transformation applies back to the vm
bind: function () {
this.handler = function () {
this.set(this.el.value.toUpperCase());
}.bind(this);
this.el.addEventListener('input', this.handler);
},
unbind: function () {
this.el.removeEventListener('input', this.handler);
}
});
Тогда я могу использовать эту директиву в поле ввода с v-model
.
<input type="text" v-model="someData" v-uppercase="someData">
Теперь, всякий раз, когда я ввожу в это поле или изменяю someData
, значение преобразуется в верхний регистр.
Это по существу делало то же самое, что я надеялся v-model="someData | uppercase"
. Но, конечно, вы не можете этого сделать.
В суммировании: создайте директиву, которая преобразует данные, а не фильтр.
Ответ 3
Когда вы сначала получите значение, отрегулируйте его, чтобы он соответствовал входу. Я получил его в функции ready
, но вы могли бы это сделать и после вызова БД:
ready: function(){
var year = this.date.substr(0, 4);
var monDay = this.date.substr(5,5);
var result = monDay + "-" + year;
this.date = result.replace(/-/g,"/");
}
Возможно, вам придется сделать что-то подобное по пути обратно в вашу базу данных.
Ответ 4
Вот как я реализовал фильтр vue для v-модели, используя обратный вызов watch, это не будет обновлять значение при загрузке.
Vue.filter('uppercase', function (value) {
return value.toUpperCase();
});
HTML:
<input type="text" v-model="someData">
И обратный вызов часов:
watch:{
someData(val) {
this.someData = this.$options.filters.uppercase(val);
},
}
Ответ 5
Перейдите в main.js и добавьте следующий код:
import moment from 'moment'
Vue.filter('myDate', function (value) {
if (value) {
return moment(String(value)).format('dd/mm/yyyy')
}
});
В своем HTML сделайте следующее:
<label>Date</label>
<v-text-field :value="date | myDate" @input="value=>date=value"></v-text-field>
<p>{{ date | myDate 'dd/mm/yyyy' }}</p>
Итак, мы использовали выше v-bind, чтобы связать значение и обработчик события @input, чтобы иметь функциональность v-модели.
Ответ 6
Я обнаружил, что могу фильтровать ввод, используя обычный компонент v-bind:value
/v-on:input
dance, не прибегая к $forceUpdate()
data
или watch
если я просто вызываю $forceUpdate()
после $forceUpdate()
отфильтрованного значения:
Компонент Vue:
{
props: ['value'],
methods: {
mEmit: function(EVT) {
const VAL = EVT.target.value;
var FILTERED = myFilterFunction(VAL);
this.$emit('input', FILTERED);
this.$forceUpdate();
}
}
}
Компонент HTML (данные фильтруются по мере ввода):
<input type="text" v-bind:value="value" v-on:input="mEmit($event)" />
Используя компонент:
<my-component v-model="myDataVar"></my-component>