Vue.js 表格没有反应
Vue.js form not reactive
所以我有一个简单的计算器。用户选择字体,然后选择大小,然后通过输入单词,计算价格。
问题是此表单中的某些元素不是反应性的,对于术语我是新手感到抱歉Vue.js。
这是我的 HTML
<div id="app">
<ul>
<li v-for="font in fontTypes" v-on:click="fontType(font)">{{ font.name }}</li>
</ul>
<ul>
<li v-for="currentFont in currentFonts" v-on:click="fontSize(currentFont)">{{ currentFont.size }}</li>
</ul>
<input type="text" v-model="result">
<div id="result">
<p>{{ finalPrice }}</p>
</div>
</div>
这是 JS:
var formatter = new Intl.NumberFormat('lt-LT', {
style: 'currency',
currency: 'EUR',
minimumFractionDigits: 2
});
var vm = new Vue({
el: '#app',
data: {
result: '',
currentFonts: '',
selectedFont: '',
selectedSize: '',
selectedFontSizePrice: '',
fontTypes: [
{ name: 'Font 1', params: [ {size: '2.5', price: '3.10'}, {size: '3', price: '5'} ] },
{ name: 'Font 2', params: [ {size: '3', price: '4'}, {size: '4', price: '7'} ] },
{ name: 'Font 3', params: [ {size: '7', price: '45'}, {size: '8', price: '50'} ] }
]
},
computed: {
finalPrice: function() {
var letterCount = this.result.replace(/\s/g, "").length;
var letterPrice = this.selectedFontSizePrice;
var price = letterCount * letterPrice;
return formatter.format(price);
}
},
methods: {
fontType: function(selectedFont) {
this.selectedFont = selectedFont.name;
this.currentFonts = selectedFont.params;
},
fontSize: function(selectedSize) {
this.selectedSize = selectedSize.size;
this.selectedFontSizePrice = selectedSize.price;
}
}
});
selectedFontSizePrice 不是反应式的。当我更改字体时 (selectedFont) selectedFontSizePrice 保持不变。如果父 selector 发生变化,我需要某种清算,甚至更好 select 列表中的第一个值并重新计算 finalPrice。或者也许我在这里做错了什么?
不确定我是否理解问题,但是如果您想在 select 时更新 'selectedFontSizePrice' 值 fontType,我觉得你应该调用函数fontSize(据我所知是修改'selectedFontSizePrice') 从函数内部 fontType
methods: {
fontType: function(selectedFont) {
this.selectedFont = selectedFont.name;
this.currentFonts = selectedFont.params;
this.fontSize(selectedFont.params[0]); //select first value
},
fontSize: function(selectedSize) {
this.selectedSize = selectedSize.size;
this.selectedFontSizePrice = selectedSize.price;
}
}
Vue 允许您做的事情之一就是轻松编写自己的组件。看起来有人通常会使用 select 元素,而您选择使用无序列表元素。通过定义一个小的 Vue 组件,您可以轻松地编写自己的无序列表元素 表现得像 select。
Vue.component('list-select', {
props: ["items"],
template:"<ul class='list-select'><li :class='selectClass(item)' v-for='item in items' :value='item.value' @click='onClick(item)'>{{item.text}}</li>",
data(){
return {
value: null,
selectedItem: null
}
},
methods:{
selectClass(item){
return {
selected: item == this.selectedItem
}
},
onClick(item){
this.selectedItem = item;
this.$emit('input', item.value);
}
}
});
然后,你就可以在你的Vue中使用这个组件了。
<div id="app">
<list-select :items="types" v-model="selectedFont" @input="selectedSize = null"></list-select>
<list-select v-if="selectedFont" :items="sizes" v-model="selectedPrice"></list-select>
<input type="text" v-model="result">
<div id="result">
<p>{{ finalPrice }}</p>
</div>
</div>
这是 Vue 定义。
var vm = new Vue({
el: '#app',
data: {
result: '',
selectedFont: null,
selectedPrice: null,
fontTypes: [
{ name: 'Font 1', params: [ {size: '2.5', price: '3.10'}, {size: '3', price: '5'} ] },
{ name: 'Font 2', params: [ {size: '3', price: '4'}, {size: '4', price: '7'} ] },
{ name: 'Font 3', params: [ {size: '7', price: '45'}, {size: '8', price: '50'} ] }
]
},
computed: {
types(){
return this.fontTypes.map((type) => {
return {text: type.name, value: type.params};
});
},
sizes(){
return this.selectedFont.map((size) => {
return {text: size.size, value: size.price};
});
},
finalPrice: function() {
if (this.result.length <= 0)
return formatter.format(0);
var letterCount = this.result.replace(/\s/g, "").length;
return formatter.format(letterCount * this.selectedPrice);
}
}
});
这种方法使一切都完全响应并以惯用的方式使用 Vue。 Here is a working example.
更改此方法:
fontType: function(selectedFont) {
this.selectedFont = selectedFont.name;
this.currentFonts = selectedFont.params;
}
至:
fontType: function(selectedFont) {
this.selectedFont = selectedFont.name;
this.currentFonts = [];
selectedFont.params.forEach(function(p){
this.currentFonts.push(p);
}.bind(this));
}
数组只是不响应“=”操作。
所以我有一个简单的计算器。用户选择字体,然后选择大小,然后通过输入单词,计算价格。
问题是此表单中的某些元素不是反应性的,对于术语我是新手感到抱歉Vue.js。
这是我的 HTML
<div id="app">
<ul>
<li v-for="font in fontTypes" v-on:click="fontType(font)">{{ font.name }}</li>
</ul>
<ul>
<li v-for="currentFont in currentFonts" v-on:click="fontSize(currentFont)">{{ currentFont.size }}</li>
</ul>
<input type="text" v-model="result">
<div id="result">
<p>{{ finalPrice }}</p>
</div>
</div>
这是 JS:
var formatter = new Intl.NumberFormat('lt-LT', {
style: 'currency',
currency: 'EUR',
minimumFractionDigits: 2
});
var vm = new Vue({
el: '#app',
data: {
result: '',
currentFonts: '',
selectedFont: '',
selectedSize: '',
selectedFontSizePrice: '',
fontTypes: [
{ name: 'Font 1', params: [ {size: '2.5', price: '3.10'}, {size: '3', price: '5'} ] },
{ name: 'Font 2', params: [ {size: '3', price: '4'}, {size: '4', price: '7'} ] },
{ name: 'Font 3', params: [ {size: '7', price: '45'}, {size: '8', price: '50'} ] }
]
},
computed: {
finalPrice: function() {
var letterCount = this.result.replace(/\s/g, "").length;
var letterPrice = this.selectedFontSizePrice;
var price = letterCount * letterPrice;
return formatter.format(price);
}
},
methods: {
fontType: function(selectedFont) {
this.selectedFont = selectedFont.name;
this.currentFonts = selectedFont.params;
},
fontSize: function(selectedSize) {
this.selectedSize = selectedSize.size;
this.selectedFontSizePrice = selectedSize.price;
}
}
});
selectedFontSizePrice 不是反应式的。当我更改字体时 (selectedFont) selectedFontSizePrice 保持不变。如果父 selector 发生变化,我需要某种清算,甚至更好 select 列表中的第一个值并重新计算 finalPrice。或者也许我在这里做错了什么?
不确定我是否理解问题,但是如果您想在 select 时更新 'selectedFontSizePrice' 值 fontType,我觉得你应该调用函数fontSize(据我所知是修改'selectedFontSizePrice') 从函数内部 fontType
methods: {
fontType: function(selectedFont) {
this.selectedFont = selectedFont.name;
this.currentFonts = selectedFont.params;
this.fontSize(selectedFont.params[0]); //select first value
},
fontSize: function(selectedSize) {
this.selectedSize = selectedSize.size;
this.selectedFontSizePrice = selectedSize.price;
}
}
Vue 允许您做的事情之一就是轻松编写自己的组件。看起来有人通常会使用 select 元素,而您选择使用无序列表元素。通过定义一个小的 Vue 组件,您可以轻松地编写自己的无序列表元素 表现得像 select。
Vue.component('list-select', {
props: ["items"],
template:"<ul class='list-select'><li :class='selectClass(item)' v-for='item in items' :value='item.value' @click='onClick(item)'>{{item.text}}</li>",
data(){
return {
value: null,
selectedItem: null
}
},
methods:{
selectClass(item){
return {
selected: item == this.selectedItem
}
},
onClick(item){
this.selectedItem = item;
this.$emit('input', item.value);
}
}
});
然后,你就可以在你的Vue中使用这个组件了。
<div id="app">
<list-select :items="types" v-model="selectedFont" @input="selectedSize = null"></list-select>
<list-select v-if="selectedFont" :items="sizes" v-model="selectedPrice"></list-select>
<input type="text" v-model="result">
<div id="result">
<p>{{ finalPrice }}</p>
</div>
</div>
这是 Vue 定义。
var vm = new Vue({
el: '#app',
data: {
result: '',
selectedFont: null,
selectedPrice: null,
fontTypes: [
{ name: 'Font 1', params: [ {size: '2.5', price: '3.10'}, {size: '3', price: '5'} ] },
{ name: 'Font 2', params: [ {size: '3', price: '4'}, {size: '4', price: '7'} ] },
{ name: 'Font 3', params: [ {size: '7', price: '45'}, {size: '8', price: '50'} ] }
]
},
computed: {
types(){
return this.fontTypes.map((type) => {
return {text: type.name, value: type.params};
});
},
sizes(){
return this.selectedFont.map((size) => {
return {text: size.size, value: size.price};
});
},
finalPrice: function() {
if (this.result.length <= 0)
return formatter.format(0);
var letterCount = this.result.replace(/\s/g, "").length;
return formatter.format(letterCount * this.selectedPrice);
}
}
});
这种方法使一切都完全响应并以惯用的方式使用 Vue。 Here is a working example.
更改此方法:
fontType: function(selectedFont) {
this.selectedFont = selectedFont.name;
this.currentFonts = selectedFont.params;
}
至:
fontType: function(selectedFont) {
this.selectedFont = selectedFont.name;
this.currentFonts = [];
selectedFont.params.forEach(function(p){
this.currentFonts.push(p);
}.bind(this));
}
数组只是不响应“=”操作。