处理这个高阶组件的最惯用的 Vue 方法是什么?
What's the most idomatic Vue way of handling this higher-order component?
我有一个 VueJS 组织和架构问题。我有一堆页面用作系统中各个对象的 CRUD 页面。他们共享很多代码。我已经在一个共享组件中抽象了它,但我不喜欢我所做的,我正在寻找有关执行此操作的惯用 Vue 方法的建议。
我正在尝试创建一个接受两个参数的高阶组件:
一个编辑组件,它是每个对象的可编辑视图。因此,您可以将其视为具有 v 模型的文本输入的替代品,接受它有大量不同的输入。
一个列表组件,显示系统中该类型的所有对象的列表。它控制导航以编辑该对象。
通常这只是我使用插槽并在每个 CRUD 对象的视图页面中调用此组件的地方。所以基本上我会有这样的东西:
<!-- this file is src/views/DogsCRUDPage.vue -->
<template>
<general-crud-component
name="dogs"
backendurl="/dogs/"
>
<template slot="list">
<dogs-list-component />
</template>
<template slot="edit">
<dogs-edit-field v-model="... oops .." />
</template>
</general-crud-component>
</template>
<script>
export default {
name: "DogCRUDPage",
components: {
GeneralCrudComponent,
DogListComponent,
DogEditField,
},
}
</script>
这很好,因为它符合我所有其他 VueJS 页面的一般语法以及我如何将道具和东西传递给共享代码。然而,问题在于 GeneralCRUDComponent 处理所有检查对象是否被编辑的机制,并因此隐藏或取消隐藏保存按钮等。因此它在其数据中具有可编辑对象,它将成为 DogsEditField 的 v-model 或任何其他传递给它的。所以它需要给这个组件传递一个 prop。所以我做了什么:
// This file is src/utils/crud.js
import Vue from "vue"
const crudView = (listComponent, editComponent) => {
return Vue.component('CrudView', {
template: `
<v-row>
<list-component />
<v-form>
<edit-component v-model="obj" />
</v-form>
</v-row>
`,
components: {
ListComponent: listComponent,
EditComponent: editComponent,
},
data() {
return {
obj: {},
}
},
})
}
export default crudView
此文件有大量未显示的共享代码,这些代码正在执行编辑、撤消、保存等具体操作。
然后在我的 src/router/index.js
//import DogCRUDPage from "@/views/libs/DogCRUDPage"
import crudView from "@/utils/crud"
import DogListComponent from "@/components/DogListComponent"
import DogEditField from "@/components/design/DogEditField"
const DogCRUDPage = crudView(DesignBasisList, DesignBasis)
Vue.use(VueRouter);
export default new VueRouter({
routes: [
{
path: "/dog",
name: "dog",
component: DogCRUDPage,
},
})
这是有效的,但有一些我不喜欢的问题。首先,我需要为我的项目启用 runtimecompiler,这会增加浏览器的负载大小。我需要将列表和编辑组件导入到我的路由器,而不仅仅是我有一个页面的每个对象的页面。这个新共享组件的语法与所有其他页面使用的模板语法完全不同。它将我创建的所有页面放入 router/index.js 文件,而不是像我在 Vue.
中习惯的 src/views 中的文件一样布局
完成此任务的惯用方法是什么?我走在正确的轨道上吗?我很高兴这样做,它正在工作,如果这真的是我们在 Vue 中这样做的方式。但如果 Vue 社区做一些不同的事情,我很乐意探索替代方案。我想我主要是在寻找惯用的 Vue 方法来完成这个。非常感谢。
这个怎么样:
DogsPage.vue
<template>
<CrudView
:editComponent="DogsEdit"
:listComponent="DogsList"
></CrudView>
</template>
<script>
import DogsEdit from '@/components/DogsEdit.vue'
import DogsList from '@/components/DogsList.vue'
import CrudView from '@/components/CrudView.vue'
export default {
components: { CrudView },
data() {
return { DogsEdit, DogsList }
}
}
</script>
CrudView.vue
<template>
<div>
<component :is="listComponent"></component>
<component :is="editComponent" v-model="obj"></component>
</div>
</template>
<script>
export default {
props: {
editComponent: Object,
listComponent: Object
},
data() {
return {
obj: {}
}
}
}
</script>
我有一个 VueJS 组织和架构问题。我有一堆页面用作系统中各个对象的 CRUD 页面。他们共享很多代码。我已经在一个共享组件中抽象了它,但我不喜欢我所做的,我正在寻找有关执行此操作的惯用 Vue 方法的建议。
我正在尝试创建一个接受两个参数的高阶组件:
一个编辑组件,它是每个对象的可编辑视图。因此,您可以将其视为具有 v 模型的文本输入的替代品,接受它有大量不同的输入。
一个列表组件,显示系统中该类型的所有对象的列表。它控制导航以编辑该对象。
通常这只是我使用插槽并在每个 CRUD 对象的视图页面中调用此组件的地方。所以基本上我会有这样的东西:
<!-- this file is src/views/DogsCRUDPage.vue -->
<template>
<general-crud-component
name="dogs"
backendurl="/dogs/"
>
<template slot="list">
<dogs-list-component />
</template>
<template slot="edit">
<dogs-edit-field v-model="... oops .." />
</template>
</general-crud-component>
</template>
<script>
export default {
name: "DogCRUDPage",
components: {
GeneralCrudComponent,
DogListComponent,
DogEditField,
},
}
</script>
这很好,因为它符合我所有其他 VueJS 页面的一般语法以及我如何将道具和东西传递给共享代码。然而,问题在于 GeneralCRUDComponent 处理所有检查对象是否被编辑的机制,并因此隐藏或取消隐藏保存按钮等。因此它在其数据中具有可编辑对象,它将成为 DogsEditField 的 v-model 或任何其他传递给它的。所以它需要给这个组件传递一个 prop。所以我做了什么:
// This file is src/utils/crud.js
import Vue from "vue"
const crudView = (listComponent, editComponent) => {
return Vue.component('CrudView', {
template: `
<v-row>
<list-component />
<v-form>
<edit-component v-model="obj" />
</v-form>
</v-row>
`,
components: {
ListComponent: listComponent,
EditComponent: editComponent,
},
data() {
return {
obj: {},
}
},
})
}
export default crudView
此文件有大量未显示的共享代码,这些代码正在执行编辑、撤消、保存等具体操作。
然后在我的 src/router/index.js
//import DogCRUDPage from "@/views/libs/DogCRUDPage"
import crudView from "@/utils/crud"
import DogListComponent from "@/components/DogListComponent"
import DogEditField from "@/components/design/DogEditField"
const DogCRUDPage = crudView(DesignBasisList, DesignBasis)
Vue.use(VueRouter);
export default new VueRouter({
routes: [
{
path: "/dog",
name: "dog",
component: DogCRUDPage,
},
})
这是有效的,但有一些我不喜欢的问题。首先,我需要为我的项目启用 runtimecompiler,这会增加浏览器的负载大小。我需要将列表和编辑组件导入到我的路由器,而不仅仅是我有一个页面的每个对象的页面。这个新共享组件的语法与所有其他页面使用的模板语法完全不同。它将我创建的所有页面放入 router/index.js 文件,而不是像我在 Vue.
中习惯的 src/views 中的文件一样布局完成此任务的惯用方法是什么?我走在正确的轨道上吗?我很高兴这样做,它正在工作,如果这真的是我们在 Vue 中这样做的方式。但如果 Vue 社区做一些不同的事情,我很乐意探索替代方案。我想我主要是在寻找惯用的 Vue 方法来完成这个。非常感谢。
这个怎么样:
DogsPage.vue
<template>
<CrudView
:editComponent="DogsEdit"
:listComponent="DogsList"
></CrudView>
</template>
<script>
import DogsEdit from '@/components/DogsEdit.vue'
import DogsList from '@/components/DogsList.vue'
import CrudView from '@/components/CrudView.vue'
export default {
components: { CrudView },
data() {
return { DogsEdit, DogsList }
}
}
</script>
CrudView.vue
<template>
<div>
<component :is="listComponent"></component>
<component :is="editComponent" v-model="obj"></component>
</div>
</template>
<script>
export default {
props: {
editComponent: Object,
listComponent: Object
},
data() {
return {
obj: {}
}
}
}
</script>