如何在 Vue.js 中的两个组件之间共享一个方法?
How to share a method between two components in Vue.js?
我有一个 Ag-Grid,它有特定的操作按钮和从 MongoDB 数据库中填充的动态数据。我的 MasterData.Vue 文件中有一个方法可以刷新网格。我的网格记录中的每个操作按钮执行 update/delete 操作。当我单击这些按钮时,我在另一个 Modal.Vue 文件中设计了一个自定义的弹出模式组件。我想在 Modal.Vue 中调用 RefreshGrid() 方法。我尝试使用 props 来共享数据,但同样的方法在方法上不起作用。
MasterData.Vue 脚本
<script>
import { AgGridVue } from 'ag-grid-vue';
import { mapGetters } from 'vuex';
import gridEditButtons from '@/components/GridEditButton';
import MasterModal from '@/components/MasterModal';
export default {
name: 'masterData',
data () {
return {
addBtnClick: false,
delBtnClick: false,
editVisible: false,
selected: 'Business Area',
dropdown_tables: [
'Business Area',
'Council',
'Sub Area',
'Type',
'Work Flow Stage'
],
gridOptions: {
domLayout: 'autoHeight',
enableColumnResize: true,
rowDragManaged: true,
animateRows: true,
context: {
vm: null
}
}
};
},
components: {
'ty-master-modal': MasterModal,
'ag-grid-vue': AgGridVue,
gridEditButtons
},
methods: {
// Filter Grid Contents based on Dropdown selection
RefreshGrid: function () {
let cName;
if (this.selected === 'Business Area') {
cName = 'businessarea';
} else if (this.selected === 'Council') {
cName = 'council';
} else if (this.selected === 'Type') {
cName = 'typemaster';
} else if (this.selected === 'Work Flow Stage') {
cName = 'workflowstage';
}
let obj = {
vm: this,
collectionName: cName,
action: 'masterData/setMasterData',
mutation: 'setMasterData'
};
this.$store.dispatch(obj.action, obj);
}
};
</script>
Modal.Vue 脚本
<script>
import {mapGetters} from 'vuex';
export default {
name: 'MasterModal',
props: {
readOnly: Boolean,
entryData: Object,
addBtnClick: Boolean,
delBtnClick: Boolean,
editVisible: Boolean,
selectedTable: String
},
data () {
return {
fieldAlert: false,
isReadOnly: false,
dialog: false,
dialogDelete: false,
valid: false,
visible: false,
disable: false
};
},
computed: {
...mapGetters('masterData', {
entryState: 'entryState',
// entryData: 'entryData',
columns: 'columns',
selectedRowId: 'selectedRowId'
})
},
watch: {
addBtnClick: function (newValue, oldValue) {
this.setDialog(!this.dialog);
},
editVisible: function (newValue, oldValue) {
this.setVisible(!this.visible);
},
delBtnClick: function (newValue, oldValue) {
this.setDialogDelete(!this.dialogDelete);
}
},
methods: {
setDialog (bValue) {
this.dialog = bValue;
},
setDialogDelete (bValue) {
this.dialogDelete = bValue;
},
}
};
</script>
有几种方法可以实现这一点。
一种是使用emit
在MasterModal.vue组件运行this.$emit('refreshGrid')
在父MasterData.Vue 组件使用 <ty-master-modal @refreshGrid="RefreshGrid" ...>
如果您有直接亲子关系,这可能是最佳选择
另一种方法是将函数作为 prop 传递给子组件。
<ty-master-modal :onRefreshGrid="RefreshGrid" ...>
然后在MasterModal.vue中添加一个属性onRefreshGrid
,就可以调用函数了。
另一种使用 vuex 的方法是向 MasterData.Vue 添加一个 watch 并在 vuex store ie 中监视一个变量。 actionInvoker
。当 actionInvoker
改变时,动作执行。要更改该值,请将其设置为 0 并递增或在两者之间切换,或者设置为随机值。优点是你可以从任何地方调用它。
这个(和以前的)解决方案的问题在于,您的功能与 view/component 相关联,但不应该存在。我会推荐第三种解决方案,即将功能推送到 vuex 操作中,然后您可以从任何地方调用它。这将需要您也将 selected
变量存储在 vuex 中,并且如果您想要拥有多个 Modal 和 Master 组件实例,则单个存储将禁止这样做(除非您添加对多个实例的支持)。
我有一个 Ag-Grid,它有特定的操作按钮和从 MongoDB 数据库中填充的动态数据。我的 MasterData.Vue 文件中有一个方法可以刷新网格。我的网格记录中的每个操作按钮执行 update/delete 操作。当我单击这些按钮时,我在另一个 Modal.Vue 文件中设计了一个自定义的弹出模式组件。我想在 Modal.Vue 中调用 RefreshGrid() 方法。我尝试使用 props 来共享数据,但同样的方法在方法上不起作用。
MasterData.Vue 脚本
<script>
import { AgGridVue } from 'ag-grid-vue';
import { mapGetters } from 'vuex';
import gridEditButtons from '@/components/GridEditButton';
import MasterModal from '@/components/MasterModal';
export default {
name: 'masterData',
data () {
return {
addBtnClick: false,
delBtnClick: false,
editVisible: false,
selected: 'Business Area',
dropdown_tables: [
'Business Area',
'Council',
'Sub Area',
'Type',
'Work Flow Stage'
],
gridOptions: {
domLayout: 'autoHeight',
enableColumnResize: true,
rowDragManaged: true,
animateRows: true,
context: {
vm: null
}
}
};
},
components: {
'ty-master-modal': MasterModal,
'ag-grid-vue': AgGridVue,
gridEditButtons
},
methods: {
// Filter Grid Contents based on Dropdown selection
RefreshGrid: function () {
let cName;
if (this.selected === 'Business Area') {
cName = 'businessarea';
} else if (this.selected === 'Council') {
cName = 'council';
} else if (this.selected === 'Type') {
cName = 'typemaster';
} else if (this.selected === 'Work Flow Stage') {
cName = 'workflowstage';
}
let obj = {
vm: this,
collectionName: cName,
action: 'masterData/setMasterData',
mutation: 'setMasterData'
};
this.$store.dispatch(obj.action, obj);
}
};
</script>
Modal.Vue 脚本
<script>
import {mapGetters} from 'vuex';
export default {
name: 'MasterModal',
props: {
readOnly: Boolean,
entryData: Object,
addBtnClick: Boolean,
delBtnClick: Boolean,
editVisible: Boolean,
selectedTable: String
},
data () {
return {
fieldAlert: false,
isReadOnly: false,
dialog: false,
dialogDelete: false,
valid: false,
visible: false,
disable: false
};
},
computed: {
...mapGetters('masterData', {
entryState: 'entryState',
// entryData: 'entryData',
columns: 'columns',
selectedRowId: 'selectedRowId'
})
},
watch: {
addBtnClick: function (newValue, oldValue) {
this.setDialog(!this.dialog);
},
editVisible: function (newValue, oldValue) {
this.setVisible(!this.visible);
},
delBtnClick: function (newValue, oldValue) {
this.setDialogDelete(!this.dialogDelete);
}
},
methods: {
setDialog (bValue) {
this.dialog = bValue;
},
setDialogDelete (bValue) {
this.dialogDelete = bValue;
},
}
};
</script>
有几种方法可以实现这一点。
一种是使用emit
在MasterModal.vue组件运行this.$emit('refreshGrid')
在父MasterData.Vue 组件使用 <ty-master-modal @refreshGrid="RefreshGrid" ...>
如果您有直接亲子关系,这可能是最佳选择
另一种方法是将函数作为 prop 传递给子组件。
<ty-master-modal :onRefreshGrid="RefreshGrid" ...>
然后在MasterModal.vue中添加一个属性onRefreshGrid
,就可以调用函数了。
另一种使用 vuex 的方法是向 MasterData.Vue 添加一个 watch 并在 vuex store ie 中监视一个变量。 actionInvoker
。当 actionInvoker
改变时,动作执行。要更改该值,请将其设置为 0 并递增或在两者之间切换,或者设置为随机值。优点是你可以从任何地方调用它。
这个(和以前的)解决方案的问题在于,您的功能与 view/component 相关联,但不应该存在。我会推荐第三种解决方案,即将功能推送到 vuex 操作中,然后您可以从任何地方调用它。这将需要您也将 selected
变量存储在 vuex 中,并且如果您想要拥有多个 Modal 和 Master 组件实例,则单个存储将禁止这样做(除非您添加对多个实例的支持)。