feat(ts): typescript examples + improve vue-app typings (#4695)

This commit is contained in:
Kevin Marrec 2019-01-06 10:07:17 +01:00 committed by Pooya Parsa
parent 3ccfcedb65
commit b38e0aac43
28 changed files with 206 additions and 140 deletions

View File

@ -0,0 +1,3 @@
# TypeScript with Vuex example
https://nuxtjs.org/examples/typescript-vuex

View File

@ -13,18 +13,14 @@
</template>
<script lang="ts">
// PLEASE NOTE
// All "Nuxt Class Components" require at minimum a script tag that exports a default object
import Vue from 'vue'
import Component from 'nuxt-class-component'
import { Prop } from 'vue-property-decorator'
import { Vue, Component, Prop } from 'vue-property-decorator'
import { namespace } from 'vuex-class'
import * as people from '~/store/modules/people'
const People = namespace(people.name)
@Component({})
@Component
export default class Card extends Vue {
@Prop() person
@People.Action select

View File

@ -0,0 +1,12 @@
<template>
<div class="container">
<Nuxt />
</div>
</template>
<script lang="ts">
import { Component, Vue } from 'vue-property-decorator'
@Component
export default class DefaultLayout extends Vue {}
</script>

View File

@ -1,23 +1,15 @@
export default {
env: {
baseUrl: process.env.BASE_URL || 'http://localhost:3000'
},
const config = {
head: {
title: 'starter',
meta: [
{ charset: 'utf-8' },
{ name: 'viewport', content: 'width=device-width, initial-scale=1' },
{ hid: 'description', name: 'description', content: 'Nuxt.js project' }
{ hid: 'description', name: 'description', content: 'Nuxt TS project' }
],
link: [{ rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' }]
},
/*
** Customize the progress-bar color
*/
loading: { color: '#3B8070' },
/*
** Build configuration
*/
css: ['tachyons/css/tachyons.min.css', '~/assets/css/main.css'],
modules: ['~/modules/typescript']
css: ['tachyons/css/tachyons.min.css', '~/assets/css/main.css']
}
export default config

View File

@ -0,0 +1,22 @@
{
"version": "1.0.0",
"private": true,
"dependencies": {
"axios": "^0.18.0",
"nuxt-ts-edge": "latest",
"tachyons": "^4.11.1",
"vue-property-decorator": "^7.2.0",
"vuex-class": "^0.3.1"
},
"scripts": {
"dev": "nuxt-ts",
"build": "nuxt-ts build",
"start": "nuxt-ts start",
"generate": "nuxt-ts generate",
"lint": "tslint --project ."
},
"devDependencies": {
"@types/node": "^10.12.18",
"tslint-config-standard": "^8.0.1"
}
}

View File

@ -0,0 +1,39 @@
<template>
<section class="pa4">
<div class="bg-white-90 pa4">
<div class="f1">
Nuxt TypeScript Starter
</div>
<div class="f3">
Selected Person: {{ selectedPerson.first_name }} {{ selectedPerson.last_name }}
</div>
{{ selected }}
</div>
<div class="flex flex-wrap ph2 justify-between bg-white-80">
<div v-for="person in people" :key="person.id">
<Card :person="person" />
</div>
</div>
</section>
</template>
<script lang="ts">
import { Component, Vue } from 'vue-property-decorator'
import Card from '~/components/Card.vue'
import { namespace } from 'vuex-class'
import * as people from '~/store/modules/people'
const People = namespace(people.name)
@Component({
components: {
Card
}
})
export default class IndexPage extends Vue {
@People.State selected
@People.State people
@People.Getter selectedPerson
}
</script>

View File

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -11,11 +11,7 @@ import * as people from './modules/people'
// action: Sync or async operations that commit mutations
// mutations: Modify the state
interface ModulesStates {
people: people.State
}
export type RootState = root.State & ModulesStates
export type RootState = root.State
const createStore = () => {
return new Vuex.Store({

View File

@ -1,5 +1,5 @@
import { GetterTree, ActionContext, ActionTree, MutationTree } from 'vuex'
import axios from '~/plugins/axios'
import axios from 'axios'
import { RootState } from 'store'
import * as people from './modules/people'
@ -17,7 +17,7 @@ export interface Actions<S, R> extends ActionTree<S, R> {
export const actions: Actions<State, RootState> = {
async nuxtServerInit ({ commit }) {
const response = await axios.get('/random-data.json')
const response = await axios.get('/random-data.json', { proxy: { host: '127.0.0.1', port: 3000 } })
const staticPeople = response.data.slice(0, 10)
commit(`${people.name}/${people.types.SET}`, staticPeople, { root: true })
}

View File

@ -0,0 +1,27 @@
{
"compilerOptions": {
"target": "es5",
"module": "esnext",
"moduleResolution": "node",
"lib": ["es2015", "dom"],
"esModuleInterop": true,
"experimentalDecorators": true,
"allowJs": true,
"sourceMap": true,
"strict": true,
"allowSyntheticDefaultImports": true,
"noImplicitAny": false,
"noEmit": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"removeComments": true,
"baseUrl": ".",
"paths": {
"~/*": ["./*"]
},
"types": [
"@types/node",
"@nuxt/vue-app-edge"
]
}
}

View File

@ -0,0 +1,9 @@
{
"defaultSeverity": "error",
"extends": [
"tslint-config-standard"
],
"rules": {
"prefer-const": true
}
}

View File

@ -1,9 +0,0 @@
module.exports = {
parserOptions: {
parser: 'babel-eslint',
sourceType: 'module',
ecmaFeatures: {
legacyDecorators: true
}
}
}

View File

@ -1,3 +1,3 @@
# Using typescript within nuxt.js
# TypeScript example
https://github.com/johnlindquist/nuxt-typescript-starter/
https://nuxtjs.org/examples/typescript

View File

@ -0,0 +1,14 @@
<template>
<div>
{{ message }}
</div>
</template>
<script lang="ts">
import { Component, Vue } from 'vue-property-decorator'
@Component
export default class HelloWorld extends Vue {
message: string = 'Hello world !'
}
</script>

View File

@ -1,5 +0,0 @@
<template>
<div class="container">
<Nuxt />
</div>
</template>

View File

@ -1,30 +0,0 @@
export default function () {
// Add .ts extension for store, middleware and more
this.nuxt.options.extensions.push('ts')
// Extend build
this.extendBuild((config) => {
const tsLoader = {
loader: 'ts-loader',
options: {
appendTsSuffixTo: [/\.vue$/]
},
exclude: [
/dist/,
/\.temp/
]
}
// Add TypeScript loader
config.module.rules.push(
Object.assign(
{
test: /((client|server)\.js)|(\.tsx?)$/
},
tsLoader
)
)
// Add .ts extension in webpack resolve
if (config.resolve.extensions.indexOf('.ts') === -1) {
config.resolve.extensions.push('.ts')
}
})
}

View File

@ -0,0 +1,3 @@
export default {
plugins: ['~/plugins/hello']
}

View File

@ -1,22 +1,19 @@
{
"version": "1.0.1",
"version": "1.0.0",
"private": true,
"dependencies": {
"axios": "^0.18.0",
"nuxt-class-component": "^1.1.3",
"nuxt-edge": "latest",
"tachyons": "^4.9.1",
"vue-property-decorator": "^7.2.0",
"vuex-class": "^0.3.1"
"nuxt-ts-edge": "latest",
"vue-property-decorator": "^7.2.0"
},
"scripts": {
"dev": "nuxt",
"build": "nuxt build",
"start": "nuxt start",
"generate": "nuxt generate"
"dev": "nuxt-ts",
"build": "nuxt-ts build",
"start": "nuxt-ts start",
"generate": "nuxt-ts generate",
"lint": "tslint --project ."
},
"devDependencies": {
"ts-loader": "^5.3.1",
"typescript": "^3.1.6"
"@types/node": "^10.12.18",
"tslint-config-standard": "^8.0.1"
}
}

View File

@ -1,41 +1,15 @@
<template>
<section class="pa4">
<div class="bg-white-90 pa4">
<div class="f1">
Nuxt TypeScript Starter
</div>
<div class="f3">
Selected Person: {{ selectedPerson.first_name }} {{ selectedPerson.last_name }}
</div>
{{ selected }}
</div>
<div class="flex flex-wrap ph2 justify-between bg-white-80">
<div v-for="person in people" :key="person.id">
<Card :person="person" />
</div>
</div>
</section>
<HelloWorld />
</template>
<script lang="ts">
import Vue from 'vue'
import Component from 'nuxt-class-component'
import Card from '~/components/Card.vue'
import { namespace } from 'vuex-class'
import * as people from '~/store/modules/people'
const People = namespace(people.name)
import { Component, Vue } from 'vue-property-decorator'
import HelloWorld from '~/components/HelloWorld.vue'
@Component({
components: {
Card
HelloWorld
}
})
export default class extends Vue {
@People.State selected
@People.State people
@People.Getter selectedPerson
}
export default class Home extends Vue {}
</script>

View File

@ -1,5 +0,0 @@
import axios from 'axios'
export default axios.create({
baseURL: process.env.baseUrl
})

View File

@ -0,0 +1,3 @@
export default () => {
console.log(`Hello from ${process.server ? 'Server' : 'Client'} !`)
}

View File

@ -1,23 +1,27 @@
{
"compilerOptions": {
"target": "es5",
"lib": [
"dom",
"es2015"
],
"module": "es2015",
"module": "esnext",
"moduleResolution": "node",
"lib": ["es2015", "dom"],
"esModuleInterop": true,
"experimentalDecorators": true,
"noImplicitAny": false,
"noImplicitThis": false,
"strictNullChecks": true,
"removeComments": true,
"suppressImplicitAnyIndexErrors": true,
"allowSyntheticDefaultImports": true,
"baseUrl": ".",
"allowJs": true,
"sourceMap": true,
"strict": true,
"allowSyntheticDefaultImports": true,
"noImplicitAny": false,
"noEmit": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"removeComments": true,
"baseUrl": ".",
"paths": {
"~/*": ["./*"]
}
},
"types": [
"@types/node",
"@nuxt/vue-app-edge"
]
}
}

View File

@ -0,0 +1,9 @@
{
"defaultSeverity": "error",
"extends": [
"tslint-config-standard"
],
"rules": {
"prefer-const": true
}
}

View File

@ -2,6 +2,9 @@ import Vue from "vue";
import VueRouter, { Route } from "vue-router";
import { Store } from "vuex";
// augment typings of NodeJS.Process
import "./process";
// augment typings of Vue.js
import "./vue";

12
packages/vue-app/types/process.d.ts vendored Normal file
View File

@ -0,0 +1,12 @@
/**
* Extends NodeJS.Process interface
*/
declare namespace NodeJS {
interface Process {
browser: boolean;
client: boolean;
server: boolean;
static: boolean;
}
}