Giter VIP home page Giter VIP logo

typescript-vue-starter's Introduction

This repo is deprecated, it was created in the days before Vue shipped with TypeScript out of the box. Now the best path to get started is through the official CLI. We'll keep this repo around as a useful archive.


TypeScript Vue Starter

This quick start guide will teach you how to get TypeScript and Vue working together. This guide is flexible enough that any steps here can be used to integrate TypeScript into an existing Vue project.

Before you begin

If you're new to Typescript and Vue, here are few resources to get you up and running:

TypeScript

Vue

Initialize your project

Let's create a new package.

mkdir typescript-vue-tutorial
cd typescript-vue-tutorial

Next, we'll scaffold our project in the following way:

typescript-vue-tutorial/
├─ dist/
└─ src/
   └─ components/

TypeScript files will start out in your src folder, run through the TypeScript compiler, then webpack, and end up in a bundle.js file in dist. Any components that we write will go in the src/components folder.

Let's scaffold this out:

mkdir src
cd src
mkdir components
cd ..

Webpack will eventually generate the dist directory for us.

Initialize the project

Now we'll turn this folder into an npm package.

npm init

You'll be given a series of prompts. You can use the defaults except for your entry point. You can always go back and change these in the package.json file that's been generated for you.

Install our dependencies

Ensure TypeScript, Webpack, Vue and the necessary loaders are installed.

npm install --save-dev typescript webpack webpack-cli ts-loader css-loader vue vue-loader vue-template-compiler

Webpack is a tool that will bundle your code and optionally all of its dependencies into a single .js file. While you don't need to use a bundler like Webpack or Browserify, these tools will allow us to use .vue files which we'll cover in a bit.

We didn't need to add .d.ts files, but if we were using a package which didn't ship declaration files, we'd need to install the appropriate @types/ package. Read more about using definition files in our documentation.

Add a TypeScript configuration file

You'll want to bring your TypeScript files together - both the code you'll be writing as well as any necessary declaration files.

To do this, you'll need to create a tsconfig.json which contains a list of your input files as well as all your compilation settings. Simply create a new file in your project root named tsconfig.json and fill it with the following contents:

You can easily create tsconfig.json this command.

tsc --init
{
    "compilerOptions": {
        "outDir": "./built/",
        "sourceMap": true,
        "strict": true,
        "noImplicitReturns": true,
        "module": "es2015",
        "moduleResolution": "node",
        "target": "es5"
    },
    "include": [
        "./src/**/*"
    ]
}

Notice the strict flag is set to true. At the very least, TypeScript's noImplicitThis flag will need to be turned on to leverage Vue's declaration files, but strict gives us that and more (like noImplicitAny and strictNullChecks). We strongly recommend using TypeScript's stricter options for a better experience.

Adding Webpack

We'll need to add a webpack.config.js to bundle our app.

var path = require('path')
var webpack = require('webpack')
const VueLoaderPlugin = require('vue-loader/lib/plugin')

module.exports = {
  entry: './src/index.ts',
  output: {
    path: path.resolve(__dirname, './dist'),
    publicPath: '/dist/',
    filename: 'build.js'
  },
  module: {
    rules: [
      {
        test: /\.vue$/,
        loader: 'vue-loader',
        options: {
          loaders: {
            // Since sass-loader (weirdly) has SCSS as its default parse mode, we map
            // the "scss" and "sass" values for the lang attribute to the right configs here.
            // other preprocessors should work out of the box, no loader config like this necessary.
            'scss': 'vue-style-loader!css-loader!sass-loader',
            'sass': 'vue-style-loader!css-loader!sass-loader?indentedSyntax',
          }
          // other vue-loader options go here
        }
      },
      {
        test: /\.tsx?$/,
        loader: 'ts-loader',
        exclude: /node_modules/,
        options: {
          appendTsSuffixTo: [/\.vue$/],
        }
      },
      {
        test: /\.(png|jpg|gif|svg)$/,
        loader: 'file-loader',
        options: {
          name: '[name].[ext]?[hash]'
        }
      },
      {
        test: /\.css$/,
        use: [
          'vue-style-loader',
          'css-loader'
        ]
      }
    ]
  },
  resolve: {
    extensions: ['.ts', '.js', '.vue', '.json'],
    alias: {
      'vue$': 'vue/dist/vue.esm.js'
    }
  },
  devServer: {
    historyApiFallback: true,
    noInfo: true
  },
  performance: {
    hints: false
  },
  devtool: '#eval-source-map',
  plugins: [
    // make sure to include the plugin for the magic
    new VueLoaderPlugin()
  ]
}

if (process.env.NODE_ENV === 'production') {
  module.exports.devtool = '#source-map'
  // http://vue-loader.vuejs.org/en/workflow/production.html
  module.exports.plugins = (module.exports.plugins || []).concat([
    new webpack.DefinePlugin({
      'process.env': {
        NODE_ENV: '"production"'
      }
    }),
    new webpack.optimize.UglifyJsPlugin({
      sourceMap: true,
      compress: {
        warnings: false
      }
    }),
    new webpack.LoaderOptionsPlugin({
      minimize: true
    })
  ])
}

Add a build script

Open up your package.json and add a script named build to run Webpack. Your "scripts" field should look something like this:

"scripts": {
    "build": "webpack",
    "test": "echo \"Error: no test specified\" && exit 1"
  },

Once we add an entry point, we'll be able to build by running

npm run build

and have builds get triggered on changes by running

npm run build -- --watch

Create a basic project

Let's create the most bare-bones Vue & TypeScript example that we can try out. First, create the file ./src/index.ts:

// src/index.ts

import Vue from "vue";

let v = new Vue({
    el: "#app",
    template: `
    <div>
        <div>Hello {{name}}!</div>
        Name: <input v-model="name" type="text">
    </div>`,
    data: {
        name: "World"
    }
});

Let's check to see if everything is wired up correctly. Create an index.html with the following content at your root:

<!doctype html>
<html>
<head></head>

<body>
    <div id="app"></div>
</body>
<script src="./dist/build.js"></script>

</html>

Now run npm run build and open up your index.html file in a browser.

You should see some text that says Hello World!. Below that, you'll see a textbox. If you change the content of the textbox, you'll notice how the text is synchronized between the two.

Congrats! You've gotten TypeScript and Vue fully hooked up!

Adding a component

As you've just seen, Vue has a very simple interface for when you need to accomplish simple tasks. When our page only needed to communicate a bit of data between two elements, it took very little code.

For more complex tasks, Vue is flexible in that it supports breaking your application into components. Components are useful for separating the concerns of how entities are displayed to the user. Read up more on components from Vue's documentation.

A Vue component can be declared in the following manner:

// src/components/Hello.ts

import Vue from "vue";

export default Vue.extend({
    template: `
        <div>
            <div>Hello {{name}}{{exclamationMarks}}</div>
            <button @click="decrement">-</button>
            <button @click="increment">+</button>
        </div>
    `,
    props: ['name', 'initialEnthusiasm'],
    data() {
        return {
            enthusiasm: this.initialEnthusiasm,
        }
    },
    methods: {
        increment() { this.enthusiasm++; },
        decrement() {
            if (this.enthusiasm > 1) {
                this.enthusiasm--;
            }
        },
    },
    computed: {
        exclamationMarks(): string {
            return Array(this.enthusiasm + 1).join('!');
        }
    }
});

This component has two buttons and some text. When rendered, it takes an initial name and an initialEnthusiasm which is the number of exclamation marks we want to display. When we hit the + button, it adds an exclamation mark to the end of the text. Likewise, when we hit the - button, it removes an exclamation mark unless we're down to just one.

Our root Vue instance can consume it as follows:

// src/index.ts

import Vue from "vue";
import HelloComponent from "./components/Hello";

let v = new Vue({
    el: "#app",
    template: `
    <div>
        Name: <input v-model="name" type="text">
        <hello-component :name="name" :initialEnthusiasm="5" />
    </div>
    `,
    data: { name: "World" },
    components: {
        HelloComponent
    }
});

However, we'll note that it is fairly popular to use Vue's single file components. Let's try writing the above as an SFC.

Single File Components

When using Webpack or Browserify, Vue has plugins like vue-loader and vueify which allow you to author your components in HTML-like files. These files, which end in a .vue extension, are single file components.

There are a few things that need to be put in place to use .vue files with TypeScript, but luckily we're already halfway there. We already installed vue-loader earlier when we got our dev dependencies. We also specified the appendTsSuffixTo: [/\.vue$/], option to ts-loader in our webpack.config.js file, which allows TypeScript to process the code extracted from a single file component.

One extra thing we'll have to do is tell TypeScript what .vue files will look like when they're imported. We'll do this with a vue-shims.d.ts file:

// src/vue-shims.d.ts

declare module "*.vue" {
    import Vue from "vue";
    export default Vue;
}

We don't need to import this file anywhere. It's automatically included by TypeScript, and it tells it that anything imported that ends in .vue has the same shape of the Vue constructor itself.

What's left? The editing experience! One of the best features TypeScript gives us is its editor support. To leverage that within .vue files, we recommend using Visual Studio Code with the Vetur plugin for Vue.

Now, let's write an SFC!

<!-- src/components/Hello.vue -->

<template>
    <div>
        <div class="greeting">Hello {{name}}{{exclamationMarks}}</div>
        <button @click="decrement">-</button>
        <button @click="increment">+</button>
    </div>
</template>

<script lang="ts">
import Vue from "vue";

export default Vue.extend({
    props: ['name', 'initialEnthusiasm'],
    data() {
        return {
            enthusiasm: this.initialEnthusiasm,
        }
    },
    methods: {
        increment() { this.enthusiasm++; },
        decrement() {
            if (this.enthusiasm > 1) {
                this.enthusiasm--;
            }
        },
    },
    computed: {
        exclamationMarks(): string {
            return Array(this.enthusiasm + 1).join('!');
        }
    }
});
</script>

<style>
.greeting {
    font-size: 20px;
}
</style>

and let's import it for our root instance:

// src/index.ts

import Vue from "vue";
import HelloComponent from "./components/Hello.vue";

let v = new Vue({
    el: "#app",
    template: `
    <div>
        Name: <input v-model="name" type="text">
        <hello-component :name="name" :initialEnthusiasm="5" />
    </div>
    `,
    data: { name: "World" },
    components: {
        HelloComponent
    }
});

Notice a few things about our single-file component:

  • We had to write <script lang="ts"> to get it working with TypeScript.
  • We had to import the component with the .vue extension in index.ts.
  • We were able to write CSS isolated to our components in a <style> tag, which we couldn't do in our .ts components.
  • We default-exported a call to Vue.extend (rather than the options bag itself). If you don't write Vue.extend, Vetur will make it look like things are working correctly, but you'll get an error when you build your project.

Try running npm run build and open up index.html to see the result!

Using decorators to define a component

Components can also be defined using decorators. With the help of two additional packages, (vue-class-component and vue-property-decorator), our components can be rewritten in the following manner:

import { Vue, Component, Prop } from "vue-property-decorator";

@Component
export default class HelloDecorator extends Vue {
    @Prop() name!: string;
    @Prop() initialEnthusiasm!: number;

    enthusiasm = this.initialEnthusiasm;

    increment() {
        this.enthusiasm++;
    }
    decrement() {
        if (this.enthusiasm > 1) {
            this.enthusiasm--;
        }
    }

    get exclamationMarks(): string {
        return Array(this.enthusiasm + 1).join('!');
    }
}

Instead of using Vue.extend to define our component, we create a class extending Vue and decorate it using the @Component decorator from the vue-class-component package (which was re-exported from the vue-property-decorator package).

Properties are defined by prefixing instance variables with the @Prop() decorator from the vue-property-decorator package. Because the --strictPropertyInitialization option is on, we need to tell TypeScript that Vue will initialize our properties by appending a ! to them. This tells TypeScript "hey, relax, someone else is going to assign this property a value."

Regular instance variables, such as enthusiasm in our example, are automatically made available for data binding to the template, just as if they had been defined in the data field. Note that all variables must be set to a value other than undefined for the binding to work.

Similarly, methods such as increment are treated as if they had been written in the methods field, and are automatically made available for the template.

Finally, computed properties like exclamationMarks are simply written as get accessors.

What next?

You can try out this application by cloning it from GitHub.

Once you feel like you've got a handle on that, you can try out a sample TodoMVC-style app written in TypeScript and Vue. This TodoMVC-style sample features routing through vue-router so that your application can show different views depending on the current URL.

You may also want to look into Vuex if you're looking for Redux-style state management.

typescript-vue-starter's People

Contributors

astray-git avatar cho0o0 avatar danielrosenwasser avatar jdiehl avatar joshrosenhanst avatar kumaran-14 avatar lyonsbp avatar microsoftopensource avatar msftgits avatar orta avatar runxc1 avatar scottlaw1 avatar spotts9 avatar webhacking avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

typescript-vue-starter's Issues

No default export?

"npm run build" results in

"error TS1192: Module '"myabsolutepath/test_chrome_ext_typescript/node_modules/vue/types/index"' has no default export."

Being a complete beginner to webpack/npm/typescript, and not much experience in javascript, I eventually googled a solution to be

import * as Vue from "vue";

in the index.ts file. This built. It results in the browser console giving:

"Uncaught TypeError: WEBPACK_IMPORTED_MODULE_0_vue is not a function"

In the end I had to include "allowSyntheticDefaultImports": true in tsconfig.json compiler options. which was the final fix and and works with the original import statement.

By the way, I didn't use the https://github.com/DanielRosenwasser/vue#540a38fb21adb7a7bc394c65e23e6cffb36cd867

as being irrelevant to a basic skeleton and a potential problem; plus not comprehensible to a newbie. I merely 'npm install vue'.

Also my typescript install is global. Everything else was as given in the guide.

Any chance of some words on getting debugging working from VSCode?

official ssr

Would it be possible to provide as additional option any kind of official vue server-side rendering with .net core starter?
Kind regards

scss not compiling

ERROR in ./src/app.vue?vue&type=style&index=0&id=5ef48958&scoped=true&lang=scss& (./node_modules/vue-loader/lib??ref--2!./node_modules/vue-loader/lib??vue-loader-options!./src/app.vue?vue&type=style&index=0&id=5ef48958&scoped=true&lang=scss&)
Module build failed (from ./node_modules/vue-loader/lib/index.js):
TypeError: Cannot read property 'content' of undefined
    at selectBlock (C:\Users\pc\Desktop\play\essentialfootball\node_modules\vue-loader\lib\select.js:41:13)
    at Object.module.exports (C:\Users\pc\Desktop\play\essentialfootball\node_modules\vue-loader\lib\index.js:79:12)
 @ ./src/app.vue?vue&type=style&index=0&id=5ef48958&scoped=true&lang=scss& 1:0-196 1:212-215 1:217-410 1:217-410
 @ ./src/app.vue
 @ ./src/app.ts

i could not compile scss styles, but I solved by changing how the vue style loader was loaded:

      {
        test: /\.scss$/,
        use: [
          'vue-style-loader',
          'css-loader',
          'sass-loader'
        ]
      }

Vue App with TypeScript + SystemJS

I wanted to know what changes need to be made to my tsconfig and systemjs config if I'm using TypeScript + SystemJS and NOT "webpack + es2015 module loader"? As of now Vue is resolving for me with the below changes
import Vue from "../jspm_packages/npm/[email protected]/types/vue";
but it does resolve if I do
import { Vue } from "../jspm_packages/npm/[email protected]/types/vue"; I do not understand the nuance of when and when not to use the curly braces and why.

Doesn't work with latest Vue 2.3.4

First, I appreciate your work.
However, an app starter is much less useful if I have to use your specific fork of vue and vue-router. I'm going to go out on a limb and say that most organizations are not going to want to be tied to another dev's fork, especially one that is customized. Is there a plan for a future build that will work with current builds of Vue? Otherwise, this is a non-solution for most folks.

Nuxt support

Is it possible to add nuxt support or TypeScript-Nuxt-Starter. I could not manage to use nuxt 2 with typescript successfully.

Many thanks.

Upgrade documentation to vue 2.5

It seems a lot has changed in Vue 2.5 regarding typescript (and using vue-class-component). It would be helpful if the Typescript Vue starter can be updated. The example code repository is 2 years old! It contradicts the official Vue docs.

Feedback to the starter

Hey @DanielRosenwasser I didn't know where I should post it so I do it here. Please let me know, whether it is not correct.

I saw your talk about Vue + TypeScript on the VueConf 2018. I liked the talk very much, thx for that. Maybe I misunderstand smth but why do you "prefer" the way, using TS + Vue w/o using classes and decorators? I think using the class syntax and decorators are the more common way nowadays when we use TypeScript, isn't it? Using the class syntax is more optional, correct? Are there any pros and cons of using the one or the other way, in your example?

I also have an example, it is not finished yet and w/o using the CLI but my first steps with Vue and TypeScript: https://github.com/Chris2011/Vue-TypeScript-Live-Search-Sample and do a refactoring right now. Remove some old, dumbass code ;).

Cheers

Chris

Got error on HelloComponent.vue

Got the error message when building with webpack.
However, it still can run perfectly.

error TS2345: Argument of type 'typeof HelloDecorator' is not assignable to parameter of type 'VueClass<Vue>'.
  Type 'typeof HelloDecorator' is not assignable to type 'new (...args: any[]) => Vue'.
    Type 'HelloDecorator' is not assignable to type 'Vue'.
      Types of property '$options' are incompatible.
        Type 'ComponentOptions<HelloDecorator, DefaultData<HelloDecorator>, DefaultMethods<HelloDecorator>, Def...' is not assignable to type 'ComponentOptions<Vue, DefaultData<Vue>, DefaultMethods<Vue>, DefaultComputed, PropsDefinition<Rec...'.
          Type 'HelloDecorator' is not assignable to type 'Vue'.

Note regarding NODE_ENV=development vs NODE_ENV=production

Vue Template compiler emits different content depending on this setting. It would be advised to include it in the scripts so devs can switch output easily from development to production...

"scripts": {
"build": "NODE_ENV=development webpack",
"test": "echo "Error: no test specified" && exit 1"
},

--> Output: build.js ---> 877 kB

vs

"scripts": {
"build": "NODE_ENV=production webpack",
"test": "echo "Error: no test specified" && exit 1"
},

--> Output: build.js ---> 104 kB (35kB gzip)

Great work on this. The workflow and example are very well done.

"Go to definition" on vue components goes to vue.d.ts

Repro steps:

  1. Clone and npm install this repo
  2. Open index.ts in VS code
  3. Right-click then select Go to Definition on HelloComponent
  4. VS Code opens vue.d.ts. When going to the definition of "./components/Hello.vue" I'm taken to vue-shims.d.ts instead.

Is this a known issue?

Not able to use decorators to define a component

Was giving a try for https://github.com/Microsoft/TypeScript-Vue-Starter#using-decorators-to-define-a-component

I see error:

TS1238: Unable to resolve signature of class decorator when called as an expression.
Type '<VC extends VueClass<{}>>(target: VC) => VC' is not assignable to type 'typeof HelloDecorator'.
Property 'extend' is missing in type '<VC extends VueClass<{}>>(target: VC) => VC'.

I am using Typescript version: 2.7.1

//Hello.vue
screen shot 2018-02-10 at 2 45 58 pm

// tsconfig.json
screen shot 2018-02-10 at 3 30 03 pm

Typescript doesn't infer type of component imported from .vue

On this import statement:

import myComponent from ./myComponent.vue

myComponent has the type of Vue. When I "go to defintion" on this symbol, it goes to Vue type declaration instead of going to myComponent.vue file.

Is there a way to resolve this? I'm trying to switch from ts files to single file components but this seems like a regression compared to working with ts files.

Add precondition to readme.

I'm an experienced JS and VueJS developer, but I have no experience with TypeScript.
I require to learn TypeScript, but I'm not sure if this is the best starting point.

That's why I was thinking: It would be great if the top of this readme could say something in the lines of:
"This Starter requires basic knowledge of TypeScript. To get this basic knowledge please follow the short guide at .............., then come back here!" Then add a url to a short guide we can tackle first!

Or would that be too idealistic? : D

Either way I'd love to know any url with a good recommended short guide with basic knowledge I should know on beforehand. I have watched a couple of seminars on TypeScript but I'm feeling it hasn't hit me yet. And there are a lot of very mediocre written guides...

Anyway good job!

The starter seems to be broken at the "hello.vue" stage

When you get to the single page component step in the starter, build does not work.

I think other issues are mentioning this, and it looks like people found solution(s), but nothing clear enough for me to copy.
For example, I tried pasting in the new rule mentioned in one issue, and adding the plugin mentioned in another.

However, with a bit of googling I see that vue includes tools to get started with typescript, so maybe that's a better option than trying this tutorial...

>npm run build
ERROR in ./src/components/Hello.vue?vue&type=style&index=0&lang=css& (./node_modules/vue-loader/lib??vue-loader-options!./src/components/Hello.vue?vue&type=style&index=0&lang=css&) 36:0
Module parse failed: Unexpected token (36:0)
You may need an appropriate loader to handle this file type.
| 
| 
> .greeting {
|     font-size: 20px;
| }
 @ ./src/components/Hello.vue?vue&type=style&index=0&lang=css& 1:0-128 1:144-147 1:149-274 1:149-274
 @ ./src/components/Hello.vue
 @ ./src/index.ts

Update project with vue CLI support

Currently the vue cli is the recommended way to setup an app, and you no longer use webpack directly. Instead you have a vue.config.js that you work with.

Vuex Support

Add support for Vuex please!
At his moment it gives me this error:

vuex

I don't know to setup

I just run "npm init" and 'npm install --save-dev typescript webpack ts-loader css-loader vue vue-loader vue-template-compiler" and setup directoery like the description but there are no file like the sample. So I need to run "npm install -g @vue/cli" or I need to down load the sample and run these command ?

Typescript powered code completion hangs if no computed property is given

Writing here because maybe it's VS Code, maybe TS or maybe Vue types. Sorry if it's just me :)
VS Code Version 1.18.0 (tsdk as delivered)
Vue 2.5.3, no extra types installed

Observation is that this is downgraded to any if the computed property misses.

selection_031

Now have a look at the version that contains the computed property. As you can see the whole Component property types are properly inferred.

selection_032

props detection and data() constructor

I just cloned the repo but I got errors when calling a property or instance variable. This error happens on the code published at the moment (TodoMVC).

Examples

With properties

export default Vue.extend({
  props: ['itemsLeft', 'clearCompleted', 'currentView'],
  computed: {
    itemSingularOrPlural(): string {
      return this.itemsLeft === 1 ? 'item' : 'items';
    },
    // ....
  }
});

throws the error Property 'itemsLeft' does not exist on type 'Vue'.

With data()

export default {
  methods: {
    demo () {
      alert(this.msg)
    }
  },
  data () {
    return {
      msg: 'Welcome to Your Vue.js App'
    }
  }
}

throws a Property 'msg' does not exist on type '{ demo(): void; }'.

Solution ?

Typescript "expects" things to be declared correctly and doesn't like VueJS ways of doing things (I might be wrong about this assertion, feel free to correct me).

When I tried to setup VueJS + Typescript I ended up using decorators like this one https://github.com/vuejs/vue-class-component. Maybe some decorators should be included with this starter ?

error TS2564: Property 'name' has no initializer and is not definitely assigned in the constructor.

ERROR in /Users/benzhao/Researchs/TypeScript-Vue-Starter/src/components/HelloDecorator.vue.ts
(16,11): error TS2564: Property 'name' has no initializer and is not definitely assigned in the constructor.

ERROR in /Users/benzhao/Researchs/TypeScript-Vue-Starter/src/components/HelloDecorator.vue.ts
(17,11): error TS2564: Property 'initialEnthusiasm' has no initializer and is not definitelyassigned in the constructor.

typescript version 2.7.2

Getting IntelliSense from props

Hello,
I've been struggling with getting completion on props given by a parent component in .vue files.

<template>
    <div>
        {{myClass}}
    </div>
</template>

<script lang="ts">
import Vue from "vue";
import { TestClass } from '../types/TestClass'; // TestClass interface in a .d.ts

export default Vue.extend({
    props: ['testClass'],
    mounted() {
        console.log(this.testClass);
    }
});
</script>

My goal is to have autocompletion inside the template on the myClass object of type TestClass. So I'm trying to find a way to type my variable.

Here's what I've tried until now:

Using a computed property which return the type I want. No IntelliSense.

export default Vue.extend({
    computed: {
        myClass(): TestClass {
            return this.testClass;
        }
    }
)}

image

Creating a new variable in data which copy the initial value. No IntelliSense.

export default Vue.extend({
    data() {
        return {
            myClass: <TestClass> this.testClass
        }
    }
)}

Change props declaration to be able to specify the type.
error TS2693: 'TestClass' only refers to a type, but is being used as a value here.

export default Vue.extend({
    props: {
        testClass: TestClass
    },
)}

Obviously the same error when trying to set the type property

export default Vue.extend({
    props: {
        testClass: {
            type: TestClass
        }
    },
)}

I feel like I'm just hitting a wall because this is not supported, which is kind of a bummer because I wanted the power of TypeScript combined with Vue.
I may have missed something or I'm just doing it wrong, if anyone have an idea please share :)

Can't load vue from webpack alias

I cant get vue 'vue/types/index' from like this,

//main.ts 

import vue from 'vue'

But I want to use some vue plugin ,so I have to use vue from 'vue/dist/vue.esm.js'
.Not from 'vue/types/index'。I add webpack alias but it doesn't work.
image

image

How cant I use both vue (js and ts) in my project ?

TypeScript interface is not working as expected, inside '.vue' files.

TypeScript interface doesn't work as expected with '*.vue' files. it doesn't throw any "warning" when provided type is bad. Example form vue.js file:

<script lang="ts">

    interface Test {
       w: string;
       h: number;
    }

   // This part of code doesn't work. 
   // It doesn't show any message about 
   // type incompatibility 
   //(propert h must have "number" type).

   let myVar: Test = {
       w: "10",
       h: "26",
   };

   //At the same time this code works correctly in '.ts' files.

   </script>

My devDependencies info:

"devDependencies": {
"babel-plugin-transform-object-rest-spread": "",
"cross-env": "^3.2.3",
"laravel-mix": "0.",
"normalize.css": "",
"pug": "",
"ts-loader": "^2.2.0",
"typescript": "^2.3.4",
"vue": "",
"vue-resource": "",
"vue-router": "*"
},

I use:

Laravel framework(use 'WebPack', 'laravel-mix' - that gives default webpack setting and opportunity to modify them)

About typescript+vuejs configuration:
I was using this instructions to configure my VueJs project: https://github.com/Microsoft/TypeScript-Vue-Starter . According to them I installed next NPM packages:

  • typescript
  • ts-loader
  • and created file: 'vue-shims.d.ts.'
  • added lang="ts" to my <script> section inside '*.vue' file.

My 'tsconfig.json' file settings:

{
  "compilerOptions": {
    "sourceMap": true,
    "strict": true,
    "noImplicitReturns": true,
    "module": "es2015",
    "moduleResolution": "node",
    "target": "es5",
    "allowSyntheticDefaultImports": true,
    "lib": [
      "dom",
      "es5",
      "es2015.promise"
    ]
  },
  "include": [
    "./resources/**/*"   //Folder with my '.ts' and '.vue' files.
  ]
}

My web pack settings:

mix.webpackConfig({
    module: {
        rules: [
            {
                test: /\.tsx?$/,
                loader: 'ts-loader',
                exclude: /node_modules/,
                options: {
                    appendTsSuffixTo: [/\.vue$/],
                },
            },
        ],
    },
    resolve: {
        extensions: ['.ts', '.js', '.vue', '.json'],
        alias: {
            'vue$': 'vue/dist/vue.esm.js',
        },
    },
});

Typing on props

It's great that my props are recognized, but the props are all type "any", which doesn't help me much.
I see that extend is generic, and the last property is for props. But I can't make heads or tails of what to do with that.

is it possible having .vue file path resolved?

if you import an non-existance typescript module like this

import mymodule from './src/non-existance-path/unknowfile.ts'

you will get an error show that cannot find module ./src/non-existance-path/unknowfile.ts

but when if import *.vue single file modules
for instance in index.ts

// this is valid import
import HelloDecoratorComponent from "./components/HelloDecorator.vue";

// this is invalid import because there is no file "./components/HelloDeccorator.vue"
import HelloDecoratorComponent2 from "./components/HelloDeccorator.vue";

// this is invalid import because there is no file "./components/HelloDecorator_wtfisthisJKLQ#H@!*(.vue"
import HelloDecoratorComponent2 from "./components/HelloDecorator_wtfisthisJKLQ#H@!*(.vue";

the second import is invalid because of the import name typo (double c in deCCorator.vue), also the third one is invalid too.

I know that .vue file type is defined in vue-shims.d.ts,

but typescript engine doesn't resolve these file paths, and there is no error report when coding index.ts as you have import typo causes an invalid import.

is it possible to let typescript engine resolve these .vue file paths?

loader error

I set up the project according to the above steps,npm run build时报错,I change the ts-loader ,the erros still have ,but different
errors:
ERROR in ./src/components/Hello.vue?vue&type=script&lang=ts
Module parse failed: Unexpected token (28:26)
You may need an appropriate loader to handle this file type.
| },
| computed: {
| exclamationMarks(): string {
| return Array(this.enthusiasm + 1).join('!');
| }
@ ./src/components/Hello.vue 2:0-56 3:0-51 3:0-51 10:2-8
@ ./src/index.ts

ERROR in ./src/components/Hello.vue?vue&type=template&id=5de655f2
Module parse failed: Unexpected token (2:0)
You may need an appropriate loader to handle this file type.
|
|


|
Hello {{name}}{{exclamationMarks}}

| <button @click="decrement">-
@ ./src/components/Hello.vue 1:0-83 11:2-8 12:2-17
@ ./src/index.ts

ERROR in ./src/components/Hello.vue?vue&type=style&index=0&lang=css
Module parse failed: Unexpected token (36:0)
You may need an appropriate loader to handle this file type.
|
|
| .greeting {
| font-size: 20px;
| }
@ ./src/components/Hello.vue 4:0-64
@ ./src/index.ts

ERROR in ./src/components/Hello.vue
vue-loader was used without the corresponding plugin. Make sure to include VueLoaderPlugin in your webpack config.
@ ./src/index.ts 2:0-52 8:24-38

ERROR in ./src/components/Hello.vue?vue&type=template&id=5de655f2
vue-loader was used without the corresponding plugin. Make sure to include VueLoaderPlugin in your webpack config.
@ ./src/components/Hello.vue 1:0-83 11:2-8 12:2-17
@ ./src/index.ts

ERROR in ./src/components/Hello.vue?vue&type=script&lang=ts
vue-loader was used without the corresponding plugin. Make sure to include VueLoaderPlugin in your webpack config.
@ ./src/components/Hello.vue 2:0-56 3:0-51 3:0-51 10:2-8
@ ./src/index.ts

ERROR in ./src/components/Hello.vue?vue&type=style&index=0&lang=css
vue-loader was used without the corresponding plugin. Make sure to include VueLoaderPlugin in your webpack config.
@ ./src/components/Hello.vue 4:0-64
@ ./src/index.ts

Can't import Hello.vue component

I'm trying to to run npm run build and I am getting this error

ERROR in ./src/components/Hello.vue (./node_modules/ts-loader!./node_modules/vue-loader/lib/selector.js?type=script&index=0!./src/components/Hello.vue)
Module not found: Error: Can't resolve './components/Hello.vue' in 'D:\Projects\typescript-vue-tutorial\src\components'  @ ./src/components/Hello.vue (./node_modules/ts-loader!./node_modules/vue-loader/lib/selector.js?type=script&index=0!./src/components/Hello.vue) 2:0-52 10:24-38
 @ ./src/components/Hello.vue
 @ ./src/index.ts

ERROR in D:\Projects\typescript-vue-tutorial\src\index.ts
[tsl] ERROR in D:\Projects\typescript-vue-tutorial\src\index.ts(2,28)
      TS2307: Cannot find module './components/Hello.vue'.

image

I can't figure it out. I am already using "vue-loader": "^14.2.2"

Not identifying imported components in template

I cannot get my template to recognize imported components and props. Is this a known issue? I've tried different setups and IDE's but I run into the same problem. The project compiles fine, but it's frustrating when the IDE doesn't recognize any custom components.

screen shot 2018-10-01 at 09 55 43

vue-loader was used without the corresponding plugin

Trying to do the Single File Component section, and I'm getting this error and I try to do npm run build:

ERROR in ./src/components/Hello.vue
Module Error (from ./node_modules/vue-loader/lib/index.js):
vue-loader was used without the corresponding plugin. Make sure to include VueLoaderPlugin in your webpack config.
@ ./src/index.ts 3:0-52 9:24-38

ERROR in ./src/components/Hello.vue?vue&type=template&id=5de655f2 2:0
Module parse failed: Unexpected token (2:0)
You may need an appropriate loader to handle this file type.
|

|

Hello {{name}}{{exclamationMarks}}

| <button @click="decrement">-
@ ./src/components/Hello.vue 1:0-83 11:2-8 12:2-17
@ ./src/index.ts

ERROR in ./src/components/Hello.vue?vue&type=script&lang=ts 30:26
Module parse failed: Unexpected token (30:26)
You may need an appropriate loader to handle this file type.
| },
| computed: {

    exclamationMarks(): string {

| return Array(this.enthusiasm + 1).join('!');
| }
@ ./src/components/Hello.vue 2:0-56 3:0-51 3:0-51 10:2-8
@ ./src/index.ts

ERROR in ./src/components/Hello.vue?vue&type=style&index=0&lang=css 38:0
Module parse failed: Unexpected token (38:0)
You may need an appropriate loader to handle this file type.
|
|

.greeting {
| font-size: 20px;
| }
@ ./src/components/Hello.vue 4:0-64
@ ./src/index.ts

Sorry if I missed anything obvious, I'm new to web development.

Does not build, got errors TS1238 and TS2509

➜  TypeScript-Vue-Starter git:(master) ✗ yarn
yarn install v1.5.1
[1/4] 🔍  Resolving packages...
success Already up-to-date.
✨  Done in 0.39s.
➜  TypeScript-Vue-Starter git:(master) ✗ npm run build

> [email protected] build /Users/fermigier/git/vue/TypeScript-Vue-Starter
> webpack

ts-loader: Using [email protected] and /Users/fermigier/git/vue/TypeScript-Vue-Starter/tsconfig.json
Hash: e7974bc5938b571dfaab
Version: webpack 2.5.0
Time: 2370ms
   Asset     Size  Chunks                    Chunk Names
build.js  1.08 MB       0  [emitted]  [big]  main
   [0] ./~/vue/dist/vue.esm.js 292 kB {0} [built]
   [1] ./~/process/browser.js 5.42 kB {0} [built]
   [2] (webpack)/buildin/global.js 509 bytes {0} [built]
   [3] ./~/css-loader/lib/css-base.js 2.26 kB {0} [built]
   [4] ./~/vue-loader/lib/component-normalizer.js 2.55 kB {0} [built]
   [5] ./~/vue-style-loader/lib/addStylesClient.js 6.05 kB {0} [built]
  [10] ./~/reflect-metadata/Reflect.js 52.3 kB {0} [built]
  [11] ./~/setimmediate/setImmediate.js 6.47 kB {0} [built]
  [12] ./~/timers-browserify/main.js 1.36 kB {0} [built]
  [15] ./src/index.ts 666 bytes {0} [built]
  [16] ./~/vue-class-component/dist/vue-class-component.common.js 8.05 kB {0} [built]
  [19] ./~/vue-property-decorator/lib/vue-property-decorator.umd.js 4.85 kB {0} [built]
  [22] ./~/vue-style-loader/lib/listToStyles.js 639 bytes {0} [built]
    + 10 hidden modules

ERROR in /Users/fermigier/git/vue/TypeScript-Vue-Starter/src/components/HelloDecorator.vue.ts
(14,1): error TS1238: Unable to resolve signature of class decorator when called as an expression.
  Type '<VC extends VueClass<Vue>>(target: VC) => VC' is not assignable to type 'typeof HelloDecorator'.
    Property 'extend' is missing in type '<VC extends VueClass<Vue>>(target: VC) => VC'.

ERROR in /Users/fermigier/git/vue/TypeScript-Vue-Starter/src/components/HelloDecorator.vue.ts
(15,45): error TS2509: Base constructor return type 'CombinedVueInstance<Vue, Data, Methods, Computed, Record<PropNames, any>>' is not a class or interface type.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.