vue-typescript

教你搭建typescript的vue項目

自尤大神去年9月推出vue對typescript的支持后,一直想開箱嘗試vue+ts,最近一個新項目準備入手typescript,也遇到了很多坑,下面就一步步來吧!!!

1. 項目創建和初始化

1.1 安裝腳手架、創建項目

全局安裝 vue-cli腳手架

$ npm install -g @vue/cli
復制代碼

等待安裝完成后開始下一步,檢查是否安裝成功: Vue -v

1.2. 初始化項目

$ vue create vue-ts
復制代碼
  1. 選擇預設的模板
    選擇更多功能 Manully select features
    回車后來到選擇插件
  2. 選擇插件
    這邊選擇了(Babel、Typescript、Router、Css預處理器、Linter / Formatter 格式檢查、Unit測試框架)
    使用鍵盤空格選擇插件
  3. 自動檢測typescript(yes)
  4. 路由模式選擇
    是否使用 history模式的路由 (Yes)
  5. 選擇一個css預處理器 (Sass/SCSS)
  6. 選擇格式檢查規則(什么時候進行 tslint 校驗: Line on save)
  7. 是否保存這份預設配置?(yes)
    選是的話,下次創建一個vue項目,可以直接使用這個預設文件,而無需再進行新的配置,直接使用選擇的模板創建項目

等待所有的依賴完成

通過node生產組件和頁面是基于lentoo的vuecli3-project基礎上稍作更改

2. 通過node來生成組件

安裝chalk

$ npm install chalk --save-dev
復制代碼

在根目錄中創建一個 scripts 文件夾,

2.1. 通過node來生成組件

新增一個generateComponent.js文件,放置生成組件的代碼、

新增一個template.js文件,放置組件模板的代碼 template.js文件

    /*** 將駝峰命名轉為中橫杠例如:PlInputGroup --> pl-input-group* @param str */
function toMiddleLine (str) {let temp = str.replace(/[A-Z]/g,function (match) {return "-" + match.toLowerCase()});if (temp.slice(0, 1) === '-') { //如果首字母是大寫,執行replace時會多一個-,這里需要去掉temp = temp.slice(1)}return temp;
}/*** 首字母大寫* @param {*} str 字符串* @returns*/
function initialToUp (str) {  return str.slice(0, 1).toUpperCase() + str.slice(1);  
}module.exports = {
vueTemplate: componentName => {return `<template><div class="${toMiddleLine(componentName)}">${toMiddleLine(componentName)}</div>
</template><script lang="ts">import { Vue, Component, Prop, Watch, Emit, Provide, Inject } from 'vue-property-decorator'@Component({})export default class ${initialToUp(componentName)} extends Vue {}
</script><style lang="scss" scoped>
// @import './style.scss';
.${toMiddleLine(componentName)} {}
</style>`
},
styleTemplate: componentName => {return `.${toMiddleLine(componentName)} {}`
},
entryTemplate: `import Main from './main.vue'
export default Main
`
}復制代碼

generateComponent.js文件

const chalk = require('chalk')
const path = require('path')
const fs = require('fs')const resolve = (...file) => path.resolve(__dirname, ...file)
const log = message => console.log(chalk.green(`${message}`))
const successLog = message => console.log(chalk.blue(`${message}`))
const errorLog = error => console.log(chalk.red(`${error}`))
const { vueTemplate, entryTemplate, styleTemplate } = require('./template')const generateFile = (path, data) => {if (fs.existsSync(path)) {errorLog(`${path}文件已存在`)return}return new Promise((resolve, reject) => {fs.writeFile(path, data, 'utf8', err => {if (err) {errorLog(err.message)reject(err)} else {resolve(true)}})})
}
log('請輸入要生成的組件名稱、如需生成全局組件,請加 global/ 前綴')
let componentName = ''
process.stdin.on('data', async chunk => {const inputName = String(chunk).trim().toString()/*** 組件目錄路徑*/const componentDirectory = resolve('../src/components', inputName)/*** vue組件路徑*/const componentVueName = resolve(componentDirectory, 'main.vue')/*** 入口文件路徑*/const entryComponentName = resolve(componentDirectory, 'index.ts')/*** style樣式路徑*/const styleComponentName = resolve(componentDirectory, 'style.less')const hasComponentDirectory = fs.existsSync(componentDirectory)if (hasComponentDirectory) {errorLog(`${inputName}組件目錄已存在,請重新輸入`)return} else {log(`正在生成 component 目錄 ${componentDirectory}`)await dotExistDirectoryCreate(componentDirectory)// fs.mkdirSync(componentDirectory);}try {if (inputName.includes('/')) {const inputArr = inputName.split('/')componentName = inputArr[inputArr.length - 1]} else {componentName = inputName}log(`正在生成 vue 文件 ${componentVueName}`)await generateFile(componentVueName, vueTemplate(componentName))log(`正在生成 entry 文件 ${entryComponentName}`)await generateFile(entryComponentName, entryTemplate)log(`正在生成 style 文件 ${styleComponentName}`)await generateFile(styleComponentName, styleTemplate(componentName))successLog('生成成功')} catch (e) {errorLog(e.message)}process.stdin.emit('end')
})
process.stdin.on('end', () => {log('exit')process.exit()
})
function dotExistDirectoryCreate (directory) {return new Promise((resolve) => {mkdirs(directory, function () {resolve(true)})})
}// 遞歸創建目錄
function mkdirs (directory, callback) {var exists = fs.existsSync(directory)if (exists) {callback()} else {mkdirs(path.dirname(directory), function () {fs.mkdirSync(directory)callback()})}
}復制代碼

配置package.json

"new:comp": "node ./scripts/generateComponent"
復制代碼

執行 npm / cnpm / yarn run new:comp 生成組件

2.2. 通過node來生成頁面組件

在scripts目錄下新建一個generateView.js文件

generateView.js文件

const chalk = require('chalk')
const path = require('path')
const fs = require('fs')const resolve = (...file) => path.resolve(__dirname, ...file)
const log = message => console.log(chalk.green(`${message}`))
const successLog = message => console.log(chalk.blue(`${message}`))
const errorLog = error => console.log(chalk.red(`${error}`))
const { vueTemplate } = require('./template')const generateFile = (path, data) => {if (fs.existsSync(path)) {errorLog(`${path}文件已存在`)return}return new Promise((resolve, reject) => {fs.writeFile(path, data, 'utf8', err => {if (err) {errorLog(err.message)reject(err)} else {resolve(true)}})})
}
log('請輸入要生成的頁面組件名稱、會生成在 views/目錄下')
let componentName = ''
process.stdin.on('data', async chunk => {const inputName = String(chunk).trim().toString()/*** Vue頁面組件路徑*/let componentVueName = resolve('../src/views', inputName)// 如果不是以 .vue 結尾的話,自動加上if (!componentVueName.endsWith('.vue')) {componentVueName += '.vue'}/*** vue組件目錄路徑*/const componentDirectory = path.dirname(componentVueName)const hasComponentExists = fs.existsSync(componentVueName)if (hasComponentExists) {errorLog(`${inputName}頁面組件已存在,請重新輸入`)return} else {log(`正在生成 component 目錄 ${componentDirectory}`)await dotExistDirectoryCreate(componentDirectory)}try {if (inputName.includes('/')) {const inputArr = inputName.split('/')componentName = inputArr[inputArr.length - 1]} else {componentName = inputName}log(`正在生成 vue 文件 ${componentVueName}`)await generateFile(componentVueName, vueTemplate(componentName))successLog('生成成功')} catch (e) {errorLog(e.message)}process.stdin.emit('end')
})
process.stdin.on('end', () => {log('exit')process.exit()
})
function dotExistDirectoryCreate (directory) {return new Promise((resolve) => {mkdirs(directory, function () {resolve(true)})})
}// 遞歸創建目錄
function mkdirs (directory, callback) {var exists = fs.existsSync(directory)if (exists) {callback()} else {mkdirs(path.dirname(directory), function () {fs.mkdirSync(directory)callback()})}
}復制代碼

配置package.json

"new:view": "node ./scripts/generateView"
復制代碼

執行 npm / cnpm / yarn run new:view 生成頁面

3. vue與typescript結合

3.1. 首先組件聲明

若對vue-property-decorator庫不了解的,請點擊vue-property-decorator的了解更多

創建組件如下:

<script lang="ts">import { Component, Prop, Vue, Watch, Emit, Provide, Inject } from 'vue-property-decorator'@Componentexport default class Test extends Vue {}
</script>
復制代碼

3.2. data定義

若對ts的基本類型不了解的, 請點擊 typescript中文文檔

  private listTotal: number = 50private form: any = {addText: [],addTextarea: [],text: '',textarea: '',imgUrl: ''}
復制代碼

3.3 props聲明

  // align justify 彈性布局對齊方式@Prop({default: 'center'})private align!: string@Prop({default: 'flex-start'})private justify!: string// 千萬不要這樣定義 @Prop private align: string = 'center' ---> 踩
</script>
復制代碼

3.4 vue生命周期及自定義方法

methods不需要像vue里面 methods: { text () {return console.log(222)} }

  public created (): void {}public mounted (): void {}public handleClick () {} // methods定義
復制代碼

3.5 Watch

  // 監聽路由變化@Watch('$route')onRouteChanged(route: any, oldRoute: any):void {console.log(route, oldRoute)}
復制代碼

3.6 computed

 public get msg () {return 'from typescript'}
復制代碼

3.7 Emit

  @Emit('change')private methodName(x: number, y: string) {console.log('child to parent a value')}
復制代碼

5. 踩坑

5.1 tinymac富文本編輯器的結合ts的使用,tiny中文文檔

引入tinymac的時候,會報錯

解決方法:src目錄下面新建一個shims-tinymce.d.ts文件

declare module 'tinymce/tinymce'
復制代碼

重新啟動項目就ok了

5.2 主題、樣式、語言配置

  1. 主題

引入主題報錯import 'tinymce/themes/modern/theme'

可以使用sliver主題

   import 'tinymce/themes/silver/theme'
復制代碼
  1. 樣式及語言漢化

在public目錄新建的static文件

2.1 將node_modules/tinymce/skins文件拷貝到static中

2.2 zh_CN.js 下載,拷貝到static文件中

5.3 引入主題,樣式,語言包

配置如下

public editorInit: any = {language_url: '/static/zh_CN.js',language: 'zh_CN',selector: 'textarea',skin_url: '/static/skins/ui/oxide',height: 300,browser_spellcheck: true, // 拼寫檢查branding: false, // 去水印// elementpath: false,  //禁用編輯器底部的狀態欄statusbar: false, // 隱藏編輯器底部的狀態欄paste_data_images: true, // 允許粘貼圖像plugins: setPlugins,toolbar: setToolbar,// 啟用菜單欄并顯示如下項 [文件 編輯 插入 格式 表格]menubar: 'file edit insert view format table',// 配置每個菜單欄的子菜單項(如下是默認配置)menu: {file: {title: 'File',items: 'newdocument'},edit: {title: 'Edit',items: 'undo redo | cut copy paste pastetext | selectall'},insert: {title: 'Insert',items: 'link media | template hr'},view: {title: 'View',items: 'visualaid'},format: {title: 'Format',items: 'bold italic underline strikethrough superscript subscript | formats | removeformat'},table: {title: 'Table',items: 'inserttable tableprops deletetable | cell row column'}},// 覆蓋默認的字體單位為ptfontsize_formats: '8px 10px 12px 14px 16px 18px 20px 24px 36px',/*** 下面方法是為tinymce添加自定義插入圖片按鈕* 也可以借助elementui的Upload組件,上傳圖片*/images_upload_url: '/api/image', // 上傳圖片接口地址images_upload_handler: (blobInfo: any, success: any, failure: any) => {let xhr: any = nulllet formData: any = nullxhr = new XMLHttpRequest()xhr.withCredentials = falsexhr.open('POST', this.$store.state.imgUrl)xhr.onload = () => {if (xhr.status < 200 || xhr.status >= 300) {failure(xhr.status)return}let json = JSON.parse(xhr.responseText)if (json.code === 0) {success(json.data[0].newFileName)} else {failure('HTTP Error: ' + json.msg)}}formData = new FormData()formData.append('file', blobInfo.blob(), blobInfo.filename())xhr.send(formData)}}
復制代碼

附上效果圖:

小結

前端小菜雞,各位大神有發現不足之處請告知,謝謝!!, 項目地址后期更新

相關資源鏈接

  1. TypeScript 體系調研報告
  2. ts通俗易懂文檔
  3. ts中文文檔
  4. vue-cli3 項目從搭建優化到docker部署

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/279595.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/279595.shtml
英文地址,請注明出處:http://en.pswp.cn/news/279595.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Couchbase概述

Couchbase概述 Couchbase概述 Couchbase概述Couchbase最早叫Membase&#xff0c;是由Memcached項目組的一些頭目另立的山頭。2011年與CouchDB合并&#xff0c;正式命名為Couchbase。2013年&#xff0c;作為NoSQL技術初創企業&#xff0c;拿到了2500萬美元的D輪投資。截稿時止&a…

Windows 2012 - Dynamic Access Control 淺析

Windows 2012相對于前幾個版本而已&#xff0c;做出了大量的改進&#xff0c;尤其體現在安全性和虛擬化方面。Dynamic Access Control ( 動態訪問控制&#xff09;是微軟在文件服務器的訪問控制上的新功能&#xff0c;極大的提高了安全性和靈活性。經過一天的研究學習&#xff…

windows rt_如何在Windows RT上輕松將網站添加到Flash白名單

windows rtMicrosoft’s Surface RT and other Windows RT-based machines include the Flash browser plugin, but it only runs on websites Microsoft has whitelisted. We have covered how you can add any website to the Flash whitelist, but now there’s an easier w…

powershell實現設置程序相關性腳本

公司一直有臺服務器cpu占用很高&#xff0c;分析出是恒生監控程序java占用很高&#xff0c;且三個java程序&#xff0c;僅其中一個很高&#xff0c;要恒生解決&#xff0c;一直未解決&#xff0c;導致每周重啟&#xff0c;我司運維都要手動進行程序相關性設置&#xff0c;給運維…

解決npm 的 shasum check failed for錯誤

使用npm安裝一些包失敗&#xff0c;類似如下報錯情況&#xff1a; C:\Program Files\nodejs>npm update npm npm ERR! Windows_NT 10.0.14393 npm ERR! argv "C:\\Program Files\\nodejs\\node.exe" "C:\\Program Files\\nodejs\\node_modules\\npm\\bin\\np…

chromebook刷機_您可以購買的最好的Chromebook,2017年版

chromebook刷機While once considered a novelty item by many tech enthusiasts, Chromebooks have broken out of the “just a browser” mold and become legitimate laptops. They’re full-featured, lightweight machines that can do everything most users need them …

Jmeter JDBC請求-----數據庫讀取數據進行參數化 通過SSH跳板機連接數據庫

前期準備&#xff1a; jdbc驅動&#xff1a;mysql-connector-java-5.1.7-bin.jar Jmeter 要鏈接MySQL數據庫&#xff0c;首選需要下載mysql jdbc驅動包&#xff08;注&#xff1a;驅動包的版本一定要與你數據庫的版本匹配&#xff0c;驅動版本低于mysql版本有可能會導致連接失敗…

Exchange server 2010 beta安裝部署流程

本文使用了微軟公開發布的exchange server 2010 beta進行部署測試。這篇文檔將用到下列產品 windows server 2008 64bit enterprise AD function at windows server 2008 exchange server 2010 beta ----------該exchange server 2010 beta版本屬于早期版本&#xff0c;目前最新…

08.15《CEP職業發展規劃課》

在12,13號的放假后&#xff0c;14,15號安排了CEP職業發展規劃課&#xff0c;為期兩天的課&#xff0c;內容也是很豐富。 在14號的早上&#xff0c;學習了職場中的基本禮儀、和基本素養的培訓&#xff0c;同時對未來的職業規劃做出了大致的分析。 在14號的下午開始了簡歷寫作的課…

usb 驅動修復_您可以修復物理損壞的USB驅動器嗎?

usb 驅動修復Sometimes accidents happen to a USB drive, and you find yourself in a very bad position when your only copy of an important document is on there. When something like this happens, is it possible to fix a physically broken USB drive? Today’s S…

大白話5分鐘帶你走進人工智能-第二十節邏輯回歸和Softmax多分類問題(5)

大白話5分鐘帶你走進人工智能-第二十節邏輯回歸和Softmax多分類問題(5) 上一節中&#xff0c;我們講解了邏輯回歸的優化&#xff0c;本節的話我們講解邏輯回歸做多分類問題以及傳統的多分類問題&#xff0c;我們用什么手段解決。 先看一個場景&#xff0c;假如我們現在的數據集…

Exchange 2016部署實施案例篇-01.架構設計篇(上)

年前就答應大家要給大家寫一個關于Exchange規劃部署的文章&#xff0c;一直忙到現在也沒有倒出時間來寫這個東西。特別是節后&#xff0c;更是開工不利啊&#xff0c;各種奇葩問題&#xff0c;真心無語了。廢話就不多說了&#xff0c;開始今天的議題。 相信各位對Microsoft Exc…

bzoj 4598: [Sdoi2016]模式字符串

題目描述 給出n個結點的樹結構T&#xff0c;其中每一個結點上有一個字符&#xff0c;這里我們所說的字符只考慮大寫字母A到Z&#xff0c;再給出長度為m的模式串s&#xff0c;其中每一位仍然是A到z的大寫字母。 Alice希望知道&#xff0c;有多少對結點<u&#xff0c;v>滿足…

[譯] 機器學習可以建模簡單的數學函數嗎?

原文地址&#xff1a;Can Machine Learning model simple Math functions?原文作者&#xff1a;Harsh Sahu譯文出自&#xff1a;掘金翻譯計劃本文永久鏈接&#xff1a;github.com/xitu/gold-m…譯者&#xff1a;Minghao23校對者&#xff1a;lsvih&#xff0c;zoomdong機器學習…

下載spotify音樂_如何在Spotify上播放更高質量的音樂

下載spotify音樂With Spotify Premium, you get access to higher quality music streaming. By default (and if you’re on the free plan), Spotify streams at 96kbps on mobile and 160kbps on your computer. At these sort of bitrates, you’ll hear a small but notic…

ubuntu scp命令或者用root連接ssh提示:Permission denied, please try again.錯誤

1、su -            #&#xff01;&#xff01;&#xff01; 2、vi /etc/ssh/sshd_config 3、PermitRootLogin yes    # 找到此字段&#xff0c;改為此行所示 4、/etc/init.d/ssh restart    # 重啟ssh服務 轉載于:https://www.cnblogs.com/weiyiming007/p…

Windows下壓縮包安裝Mysql

1. 下載mysql壓縮包 2. 解壓到指定目錄&#xff0c;例如D:\Program Files\mysql-5.7.25-winx64 3. 在目錄下創建配置文件my.ini [mysqld] port 3306 basedirD:/Program Files/mysql-5.7.25-winx64 datadirD:/Program Files/mysql-5.7.25-winx64/data max_connections200 char…

如何從終端打開Ubuntu Nautilus文件瀏覽器

Recently, we showed you how to open a directory in Terminal from within Nautilus. However, what if you’re working on the command line in Terminal and need to access the same directory in Nautilus? There’s an easy solution for that. 最近&#xff0c;我們向…

mysql 面試知識點筆記(七)RR如何避免幻讀及非阻塞讀、范式

2019獨角獸企業重金招聘Python工程師標準>>> 表象&#xff1a;快照讀&#xff08;非阻塞讀&#xff09;--偽MVCC &#xff08;Multi-Version Concurrent Controll多版本并發控制&#xff09; 內在&#xff1a;next-key鎖(record鎖gap鎖) rr serializabel 都支持gap鎖…

pdf 奇數頁插入頁碼_如何在Word 2013中的奇數頁碼上啟動新部分

pdf 奇數頁插入頁碼When working on a long document or a book in Word, it’s common to divide the document into sections or chapters. A common practice is to start each new section or chapter on an odd page. This is easily accomplished using sections in Word…