如何将一长串 'watch' 转换为 VueJS 中的函数式方式?
How can I convert a long list of 'watch' into a functional way in VueJS?
我是vueJS的新手。
我有一长串观察名单。都是一样的。
但是我不知道如何将它们转换成函数式的方式。
都是为了在input标签和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
属性添加过滤器。 中描述的子组件可能是处理该问题的最佳和最可重用的方法,但如果你对一些快速和肮脏的东西没问题(但不是 too 脏)你可以在问题上抛出一个更改处理程序:
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
处理程序。)
请注意,在 "filter" 版本中,v-model
值保留为原始用户输入;过滤器只影响显示的值。在第二个示例中,格式应用于 v-model
ed 值本身,因此如果您将这些值传递到其他地方,您将获得格式化版本。这两种技术都可能有用,具体取决于具体情况。 (或者您甚至可以组合使用它们——例如,删除 v 模型中的非数字,然后通过过滤器添加逗号以仅用于显示。)
我是vueJS的新手。 我有一长串观察名单。都是一样的。 但是我不知道如何将它们转换成函数式的方式。
都是为了在input标签和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
属性添加过滤器。
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>
(或者作为另一个变体,@input
处理程序。)
请注意,在 "filter" 版本中,v-model
值保留为原始用户输入;过滤器只影响显示的值。在第二个示例中,格式应用于 v-model
ed 值本身,因此如果您将这些值传递到其他地方,您将获得格式化版本。这两种技术都可能有用,具体取决于具体情况。 (或者您甚至可以组合使用它们——例如,删除 v 模型中的非数字,然后通过过滤器添加逗号以仅用于显示。)