如何转换一长串'手表'转换为VueJS中的功能方式



我是vueJS的新手。我有一长串观察名单。一切都一样。但我不知道如何将它们转换成一种功能性的方式。

它们都是为了在输入标记和v-model中添加逗号。它工作得很好。但这些代码看起来非常愚蠢,因为它们完全相同,但不是它们的名字。

new Vue({
data: {
tmp_price1: '',
tmp_price2: '',
tmp_price3: '',
tmp_a_price: '',
tmp_b_price: '',
},
watch: {
tmp_price1: function(newValue) {
if (newValue != '') {
const result = newValue.replace(/D/g, "").replace(/B(?=(d{3})+(?!d))/g, ",");
Vue.nextTick(() => this.tmp_price1 = result);
}
},
tmp_price2: function(newValue) {
if (newValue != '') {
const result = newValue.replace(/D/g, "").replace(/B(?=(d{3})+(?!d))/g, ",");
Vue.nextTick(() => this.tmp_price2 = result);
}
},
....(repeat)
},

请帮助我改进这些愚蠢的代码的有效方式。

这可能看起来过于工程化,但我可能会制作一个组件来封装通信行为。组件中会有一个可设置的计算值,它会发出供父级在更新时使用的命令值。

new Vue({
el: '#app',
data: {
tmp_price1: '',
tmp_price2: '',
tmp_price3: '',
tmp_a_price: '',
tmp_b_price: '',
},
components: {
commafiedInput: {
props: ['value'],
template: '<input v-model="commaValue">',
computed: {
commaValue: {
get() {
return this.value;
},
set(newValue) {
this.$emit('input', this.addCommas(newValue));
}
}
},
methods: {
addCommas(v) {
return v.replace(/D/g, '').replace(/B(?=(d{3})+(?!d))/g, ",");
}
}
}
}
});
<script src="https://unpkg.com/vue@latest/dist/vue.js"></script>
<div id="app">
<div> {{tmp_price1}}
<commafied-input v-model="tmp_price1"></commafied-input>
</div>
<commafied-input v-model="tmp_price2"></commafied-input>
<commafied-input v-model="tmp_price3"></commafied-input>
<commafied-input v-model="tmp_a_price"></commafied-input>
<commafied-input v-model="tmp_b_price"></commafied-input>
</div>

只需使用一个简单的过滤器即可显示值的格式化版本:

new Vue({
el: '#app',
data: {
tmp_price1: '123123',
tmp_price2: '',
tmp_price3: ''
},
filters: {
myFilter(v) {
return v.replace(/D/g, '').replace(/B(?=(d{3})+(?!d))/g, ",");
}   
}
});
<script src="https://unpkg.com/vue@latest/dist/vue.js"></script>
<div id="app">
<div><input v-model="tmp_price1">{{tmp_price1 | myFilter}}</div>
<div><input v-model="tmp_price2">{{tmp_price2 | myFilter}}</div>
<div><input v-model="tmp_price3">{{tmp_price3 | myFilter}}</div>

</div>

但这对于输入字段来说还不够;不能只在v-model属性上添加一个筛选器。Roy J的回答中描述的子组件可能是处理这一问题的最佳和最可重复使用的方法,但如果你可以处理一些有点快和脏的东西(但不是脏),你可以用一个更改处理程序来处理这个问题:

new Vue({
el: '#app',
data: {
tmp_price1: '123123',
tmp_price2: '',
tmp_price3: ''
},
methods: {
myFormatter(fieldname) {
/* replace the user's input with the formatted value.

There's probably some clever way to read the v-model 
name from the input field instead of passing it to the 
method as a string, but I'm not going to mess around 
with that for what is after all a quick-and-dirty technique */
this[fieldname] = this[fieldname].replace(/D/g, "").replace(/B(?=(d{3})+(?!d))/g, ",");
}
},
mounted() {
// if the initial values aren't always empty, you'll need to run the
// formatter function on component load as well as on user input:
['tmp_price1', 'tmp_price2', 'tmp_price3'].forEach(f => {
this.myFormatter(f);
});
}
});
<script src="https://unpkg.com/vue@latest/dist/vue.js"></script>
<div id="app">
<div><input v-model="tmp_price1" @input="myFormatter('tmp_price1')">{{tmp_price1}}</div>
<div><input v-model="tmp_price2" @input="myFormatter('tmp_price2')">{{tmp_price2}}</div>
<div><input v-model="tmp_price3" @input="myFormatter('tmp_price3')">{{tmp_price3}}</div>
</div>

(或者作为另一种变体,这个类似问题的答案使用了基本相同的技术,但将其封装在Vue指令中,以绑定输入事件,而不是附加@input处理程序。)

请注意,在"过滤器"版本中,v-model值保持原始用户输入;过滤器仅影响显示的值。在第二个示例中,格式化应用于v-modeled值本身,因此如果将这些值传递到其他地方,则会得到格式化的版本。根据具体情况,这两种技术都可能有用。(或者,你甚至可以将它们组合使用——例如,删除v模型中的非数字,然后通过过滤器添加逗号以供显示。)

最新更新