如何在 Vue.js 应用程序中共享 "computed" 方法
How to share "computed" methods across a Vue.js application
我有一个加载项目列表的 Vue.js 应用程序,每个项目都作为 prop
传递给 Vue 组件。
我发现通过使用 mixins
我可以共享公共组件属性,例如 computed
、created
等
现在,我正在尝试对项目列表进行排序,但无法弄清楚如何访问每个组件的计算属性以应用 sorting/filtering。我怎样才能做到这一点?
项
[{
price: 10,
qty: 2
}, {
price: 8,
qty: 3
}]
Mixin-./Cost.js
export default {
computed: {
cost () {
return this.price * this.qty;
}
}
}
组件(按预期工作)- ./Product.vue
import Cost from './Cost.js'
export default {
name: 'product-item',
props: ['product'],
mixins: [Cost]
}
How would you access the computed properties, or restructure this setup?
列表组件
<template>
<div id="list">
<div v-for="product in sorted" :product="product">Cost: {{ cost }} </div>
</div>
</template>
<script>
import ProductItem from './Product.vue'
export default {
components: { ProductItem },
created: () {
this.items = [...] // as noted above
},
computed: {
sorted () {
return this.items.sort( (a,b) => b.cost - a.cost); // cost is not accessible!
}
}
}
</script>
正如@Sphinx 所建议的,您可以使用 ref
来访问子组件。
例如:
<template>
<div id="list">
<product-item v-for="product in sorted" :product="product" :ref="product"></product-item>
</div>
</template>
<script>
import ProductItem from './Product.vue'
export default {
components: { ProductItem },
data: () => ({
hidrated: false,
items: []
})
created() {
this.items = [...] // as noted above
},
mounted() {
this.hidrated = true
},
computed: {
sorted () {
if (!this.hidrated && !Object.keys(this.$refs).length) {
// handle initial state, before rendered
return this.items
}
return Object.values(this.$refs)[0]
.sort((a,b) => b.cost - a.cost)
.map(c => c.product)
}
}
}
</script>
这是假设您的 List Component
中没有其他 ref
。
你还必须先检查组件是否被渲染,这里我使用hidrated
来标记组件何时被挂载。
使用vuex
。您的 vuex store
将提供一个 getters
对象,该对象可以包装到多个组件的本机 computed
对象中,或直接访问。您的代码将是 DRY、反应式、缓存和可维护的。
根据我的经验,一旦您需要超越 child-parent
数据关系,vuex
、store
和 shared state
就是可行的方法。一旦你掌握了它,你的应用程序的发展就会变得非常神奇。
显示如何安装 vuex
超出了问题的范围。访问 https://vuex.vuejs.org/guide/getters.html 以了解 getter 与计算属性的相似之处,以及在组件之间共享的价值。官方 Vuex 指南还将演示如何使用商店初始化 Vue 实例。
这里有一些片段向您展示了vuex
系统中的演员。
存储和状态
// state definition (basically a shared reactive 'data' object that lives outside components)
state:{
message:'Hello'
}
// the store getters are declared as methods and accessed as properties (just like component/computed)
getters:{
message: state => return state.message
}
从组件访问
// component 1 wraps getter
computed:{
message(){
return this.$store.getters.message
}
}
// component 2 also wraps getter
computed:{
message(){
return this.$store.getters.message
}
}
// templates can also use getters directly
<div>{{$store.getters.message}}</div>
// If message was wrapped, you can simply use the computed property
<div>{{message}}</div>
一旦您开始使用 vuex
,各种其他宝藏就会开始出现,例如 Chrome 中的开发者工具、undo/redo 支持、简单的状态重构、时间-旅行调试、应用程序持久性等。还有一些快捷方式可以将多个商店 getter 添加到您的计算属性中。
我有一个加载项目列表的 Vue.js 应用程序,每个项目都作为 prop
传递给 Vue 组件。
我发现通过使用 mixins
我可以共享公共组件属性,例如 computed
、created
等
现在,我正在尝试对项目列表进行排序,但无法弄清楚如何访问每个组件的计算属性以应用 sorting/filtering。我怎样才能做到这一点?
项
[{
price: 10,
qty: 2
}, {
price: 8,
qty: 3
}]
Mixin-./Cost.js
export default {
computed: {
cost () {
return this.price * this.qty;
}
}
}
组件(按预期工作)- ./Product.vue
import Cost from './Cost.js'
export default {
name: 'product-item',
props: ['product'],
mixins: [Cost]
}
How would you access the computed properties, or restructure this setup?
列表组件
<template>
<div id="list">
<div v-for="product in sorted" :product="product">Cost: {{ cost }} </div>
</div>
</template>
<script>
import ProductItem from './Product.vue'
export default {
components: { ProductItem },
created: () {
this.items = [...] // as noted above
},
computed: {
sorted () {
return this.items.sort( (a,b) => b.cost - a.cost); // cost is not accessible!
}
}
}
</script>
正如@Sphinx 所建议的,您可以使用 ref
来访问子组件。
例如:
<template>
<div id="list">
<product-item v-for="product in sorted" :product="product" :ref="product"></product-item>
</div>
</template>
<script>
import ProductItem from './Product.vue'
export default {
components: { ProductItem },
data: () => ({
hidrated: false,
items: []
})
created() {
this.items = [...] // as noted above
},
mounted() {
this.hidrated = true
},
computed: {
sorted () {
if (!this.hidrated && !Object.keys(this.$refs).length) {
// handle initial state, before rendered
return this.items
}
return Object.values(this.$refs)[0]
.sort((a,b) => b.cost - a.cost)
.map(c => c.product)
}
}
}
</script>
这是假设您的 List Component
中没有其他 ref
。
你还必须先检查组件是否被渲染,这里我使用hidrated
来标记组件何时被挂载。
使用vuex
。您的 vuex store
将提供一个 getters
对象,该对象可以包装到多个组件的本机 computed
对象中,或直接访问。您的代码将是 DRY、反应式、缓存和可维护的。
根据我的经验,一旦您需要超越 child-parent
数据关系,vuex
、store
和 shared state
就是可行的方法。一旦你掌握了它,你的应用程序的发展就会变得非常神奇。
显示如何安装 vuex
超出了问题的范围。访问 https://vuex.vuejs.org/guide/getters.html 以了解 getter 与计算属性的相似之处,以及在组件之间共享的价值。官方 Vuex 指南还将演示如何使用商店初始化 Vue 实例。
这里有一些片段向您展示了vuex
系统中的演员。
存储和状态
// state definition (basically a shared reactive 'data' object that lives outside components)
state:{
message:'Hello'
}
// the store getters are declared as methods and accessed as properties (just like component/computed)
getters:{
message: state => return state.message
}
从组件访问
// component 1 wraps getter
computed:{
message(){
return this.$store.getters.message
}
}
// component 2 also wraps getter
computed:{
message(){
return this.$store.getters.message
}
}
// templates can also use getters directly
<div>{{$store.getters.message}}</div>
// If message was wrapped, you can simply use the computed property
<div>{{message}}</div>
一旦您开始使用 vuex
,各种其他宝藏就会开始出现,例如 Chrome 中的开发者工具、undo/redo 支持、简单的状态重构、时间-旅行调试、应用程序持久性等。还有一些快捷方式可以将多个商店 getter 添加到您的计算属性中。