欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

如何用vue-cli3腳手架搭建一個基于ts的基礎(chǔ)腳手架的方法

 更新時間:2019年12月12日 09:00:13   作者:慕晗  
這篇文章主要介紹了如何用vue-cli3腳手架搭建一個基于ts的基礎(chǔ)腳手架的方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

忙里偷閑,整理了一下關(guān)于如何借助 vue-cli3 搭建 ts + 裝飾器 的腳手架,并如何自定義 webpack 配置,優(yōu)化。

準(zhǔn)備工作

  • @vue/cli@4.1.1
  • vue 2.6
  • node v12.13.0

安裝 node

  • 安裝 node
  • 全局安裝 nrm,npm 的鏡像源管理工具。
npm i nrm -g // 安裝
nrm ls // 查看可用源,及當(dāng)前源,帶*的是當(dāng)前使用的源
nrm use taobao // 切換源,使用源
nrm add <registry> <url> // 其中reigstry為源名,url為源的路徑
nrm del <registry> // 刪除對應(yīng)的源
nrm test npm // 測試源的響應(yīng)速度

安裝 vue-cli3

參考官方文檔:https://cli.vuejs.org/zh/guide/

npm i @vue/cli -g // 全局安裝

vue --version // 檢查是否安裝

補(bǔ)充

npm list -g --depth 0 // 查看全局安裝的包
npm outdated -g --depth=0 // 查看需要更新的全局包
npm update 包名 -g // 更新全局安裝的包

搭建項目

可參考:使用Vue-cli 3.0搭建Vue項目

新建一個基于 ts 的 vue 項目

vue create vue-cli3-ts

備注:如果是 window 系統(tǒng),用 git bash 交互提示符(切換)不會工作,用以下命令,即可解決:

winpty vue.cmd create vue-cli3-ts
  • 自定義選項 - Manually select features
  • 添加 ts 支持 - TypeScript
  • 基于類的組件 - y
  • tslint
  • 根據(jù)需要添加 router、vuex、css(less 或 scss) 預(yù)處理器、單元測試(jest)

交互說明:

  • 上下箭頭鍵切換
  • 空格鍵選中
  • 回車確定

在已存在的項目中添加 ts

vue add @vue/typescript

會把所有 .js 更改為 .ts

script 命令

// - 啟動服務(wù)
npm run serve
// - 打包編譯
npm run build
// - 執(zhí)行l(wèi)int
npm run lint
// - 執(zhí)行單元測試
npm run test:unit

npm run serve 啟動服務(wù):http://localhost:8080/#/

vue 中 ts 語法

demo: src/components/HelloWorld.vue

<script lang="ts">
import { Component, Prop, Vue } from 'vue-property-decorator';

@Component
export default class HelloWorld extends Vue {
 @Prop() private msg!: string;
}
</script>

和普通的 vue 項目不一樣的就是.vue 文件中 script 的 寫法。

主要用到的一個庫:vue-property-decorator

用法可參考:

1. 類型注解,類型推論

  • 變量后面通過 冒號+類型 來做類型注解。
  • 編譯時類型檢查,寫代碼時代碼提醒。
  • 類型推論,根據(jù)賦值類型推論出被賦值變量的類型,進(jìn)行類型限制。
let title: string; // 類型注解
title = 'ts'; // 正確
title = 4; // 錯誤

let text = 'txt'; // 類型推論
text = 2; // 錯誤

錯誤時,vscode 編輯器會有紅色波浪號提示。

數(shù)組

let names: string[]; // Array<string>
names = ['Tom'];

任意類型,沒有類型限制

let foo: any;
foo = 'foo';
foo = 3;

let list: any[];
list = [1, true, 'free'];
list[1] = 100;

函數(shù)中使用類型

function greeting (person: string): string {
 return 'Hello, ' + person;
}

// void 類型,常用于沒有返回值的函數(shù)
function warnUser (): void {
 alert('This is msg');
}

案例:vue demo

<template>
 <div class="hello">
 <input type="text" placeholder="請輸入新特性" @keyup.enter="addFeature" />
 <ul>
 <li v-for="feature in features" :key="feature">{{feature}}</li>
 </ul>
 </div>
</template>

<script lang="ts">
import { Component, Prop, Vue } from 'vue-property-decorator';

@Component
export default class Demo extends Vue {

 // 相當(dāng)于 data 中的數(shù)據(jù)項
 features: string[];
 constructor () {
 super();
 this.features = ['類型注解', '類型推論', '編譯型語言'];
 }

 // 相當(dāng)于 methods 中的方法
 addFeature (event: any) {
 console.log(event);
 this.features.push(event.target.value);
 event.target.value = '';
 }
}
</script>

2.類

ts 中的類和 es6 中的大體相同,關(guān)注特性 訪問修飾符

  • private 私有屬性,不能在類的外部訪問
  • protected 保護(hù)屬性,可以在類的內(nèi)部和派生類的內(nèi)部訪問,不能在類的外部訪問
  • public 公有屬性,可以在任意地方訪問,默認(rèn)值
  • readonly 只讀屬性,必須在聲明時或構(gòu)造函數(shù)里初始化,不可改變值

構(gòu)造函數(shù):初始化成員變量,參數(shù)加上修飾符,能夠定義并初始化一個屬性

constructor (private name = 'Tom') {
 super();
}

等同于

name: string;
constructor () {
 super();
 this.name = 'Tom';
}

存取器,暴露存取數(shù)據(jù)時可添加額外邏輯;在 vue 中可用作計算屬性

get fullName () { return this.name; }
set fullName (val) { this.name = val; }

案例:vue demo

<template>
 <p>特性數(shù)量:{{count}}</p>
</template>
<script lang="ts">
 export default class Demo extends Vue {
 // 定義 getter 作為計算屬性
 get count () {
  return this.features.length;
 }
 }
</script>

接口

接口僅約束結(jié)構(gòu),不要求實(shí)現(xiàn)

interface Person {
 firstName: string;
 lastName: string;
}
function greeting (person: Person) {
 return `Hello, ${person.firstName} ${person.lastName}`;
}
const user = {firstName: 'Jane', lastName: 'user'};
console.log(greeting(user));

案例:vue demo,聲明接口類型約束數(shù)據(jù)結(jié)構(gòu)

<template>
 <li v-for="feature in features" :key="feature.id">{{feature.name}}</li>
</template>
<script lang="ts">
 // 定義一個接口約束feature的數(shù)據(jù)結(jié)構(gòu)
 interface Feature {
 id: number;
 name: string;
 }
 
 export default class Demo extends Vue {
 private features: Feature[];
 
 constructor () {
  super();
  
  this.features = [
  {id: 1, name: '類型注解'},
  {id: 2, name: '類型推論'},
  {id: 3, name: '編譯型語言'}
  ]
 }
 }
</script>

泛型

泛型 是指在定義函數(shù)、接口或類的時候,不預(yù)先指定具體的類,而是在使用時才指定類型的一種特性。

interface Result<T> {
 data: T;
}

// 不使用泛型
interface Result {
 data: Feature[];
}

案例:使用泛型約束接口返回類型

function getData<T>(): Result<T> {
 const data: any = [
 {id: 1, name: '類型注解'},
 {id: 2, name: '類型推論'},
 {id: 3, name: '編譯型語言'} 
 ];
 return {data};
}

// 調(diào)用
this.features = getData<Feature[]>().data;

案例:使用泛型約束接口返回類型 Promise

function getData<T>(): Promise<Result<T>> {
 const data: any = [
 {id: 1, name: '類型注解'},
 {id: 2, name: '類型推論'},
 {id: 3, name: '編譯型語言'} 
 ];
 return Promise.resolve<Result<T>>({data});
}

// 調(diào)用 async 方式
async mounted () {
 this.features = (await getData<Feature[]>()).data;
}

// 調(diào)用 then 方式
mouted () {
 getData<Feature[]>().then((res: Result<Feature[]>) => {
 this.features = res.data;
 })
}

裝飾器

裝飾器用于擴(kuò)展類或者它的屬性和方法。

屬性聲明:@Prop

除了在 @Component 中聲明,還可以采用@Prop的方式聲明組件屬性

export default class Demo extends Vue {
 // Props() 參數(shù)是為 vue 提供屬性選項
 // !稱為明確賦值斷言,它是提供給ts的
 @Prop({type: String, require: true})
 private msg!: string;
}

事件處理:@Emit

// 通知父類新增事件,若未指定事件名則函數(shù)名作為事件名(駝峰變中劃線分隔)
@Emit()
private addFeature(event: any) {// 若沒有返回值形參將作為事件參數(shù)
 const feature = { name: event.target.value, id: this.features.length + 1 };
 this.features.push(feature);
 event.target.value = "";
 return feature;// 若有返回值則返回值作為事件參數(shù)
}

template 模板組件上正常寫,@add-feature

變更監(jiān)測:@Watch

@Watch('msg')
onRouteChange(val:string, oldVal:any){
 console.log(val, oldVal);
}

裝飾器原理

裝飾器本質(zhì)是工廠函數(shù),修改傳入的類、方法、屬性等

類裝飾器

// 類裝飾器表達(dá)式會在運(yùn)行時當(dāng)作函數(shù)被調(diào)用,類的構(gòu)造函數(shù)作為其唯一的參數(shù)。
function log(target: Function) {
 // target是構(gòu)造函數(shù)
 console.log(target === Foo); // true
 target.prototype.log = function() {
 console.log(this.bar);
}
// 如果類裝飾器返回一個值,它會使用提供的構(gòu)造函數(shù)來替換類的聲明。
}
@log
class Foo {
 bar = 'bar'
}
const foo = new Foo();
// @ts-ignore
foo.log();

實(shí)戰(zhàn)一下 Component,新建 Decor.vue

<template>
 <div>{{msg}}</div>
</template>
<script lang='ts'>
 import { Vue } from "vue-property-decorator";
 function Component(options: any) {
 return function(target: any) {
  return Vue.extend(options);
 };
 }
 
 @Component({
 props: {
  msg: {
  type: String,
  default: ""
  }
 }
 })
 export default class Decor extends Vue {}
</script>

源碼簡單了解

類裝飾器主要依賴庫:vue-class-component,深入源碼,了解其背后究竟做了什么。

vue-property-decorator.js

import Vue from 'vue';
import Component, { createDecorator, mixins } from 'vue-class-component';
export { Component, Vue, mixins as Mixins };

createDecorator、applyMetadata 是核心,后續(xù)實(shí)現(xiàn)都依賴它,比如 Prop、Watch、Ref。

Prop 源碼實(shí)現(xiàn):

export function Prop(options) {
 if (options === void 0) { options = {}; }
 return function (target, key) {
 applyMetadata(options, target, key);
 createDecorator(function (componentOptions, k) {
  ;
  (componentOptions.props || (componentOptions.props = {}))[k] = options;
 })(target, key);
 };
}

applyMetadata,見名知義,就是將裝飾器中的信息拿出來放到 options.type 中。

/** @see {@link https://github.com/vuejs/vue-class-component/blob/master/src/reflect.ts} */
var reflectMetadataIsSupported = typeof Reflect !== 'undefined' && typeof Reflect.getMetadata !== 'undefined';
function applyMetadata(options, target, key) {
 if (reflectMetadataIsSupported) {
 if (!Array.isArray(options) &&
  typeof options !== 'function' &&
  typeof options.type === 'undefined') {
  options.type = Reflect.getMetadata('design:type', target, key);
 }
 }
}

Reflect.getMetadata 獲取設(shè)置在類裝飾器上的元數(shù)據(jù)??蓞⒖嘉恼吕斫猓?/p>

createDecorator,見名知義,就是創(chuàng)建裝飾器。本質(zhì)是在類上定義一個私有屬性

export function createDecorator(factory) {
 return function (target, key, index) {
 var Ctor = typeof target === 'function'
  ? target
  : target.constructor;
 if (!Ctor.__decorators__) {
  Ctor.__decorators__ = [];
 }
 if (typeof index !== 'number') {
  index = undefined;
 }
 Ctor.__decorators__.push(function (options) { return factory(options, key, index); });
 };
}

項目代理及 webpack 性能優(yōu)化

在項目根目錄下新建 vue.config.js

本地開發(fā) api 代理

module.exports = {
 devServer: {
 proxy: {
  '/api': {
  target: '<url>',
  changeOrigin: true,
  pathRewrite: {
  '^/api': ''
  }
  }
 }
 }
}

本地開發(fā) api 模擬

devServer: {
 before (app) {
 before (app) {
  app.get('/api/getList', (req, res) => {
  res.json({data: [{id: 1, name: 'vue'}]})
  })
 }
 }
}

性能優(yōu)化

查看打包依賴

在 package.json 文件 script 中加入命令:

"build:report": "vue-cli-service build --report"

會在 dist 目錄下生成 report.html,可直接打開,查看打包依賴,進(jìn)行分析,進(jìn)行打包優(yōu)化

打包優(yōu)化 - cdn 引入公共庫

在 vue.config.js 中加入配置:

configureWebpack: {
 externals: { // cdn 外鏈,避免包太大,首屏優(yōu)化
 'vue': 'Vue',
 'vue-router': 'VueRouter',
 'vuex': 'Vuex'
 }
}

在 public/index.html 中加入 cdn 庫地址

<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.10/vue.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/vue-router/3.1.3/vue-router.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/vuex/3.1.2/vuex.min.js"></script>

<!-- built files will be auto injected -->

再次優(yōu)化,html head 信息中加,dns 域名預(yù)解析,js 庫 reload 預(yù)加載。

<link rel="dns-prefetch" href="cdnjs.cloudflare.com" rel="external nofollow" >
<link  rel="preload" as="script">
<link  rel="preload" as="script">
<link  rel="preload" as="script">

其他

修改本地開發(fā)端口號,在 vue.config.js 中加入配置:

devServer: {
 port: 8888
}

體驗(yàn)優(yōu)化-打包完成提示:

const WebpackBuildNotifierPlugin = require('webpack-build-notifier');
const path = require('path');

module.exports = {
 // 鏈?zhǔn)讲僮?
 chainWebpack: config => {
 // 移除 prefetch 插件,移動端對帶寬敏感
 // 路由懶加載,只對用戶頻繁操作的路由,通過 注釋 提前獲取
 // component: () => import(/* webpackChunkName: "about" */ /* webpackPrefetch: true */'../views/About.vue')
 config.plugins.delete('prefetch');
 
 // 生產(chǎn)打包才提示,開發(fā)不提示
 if (process.env.NODE_ENV === 'production') {
  config.plugin('build-notify').use(WebpackBuildNotifierPlugin, [{
  title: "My Project Webpack Build",
  logo: path.resolve("./img/favicon.png"),
  suppressSuccess: true
  }])
 }
 }
}

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • vue.js中mint-ui框架的使用方法

    vue.js中mint-ui框架的使用方法

    這篇文章主要為大家詳細(xì)介紹了vue.js中使用mint-ui框架的相關(guān)資料,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-05-05
  • vue3中項目優(yōu)化方法詳解(Web?Worker的使用)

    vue3中項目優(yōu)化方法詳解(Web?Worker的使用)

    最近在做vue3的項目中,遇到了計算量龐大導(dǎo)致頁面響應(yīng)緩慢的問題,所以下面這篇文章主要給大家介紹了關(guān)于vue3中項目優(yōu)化方法的相關(guān)資料,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2024-07-07
  • vue-model實(shí)現(xiàn)簡易計算器

    vue-model實(shí)現(xiàn)簡易計算器

    這篇文章主要為大家詳細(xì)介紹了vue-model實(shí)現(xiàn)簡易計算器,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-08-08
  • vue調(diào)用本地攝像頭實(shí)現(xiàn)拍照功能

    vue調(diào)用本地攝像頭實(shí)現(xiàn)拍照功能

    這篇文章主要介紹了vue調(diào)用本地攝像頭實(shí)現(xiàn)拍照功能,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-08-08
  • VUE 實(shí)現(xiàn)復(fù)制內(nèi)容到剪貼板的兩種方法

    VUE 實(shí)現(xiàn)復(fù)制內(nèi)容到剪貼板的兩種方法

    這篇文章主要介紹了VUE 實(shí)現(xiàn)復(fù)制內(nèi)容到剪貼板功能,本文通過兩種方法,給大家介紹的非常詳細(xì),具有一定的參考借鑒價值 ,需要的朋友可以參考下
    2019-04-04
  • 基于vue cli重構(gòu)多頁面腳手架過程詳解

    基于vue cli重構(gòu)多頁面腳手架過程詳解

    本文分步驟給大家介紹了基于vue cli重構(gòu)多頁面腳手架過程,非常不錯,具有參考借鑒價值,需要的朋友參考下
    2018-01-01
  • Vue Vine實(shí)現(xiàn)一個文件中寫多個組件的方法(最近很火)

    Vue Vine實(shí)現(xiàn)一個文件中寫多個組件的方法(最近很火)

    Vue Vine提供了全新Vue組件書寫方式,主要的賣點(diǎn)是可以在一個文件里面寫多個vue組件,Vue Vine是一個vite插件,vite解析每個模塊時都會觸發(fā)插件的transform鉤子函數(shù),本文介紹Vue Vine是如何實(shí)現(xiàn)一個文件中寫多個組件,感興趣的朋友一起看看吧
    2024-07-07
  • 5個可以加速開發(fā)的VueUse函數(shù)庫(小結(jié))

    5個可以加速開發(fā)的VueUse函數(shù)庫(小結(jié))

    VueUse為Vue開發(fā)人員提供了大量適用于Vue2和Vue3的基本Composition API 實(shí)用程序函數(shù)。具有一定的參考價值,感興趣的可以了解一下
    2021-11-11
  • 如何通過Vue實(shí)現(xiàn)@人的功能

    如何通過Vue實(shí)現(xiàn)@人的功能

    這篇文章主要介紹了如何通過vue實(shí)現(xiàn)微博中常見的@人的功能,同時增加鼠標(biāo)點(diǎn)擊事件和一些頁面小優(yōu)化。感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2021-12-12
  • Vue3+ElementPlus el-date-picker設(shè)置可選時間范圍的示例代碼

    Vue3+ElementPlus el-date-picker設(shè)置可選時間范圍的示例代碼

    在Vue3中使用Element Plus的el-date-picker組件設(shè)置可選時間范圍,你可以使用disabled-date屬性,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友參考下吧
    2023-07-07

最新評論