Skip to content

Update Vuetify generator doc #1708

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
261 changes: 28 additions & 233 deletions create-client/vuetify.md
Original file line number Diff line number Diff line change
@@ -1,269 +1,64 @@
# Vuetify Generator

## Install With Docker

If you use the API Platform distribution with Docker, first you have to add the [Vue CLI](https://cli.vuejs.org/guide/) to the Docker image.

In the `dev` stage of `pwa/Dockerfile`, add this line:

```dockerfile
RUN pnpm install -g @vue/cli @vue/cli-service-global
```

Then, rebuild your containers.

Delete the content of the `pwa\` directory (the distribution comes with a prebuilt Next.js app).

Create a new Vue App and install vuetify and other vue packages:

```console
docker compose exec pwa \
vue create -d .
docker compose exec pwa \
vue add vuetify
docker compose exec pwa \
pnpm install router lodash moment vue-i18n vue-router vuelidate vuex vuex-map-fields
```

Update the entrypoint:

```javascript
// client/src/config/entrypoint.js
export const ENTRYPOINT = 'https://localhost:8443';
```

Update the scripts part of the new `package.json`:

```json
"scripts": {
"build": "vue-cli-service build",
"lint": "vue-cli-service lint",
"start": "vue-cli-service serve --port 3000 --https"
},
```

Rebuild the docker containers again to install the Vue App and start the vue server.

Generate the vuetify components with the following command:

```console
docker compose exec pwa \
pnpm create @api-platform/client --generator vuetify --resource book
```

Omit the resource flag to generate files for all resource types exposed by the API.

Continue by [generating the VueJS Web App](#generating-the-vuejs-web-app).

## Install Without Docker

Create a Vuetify application using
[Vue CLI 3](https://cli.vuejs.org/guide/):
Bootstrap a Vuetify 3 application using `create-vuetify`:

```console
vue create -d vuetify-app
cd vuetify-app
vue add vuetify
npm init vuetify -- --typescript --preset essentials
cd my-app
```

Install the required dependencies:

```console
npm install router lodash moment vue-i18n vue-router vuelidate vuex vuex-map-fields
npm install dayjs qs @types/qs vue-i18n
```

In the app directory, generate the files for the resource you want:
To generate all the code you need for a given resource run the following command:

```console
npm init @api-platform/client https://demo.api-platform.com src/ -- --generator vuetify
npm init @api-platform/client https://demo.api-platform.com src/ -- --generator vuetify --resource book
```

Replace the URL with the entrypoint of your Hydra-enabled API.
You can also use an OpenAPI documentation with `-f openapi3`.
You can also use an OpenAPI documentation with `https://demo.api-platform.com/docs.json` and `-f openapi3`.

Omit the resource flag to generate files for all resource types exposed by the API.

## Generating the VueJS Web App

The code is ready to be executed! Register the generated routes:
**Note:** Make sure to follow the result indications of the command to register the routes and the translations.

```javascript
// src/router/index.js
import Vue from 'vue';
import VueRouter from 'vue-router';
import bookRoutes from './book';
import reviewRoutes from './review';
Then add this import in `src/plugins/vuetify.ts`:

Vue.use(VueRouter);

export default new VueRouter({
mode: 'history',
routes: [bookRoutes, reviewRoutes]
});
```typescript
// src/plugins/vuetify.ts
import { VDataTableServer } from "vuetify/labs/VDataTable"
```

Add the modules to the store:

```javascript
// src/store/index.js
import Vue from 'vue';
import Vuex from 'vuex';
import makeCrudModule from './modules/crud';
import notifications from './modules/notifications';
import bookService from '../services/book';
import reviewService from '../services/review';

Vue.use(Vuex);
In the same file replace the export with:

const store = new Vuex.Store({
modules: {
notifications,
book: makeCrudModule({
service: bookService
}),
review: makeCrudModule({
service: reviewService
})
```typescript
// src/plugins/vuetify.ts
export default createVuetify({
components: {
VDataTableServer,
},
strict: process.env.NODE_ENV !== 'production'
});

export default store;
```

Update the `src/plugins/vuetify.js` file with the following:

```javascript
// src/plugins/vuetify.js
import Vue from 'vue';
import Vuetify from 'vuetify/lib';
In `src/plugins/index.ts` add this import:

Vue.use(Vuetify);

const opts = {
icons: {
iconfont: 'mdi'
}
};

export default new Vuetify(opts);
```typescript
// src/plugins/index.ts
import i18n from "@/plugins/i18n"
```

The generator comes with an i18n feature to allow quick translations of some labels in the generated code, to make it
work, you need to create this file:

```javascript
// src/i18n.js
import Vue from 'vue';
import VueI18n from 'vue-i18n';
import messages from './locales/en';

Vue.use(VueI18n);

export default new VueI18n({
locale: process.env.VUE_APP_I18N_LOCALE || 'en',
fallbackLocale: process.env.VUE_APP_I18N_FALLBACK_LOCALE || 'en',
messages: {
en: messages
}
});
```
In the same file add `.use(i18n)` chained with the other `use()` functions.

Update your `App.vue`:
You can launch the server with:

```vue
<!-- App.vue -->
<template>
<v-app id="inspire">
<snackbar></snackbar>
<v-navigation-drawer v-model="drawer" app>
<v-list dense>
<v-list-item>
<v-list-item-action>
<v-icon>mdi-home</v-icon>
</v-list-item-action>
<v-list-item-content>
<v-list-item-title>Home</v-list-item-title>
</v-list-item-content>
</v-list-item>
<v-list-item>
<v-list-item-action>
<v-icon>mdi-book</v-icon>
</v-list-item-action>
<v-list-item-content>
<v-list-item-title>
<router-link :to="{ name: 'BookList' }">Books</router-link>
</v-list-item-title>
</v-list-item-content>
</v-list-item>
<v-list-item>
<v-list-item-action>
<v-icon>mdi-comment-quote</v-icon>
</v-list-item-action>
<v-list-item-content>
<v-list-item-title>
<router-link :to="{ name: 'ReviewList' }">Reviews</router-link>
</v-list-item-title>
</v-list-item-content>
</v-list-item>
</v-list>
</v-navigation-drawer>
<v-app-bar app color="indigo" dark>
<v-app-bar-nav-icon @click.stop="drawer = !drawer"></v-app-bar-nav-icon>
<v-toolbar-title>Application</v-toolbar-title>
</v-app-bar>

<v-main>
<Breadcrumb layout-class="pl-3 py-3" />
<router-view></router-view>
</v-main>
<v-footer color="indigo" app>
<span class="white--text">&copy; 2019</span>
</v-footer>
</v-app>
</template>

<script>
import Breadcrumb from './components/Breadcrumb';
import Snackbar from './components/Snackbar';

export default {
components: {
Breadcrumb,
Snackbar
},

data: () => ({
drawer: null
})
};
</script>
```console
npm run dev
```

To finish, update your `main.js`:

```javascript
// main.js
import Vue from 'vue';
import Vuelidate from 'vuelidate';
import App from './App.vue';
import vuetify from './plugins/vuetify';

import store from './store';
import router from './router';
import i18n from './i18n';

Vue.config.productionTip = false;

Vue.use(Vuelidate);

new Vue({
i18n,
router,
store,
vuetify,
render: h => h(App)
}).$mount('#app');
```
Go to `http://localhost:3000/books/` to start using your app.

Go to `https://localhost:8000/books/` to start using your app.
**Note:** In order to Mercure to work with the demo, you have to use the port 3000.