VueクリーンアーキテクチャEパッケージの特徴


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に入ります.
    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 先駆的なものとしてのプロデュート
  • 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 ararvosrc/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 ..テスターソーム!