VueクリーンアーキテクチャEパッケージの特徴
42560 ワード
l . vvos nは、de novo falarデきれいな建築物です.舞台裏のマスアゴラN VoosマリスFalarデゴラン、E SIMデVue.jsVMAOSの実装は、oのnonosaのAPI da sの前衛のeのvueのe vue.js
vamos l .NOSSAの実装について アーマリスジドプロデュース <研究ノート>リオ・アダルト研究所
Nesta Estrutura de Projeto , Os Pacotes und t m m todas as class as ess as rias para - um recurso無依存のNCIAは、Apacegurada Colocandoクラス親愛なるRelacionadasなしmesmo pacoteをパロテにします.アクイ・アムpost com umは、ティモ模範デcomo funcionaです.
Primeira Coisa que Premiisos Fazerは、Criar Nosso Projeto Vue、Acada com O Vue 2 com typescriptに入ります.
vamos apagarパスタ src ディ モジュール ページ ドメイン モデル 製品 コンスト コンポーネント 倉庫 ドメイン モデル ユゼセ コントローラ ビュー アゴラTudo Eestは、ダンドエルロ、灘メイシスFunciona!カルマL 'は、Vamos Estruturarのnosso Cはdido que tudo seを解決します.ディー
Primeira Coisa et n ' s s definirmos o model com o que ta ta api ararvo
COM NOSSOSモデルは、OSのエンドポイントを作成します.
クリラモスOアーキヴォー
リポジトリのCriadosは、podemosの実装のnosso ussaseデprodutos.
クリラモスOアーキヴォー
コントローラ
vamos l .NOSSAの実装について
パッケージパターン
Nesta Estrutura de Projeto , Os Pacotes und t m m todas as class as ess as rias para - um recurso無依存のNCIAは、Apacegurada Colocandoクラス親愛なるRelacionadasなしmesmo pacoteをパロテにします.アクイ・アムpost com umは、ティモ模範デcomo funcionaです.
を実装する
Primeira Coisa que Premiisos Fazerは、Criar Nosso Projeto Vue、Acada com O Vue 2 com typescriptに入ります.
vue create clean-vue
cd clean-vue
vue add vuetify
npm i axios
npm i @types/axios --save-dev
npm run serve
Propetinho Rodando Liso、ボラコダー!vamos apagarパスタ
src/components
先駆的なものとしてのプロデュートモデル
Primeira Coisa et n ' s s definirmos o model com o que ta ta api ararvo
src/module/product/domain/model/product.ts
.import { AxiosResponse } from "axios"
interface ProductI {
id?: number
name?: string
description?: string
price?: number
}
class Product {
id: number
name: string
description: string
price: number
constructor({ id = 0, name = "", description = "", price = 0.00 }: ProductI) {
this.id = id
this.name = name
this.description = description
this.price = price
}
}
class ProductPagination {
items: ProductI[]
total: number
constructor(response?: AxiosResponse) {
this.items = response?.data?.items?.map((product: any) => new Product(product)) ?? []
this.total = response?.data?.total ?? 0
}
}
export { Product, ProductPagination }
E Tambのm o oモデルデPaginaは、oを選びますsrc/module/pagination/domain/model/pagination.ts
.interface PaginationI {
page: number
itemsPerPage: number
sort: string
descending: string
search: string
}
class Pagination {
page: number
itemsPerPage: number
sort: string
descending: string
search: string
constructor({ page, itemsPerPage, sort, descending, search }: PaginationI) {
this.page = page
this.itemsPerPage = itemsPerPage
this.descending = descending
this.search = search
this.sort = sort
}
}
export { Pagination }
倉庫
COM NOSSOSモデルは、OSのエンドポイントを作成します.
クリラモスOアーキヴォー
src/module/product/repository/fetchProductsRepository.ts
.import { Pagination } from '@/module/pagination/domain/model/pagination'
import { ProductPagination } from '../domain/model/product'
import { AxiosInstance } from 'axios'
interface FetchProductsRepository {
(pagination: Pagination): Promise<ProductPagination>
}
const fetchProductsRepository = (axios: AxiosInstance): FetchProductsRepository => async (pagination: Pagination) => {
const response = await axios.get("/product", {
params: pagination
})
const productPagination = new ProductPagination(response)
return productPagination
}
export { fetchProductsRepository, FetchProductsRepository }
つのcriaremos o Arquivosrc/module/product/repository/createProductRepository.ts
.import { Product } from '../domain/model/product'
import { AxiosInstance } from 'axios'
interface CreateProductRepository {
(product: Product): Promise<Product>
}
const createProductRepository = (axios: AxiosInstance): CreateProductRepository => async (product: Product) => {
const response = await axios.post("/product", product)
return new Product(response?.data)
}
export { createProductRepository, CreateProductRepository }
ユゼセ
リポジトリのCriadosは、podemosの実装のnosso ussaseデprodutos.
クリラモスOアーキヴォー
src/module/product/domain/usecase/fetchProductsUseCase.ts
.import { FetchProductsRepository } from "../../repository/fetchProductsRepository"
import { Pagination } from "@/module/pagination/domain/model/pagination"
import { ProductPagination } from "../model/product"
import { DataOptions } from "vuetify"
interface FetchProductsUseCase {
(options: DataOptions, search: string): Promise<ProductPagination>
}
const fetchProductsUseCase = (repository: FetchProductsRepository): FetchProductsUseCase => async (options: DataOptions, search: string) => {
const pagination = new Pagination({
descending: options.sortDesc.join(","),
sort: options.sortBy.join(","),
page: options.page,
itemsPerPage: options.itemsPerPage,
search: search,
})
const productPagination = await repository(pagination)
return productPagination
}
export { fetchProductsUseCase, FetchProductsUseCase }
つのcriaremos o Arquivosrc/module/product/domain/usecase/createProductUseCase.ts
.import { CreateProductRepository } from "../../repository/createProductRepository"
import { Product } from "../model/product"
interface CreateProductsUseCase {
(product: Product): Promise<Product>
}
const createProductUseCase = (repository: CreateProductRepository): CreateProductsUseCase => async (product: Product) => {
const productCreated = await repository(product)
return productCreated
}
export { createProductUseCase, CreateProductsUseCase }
コントローラ
ノウハウのコントローラーを使用していますmodule/product/controller/productController.ts
.
import { CreateProductsUseCase } from "../domain/usecase/createProductUseCase";
import { FetchProductsUseCase } from "../domain/usecase/fetchProductUseCase";
import { Product, ProductPagination } from "../domain/model/product";
import { headers } from "../const/header";
class ProductController {
options: any
public product = new Product({})
public productPagination = new ProductPagination()
public headers = headers
public formDialog = false
constructor(
private context: any,
private fetchProductsUseCase: FetchProductsUseCase,
private createProductUseCase: CreateProductsUseCase
) { }
async paginate() {
this.productPagination = await this.fetchProductsUseCase(this.options, "")
}
async save() {
if (this.context.$refs.productForm.$refs.form.validate()) {
await this.createProductUseCase(this.product)
this.cancel()
this.paginate()
}
}
cancel() {
this.product = new Product({})
this.context.$refs.productForm.$refs.form.resetValidation()
this.formDialog = false
}
}
export { ProductController }
tudo pron!ブラナデラ.Estamos Quase l ' s , vamos figurar nossa inje pose o o de de True nnciasパラコンフィギュラーイングゼは、o ndeはnnoso製品vamos criarmodule/di/di.ts
.
import { fetchProductsRepository } from "../product/repository/fetchProductsRepository";
import { createProductRepository } from "../product/repository/createProductRepository";
import { createProductUseCase } from "../product/domain/usecase/createProductUseCase";
import { fetchProductsUseCase } from "../product/domain/usecase/fetchProductUseCase";
import { ProductController } from "../product/controller/productController";
import axios from "axios";
const axiosInstance = axios.create({
baseURL: "https://clean-go.herokuapp.com",
headers: {
"Content-Type": "application/json"
}
})
axiosInstance.interceptors.response.use((response) => response, async (err) => {
const status = err.response ? err.response.status : null
if (status === 500) {
// Do something here or on any status code return
}
return Promise.reject(err);
});
// Implementation methods from products feature
const fetchProductsRepositoryImpl = fetchProductsRepository(axiosInstance)
const fetchProductsUseCaseImpl = fetchProductsUseCase(fetchProductsRepositoryImpl)
const createProductRepositoryImpl = createProductRepository(axiosInstance)
const createProductUseCaseImpl = createProductUseCase(createProductRepositoryImpl)
const productController = (context: any) => new ProductController(
context,
fetchProductsUseCaseImpl,
createProductUseCaseImpl
)
export { productController }
アゴラsim、ボラパラノッサテレ!フィンクは、モンタラEdoをします.
クリラモスOアーキヴォーmodule/product/components/productTable.vue
<template>
<v-card>
<v-card-title>
Products
<v-spacer></v-spacer>
<v-btn
color="primary"
@click="controller.formDialog = true"
>
<v-icon left>mdi-plus</v-icon>new
</v-btn>
</v-card-title>
<v-card-text class="pa-0">
<v-data-table
dense
:items="controller.productPagination.items"
:headers="controller.headers"
:options.sync="controller.options"
@pagination="controller.paginate()"
:server-items-length="controller.productPagination.total"
></v-data-table>
</v-card-text>
</v-card>
</template>
<script>
export default {
props: {
controller: {
require: true,
},
},
};
</script>
エアルキヴォボmodule/product/components/productForm.vue
<template>
<v-dialog
persistent
width="400"
v-model="controller.formDialog"
>
<v-card>
<v-card-title class="pa-0 pb-4">
<v-toolbar
flat
dense
color="primary"
class="white--text"
>
New product
</v-toolbar>
</v-card-title>
<v-card-text>
<v-form ref="form">
<v-text-field
label="Name"
dense
filled
v-model="controller.product.name"
:rules="[(v) => !!v || 'Required']"
></v-text-field>
<v-text-field
label="Price"
dense
filled
v-model.number="controller.product.price"
:rules="[(v) => !!v || 'Required']"
></v-text-field>
<v-textarea
label="Description"
dense
filled
v-model="controller.product.description"
:rules="[(v) => !!v || 'Required']"
></v-textarea>
</v-form>
</v-card-text>
<v-card-actions>
<v-btn
@click="controller.cancel()"
color="red"
text
>cancel</v-btn>
<v-spacer></v-spacer>
<v-btn
color="primary"
@click="controller.save()"
>
<v-icon left>mdi-content-save</v-icon>save
</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
</template>
<script>
export default {
props: {
controller: {
require: true,
},
},
};
</script>
E Por FIM Criaremos O Arquivomodule/product/view/product.vue
<template>
<v-app>
<v-main>
<v-row
class="fill-height"
justify="center"
align="center"
>
<v-col
cols="12"
lg="6"
>
<product-table
ref="productTable"
:controller="controller"
/>
<product-form
ref="productForm"
:controller="controller"
/>
</v-col>
</v-row>
</v-main>
</v-app>
</template>
<script>
import { productController } from "../../di/di";
import ProductTable from "../components/productTable";
import ProductForm from "../components/productForm";
export default {
components: {
ProductTable,
ProductForm,
},
data: (context) => ({
controller: productController(context),
}),
};
</script>
エストラチュラファイナルフィコ
testando , 12 .. 3 ..テスターソーム!
Reference
この問題について(VueクリーンアーキテクチャEパッケージの特徴), 我々は、より多くの情報をここで見つけました
https://dev.to/booscaaa/vuejs-clean-architecture-e-package-by-feature-pattern-56lb
テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol
import { CreateProductsUseCase } from "../domain/usecase/createProductUseCase";
import { FetchProductsUseCase } from "../domain/usecase/fetchProductUseCase";
import { Product, ProductPagination } from "../domain/model/product";
import { headers } from "../const/header";
class ProductController {
options: any
public product = new Product({})
public productPagination = new ProductPagination()
public headers = headers
public formDialog = false
constructor(
private context: any,
private fetchProductsUseCase: FetchProductsUseCase,
private createProductUseCase: CreateProductsUseCase
) { }
async paginate() {
this.productPagination = await this.fetchProductsUseCase(this.options, "")
}
async save() {
if (this.context.$refs.productForm.$refs.form.validate()) {
await this.createProductUseCase(this.product)
this.cancel()
this.paginate()
}
}
cancel() {
this.product = new Product({})
this.context.$refs.productForm.$refs.form.resetValidation()
this.formDialog = false
}
}
export { ProductController }
import { fetchProductsRepository } from "../product/repository/fetchProductsRepository";
import { createProductRepository } from "../product/repository/createProductRepository";
import { createProductUseCase } from "../product/domain/usecase/createProductUseCase";
import { fetchProductsUseCase } from "../product/domain/usecase/fetchProductUseCase";
import { ProductController } from "../product/controller/productController";
import axios from "axios";
const axiosInstance = axios.create({
baseURL: "https://clean-go.herokuapp.com",
headers: {
"Content-Type": "application/json"
}
})
axiosInstance.interceptors.response.use((response) => response, async (err) => {
const status = err.response ? err.response.status : null
if (status === 500) {
// Do something here or on any status code return
}
return Promise.reject(err);
});
// Implementation methods from products feature
const fetchProductsRepositoryImpl = fetchProductsRepository(axiosInstance)
const fetchProductsUseCaseImpl = fetchProductsUseCase(fetchProductsRepositoryImpl)
const createProductRepositoryImpl = createProductRepository(axiosInstance)
const createProductUseCaseImpl = createProductUseCase(createProductRepositoryImpl)
const productController = (context: any) => new ProductController(
context,
fetchProductsUseCaseImpl,
createProductUseCaseImpl
)
export { productController }
<template>
<v-card>
<v-card-title>
Products
<v-spacer></v-spacer>
<v-btn
color="primary"
@click="controller.formDialog = true"
>
<v-icon left>mdi-plus</v-icon>new
</v-btn>
</v-card-title>
<v-card-text class="pa-0">
<v-data-table
dense
:items="controller.productPagination.items"
:headers="controller.headers"
:options.sync="controller.options"
@pagination="controller.paginate()"
:server-items-length="controller.productPagination.total"
></v-data-table>
</v-card-text>
</v-card>
</template>
<script>
export default {
props: {
controller: {
require: true,
},
},
};
</script>
<template>
<v-dialog
persistent
width="400"
v-model="controller.formDialog"
>
<v-card>
<v-card-title class="pa-0 pb-4">
<v-toolbar
flat
dense
color="primary"
class="white--text"
>
New product
</v-toolbar>
</v-card-title>
<v-card-text>
<v-form ref="form">
<v-text-field
label="Name"
dense
filled
v-model="controller.product.name"
:rules="[(v) => !!v || 'Required']"
></v-text-field>
<v-text-field
label="Price"
dense
filled
v-model.number="controller.product.price"
:rules="[(v) => !!v || 'Required']"
></v-text-field>
<v-textarea
label="Description"
dense
filled
v-model="controller.product.description"
:rules="[(v) => !!v || 'Required']"
></v-textarea>
</v-form>
</v-card-text>
<v-card-actions>
<v-btn
@click="controller.cancel()"
color="red"
text
>cancel</v-btn>
<v-spacer></v-spacer>
<v-btn
color="primary"
@click="controller.save()"
>
<v-icon left>mdi-content-save</v-icon>save
</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
</template>
<script>
export default {
props: {
controller: {
require: true,
},
},
};
</script>
<template>
<v-app>
<v-main>
<v-row
class="fill-height"
justify="center"
align="center"
>
<v-col
cols="12"
lg="6"
>
<product-table
ref="productTable"
:controller="controller"
/>
<product-form
ref="productForm"
:controller="controller"
/>
</v-col>
</v-row>
</v-main>
</v-app>
</template>
<script>
import { productController } from "../../di/di";
import ProductTable from "../components/productTable";
import ProductForm from "../components/productForm";
export default {
components: {
ProductTable,
ProductForm,
},
data: (context) => ({
controller: productController(context),
}),
};
</script>
Reference
この問題について(VueクリーンアーキテクチャEパッケージの特徴), 我々は、より多くの情報をここで見つけました https://dev.to/booscaaa/vuejs-clean-architecture-e-package-by-feature-pattern-56lbテキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol