Vue js 在输入字段中对 v-model 应用过滤器
Vue js apply filter on v-model in an input field
希望有人能帮助我!我已经制定了一个包装 Jasny Bootstrap 插件的指令,更具体地说是输入掩码,一切顺利!
现在我做了一个moment支持的自定义过滤器来格式化日期字段!
我从后端应用程序收到的日期格式是 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!只有在我开始输入内容后它才能正常工作!
当您最初获得值时,调整它以适合输入。我让它在 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,"/");
}
您可能还必须在备份到数据库的过程中执行类似的操作。
我明白你想做什么,但是,由于使用 v-model 时有两种绑定方式,最好只在从服务器接收日期时格式化日期,然后再使用它在您的前端应用程序中使用所需的格式 ('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's 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');
}
}
});
这对我来说效果很好,希望对您有所帮助。
这是一个fiddle:
https://jsfiddle.net/crabbly/xoLwkog9/
语法更新:
...
methods: {
getDataFromServer() {
// Ajax call to get data from server
// Let's 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')
}
}
})
当我想将输入值大写时,我遇到了类似的问题。
这就是我最后做的事情:
// 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"
做的一样。但是当然,你不能那样做。
总而言之:制作一个 转换数据的指令,而不是过滤器。
这就是我使用 watch 回调为 v-model 实现 vue 过滤器的方式,这不会在加载时更新值。
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);
},
}
我发现我可以使用普通组件 v-bind:value
/ v-on:input
dance 过滤输入,而无需诉诸 data
或 watch
子句,如果我只是调用 $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>
转到 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-model 功能。
模板
<input type="text" v-model="date" @change="onDateChange">
组件
methods: {
onDateChange(event) {
this.myDate = event.target.value
}
getFormatedDate(date) {
return '2020/08/19'
}
},
computed: {
date() {
return this.getFormatedDate(this.myDate)
}
}
我想提供一个替代方案,使用 Vue 指令的钩子更新
export default {
data() {
return {
someData: '',
}
},
directives: {
lowercase: {
update(el) {
el.value = el.value.toLowerCase()
},
},
uppercase: {
update(el) {
el.value = el.value.toUpperCase()
},
},
capitalize: {
update(el) {
const lowerCase = el.value.toLowerCase()
el.value = lowerCase.charAt(0).toUpperCase() + lowerCase.slice(1)
},
},
},
}
或
Vue.directive('lowercase', {
update(el) {
el.value = el.value.toLowerCase()
}
})
Vue.directive('uppercase', {
update(el) {
el.value = el.value.toUpperCase()
}
})
Vue.directive('capitalize', {
update(el) {
const lowerCase = el.value.toLowerCase()
el.value = lowerCase.charAt(0).toUpperCase() + lowerCase.slice(1)
}
})
<input type="text" v-model="someData" v-capitalize />
使用值绑定文本字段
示例:
<v-text-field :value="string | stringFormat"></v-text-field>
希望有人能帮助我!我已经制定了一个包装 Jasny Bootstrap 插件的指令,更具体地说是输入掩码,一切顺利!
现在我做了一个moment支持的自定义过滤器来格式化日期字段!
我从后端应用程序收到的日期格式是 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!只有在我开始输入内容后它才能正常工作!
当您最初获得值时,调整它以适合输入。我让它在 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,"/");
}
您可能还必须在备份到数据库的过程中执行类似的操作。
我明白你想做什么,但是,由于使用 v-model 时有两种绑定方式,最好只在从服务器接收日期时格式化日期,然后再使用它在您的前端应用程序中使用所需的格式 ('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's 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');
}
}
});
这对我来说效果很好,希望对您有所帮助。
这是一个fiddle:
https://jsfiddle.net/crabbly/xoLwkog9/
语法更新:
...
methods: {
getDataFromServer() {
// Ajax call to get data from server
// Let's 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')
}
}
})
当我想将输入值大写时,我遇到了类似的问题。
这就是我最后做的事情:
// 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"
做的一样。但是当然,你不能那样做。
总而言之:制作一个 转换数据的指令,而不是过滤器。
这就是我使用 watch 回调为 v-model 实现 vue 过滤器的方式,这不会在加载时更新值。
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);
},
}
我发现我可以使用普通组件 v-bind:value
/ v-on:input
dance 过滤输入,而无需诉诸 data
或 watch
子句,如果我只是调用 $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>
转到 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-model 功能。
模板
<input type="text" v-model="date" @change="onDateChange">
组件
methods: {
onDateChange(event) {
this.myDate = event.target.value
}
getFormatedDate(date) {
return '2020/08/19'
}
},
computed: {
date() {
return this.getFormatedDate(this.myDate)
}
}
我想提供一个替代方案,使用 Vue 指令的钩子更新
export default {
data() {
return {
someData: '',
}
},
directives: {
lowercase: {
update(el) {
el.value = el.value.toLowerCase()
},
},
uppercase: {
update(el) {
el.value = el.value.toUpperCase()
},
},
capitalize: {
update(el) {
const lowerCase = el.value.toLowerCase()
el.value = lowerCase.charAt(0).toUpperCase() + lowerCase.slice(1)
},
},
},
}
或
Vue.directive('lowercase', {
update(el) {
el.value = el.value.toLowerCase()
}
})
Vue.directive('uppercase', {
update(el) {
el.value = el.value.toUpperCase()
}
})
Vue.directive('capitalize', {
update(el) {
const lowerCase = el.value.toLowerCase()
el.value = lowerCase.charAt(0).toUpperCase() + lowerCase.slice(1)
}
})
<input type="text" v-model="someData" v-capitalize />
使用值绑定文本字段 示例:
<v-text-field :value="string | stringFormat"></v-text-field>