<span id="mktg5"></span>

<i id="mktg5"><meter id="mktg5"></meter></i>

        <label id="mktg5"><meter id="mktg5"></meter></label>
        最新文章專題視頻專題問(wèn)答1問(wèn)答10問(wèn)答100問(wèn)答1000問(wèn)答2000關(guān)鍵字專題1關(guān)鍵字專題50關(guān)鍵字專題500關(guān)鍵字專題1500TAG最新視頻文章推薦1 推薦3 推薦5 推薦7 推薦9 推薦11 推薦13 推薦15 推薦17 推薦19 推薦21 推薦23 推薦25 推薦27 推薦29 推薦31 推薦33 推薦35 推薦37視頻文章20視頻文章30視頻文章40視頻文章50視頻文章60 視頻文章70視頻文章80視頻文章90視頻文章100視頻文章120視頻文章140 視頻2關(guān)鍵字專題關(guān)鍵字專題tag2tag3文章專題文章專題2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章專題3
        問(wèn)答文章1 問(wèn)答文章501 問(wèn)答文章1001 問(wèn)答文章1501 問(wèn)答文章2001 問(wèn)答文章2501 問(wèn)答文章3001 問(wèn)答文章3501 問(wèn)答文章4001 問(wèn)答文章4501 問(wèn)答文章5001 問(wèn)答文章5501 問(wèn)答文章6001 問(wèn)答文章6501 問(wèn)答文章7001 問(wèn)答文章7501 問(wèn)答文章8001 問(wèn)答文章8501 問(wèn)答文章9001 問(wèn)答文章9501
        當(dāng)前位置: 首頁(yè) - 科技 - 知識(shí)百科 - 正文

        使用VueCli3+TypeScript+Vuex一步步構(gòu)建todoList的方法

        來(lái)源:懂視網(wǎng) 責(zé)編:小采 時(shí)間:2020-11-27 21:53:24
        文檔

        使用VueCli3+TypeScript+Vuex一步步構(gòu)建todoList的方法

        使用VueCli3+TypeScript+Vuex一步步構(gòu)建todoList的方法:前言 Vue3.x 即將來(lái)襲,使用 TypeScirpt 重構(gòu),TypeScript 將成為 vue 社區(qū)的標(biāo)配,出于一名程序員的焦慮,決定現(xiàn)在 Vue2.6.x 踩一波坑。 vue 官方文檔已經(jīng)簡(jiǎn)略地對(duì) typescript 的支持進(jìn)行了介紹,我們使用 Vue Cli3 直接生成項(xiàng)目 創(chuàng)建項(xiàng)目
        推薦度:
        導(dǎo)讀使用VueCli3+TypeScript+Vuex一步步構(gòu)建todoList的方法:前言 Vue3.x 即將來(lái)襲,使用 TypeScirpt 重構(gòu),TypeScript 將成為 vue 社區(qū)的標(biāo)配,出于一名程序員的焦慮,決定現(xiàn)在 Vue2.6.x 踩一波坑。 vue 官方文檔已經(jīng)簡(jiǎn)略地對(duì) typescript 的支持進(jìn)行了介紹,我們使用 Vue Cli3 直接生成項(xiàng)目 創(chuàng)建項(xiàng)目

        前言

        Vue3.x 即將來(lái)襲,使用 TypeScirpt 重構(gòu),TypeScript 將成為 vue 社區(qū)的標(biāo)配,出于一名程序員的焦慮,決定現(xiàn)在 Vue2.6.x 踩一波坑。

        vue 官方文檔已經(jīng)簡(jiǎn)略地對(duì) typescript 的支持進(jìn)行了介紹,我們使用 Vue Cli3 直接生成項(xiàng)目

        創(chuàng)建項(xiàng)目

        ❓為什么使用 Vue Cli3 構(gòu)建項(xiàng)目

        官方維護(hù),后續(xù)升級(jí)減少兼容性問(wèn)題

        使用以下配置進(jìn)行項(xiàng)目的生成:

      1. Babel 對(duì) Ts 進(jìn)行轉(zhuǎn)譯
      2. TSLint 對(duì) TS 代碼進(jìn)行規(guī)范,后續(xù)會(huì)使用 prettier 對(duì)項(xiàng)目進(jìn)行編碼的統(tǒng)一
      3. 默認(rèn)安裝 Vuex 和 Router , Router 使用  history 模式
      4. 使用 Jest 進(jìn)行單元測(cè)試
      5. ╭─~/otherEWokspace
        ╰─➤ vue create ts-vuex-demo
        
        
        Vue CLI v3.6.3
        ┌───────────────────────────┐
        │ Update available: 3.9.3 │
        └───────────────────────────┘
        ? Please pick a preset: Manually select features
        
        ? Check the features needed for your project: Babel, TS, Router, Vuex, CSS P
        re-processors, Linter, Unit
        
        ? Use class-style component syntax? Yes
        
        ? Use Babel alongside TypeScript for auto-detected polyfills? Yes
        
        ? Use history mode for router? (Requires proper server setup for index fallb
        ack in production) Yes
        
        ? Pick a CSS pre-processor (PostCSS, Autoprefixer and CSS Modules are suppor
        ted by default): Sass/SCSS (with node-sass)
        
        ? Pick a linter / formatter config: TSLint
        
        ? Pick additional lint features: (Press <space> to select, <a> to toggle all
        , <i> to invert selection)Lint on save
        
        ? Pick a unit testing solution: Jest
        
        ? Where do you prefer placing config for Babel, PostCSS, ESLint, etc.? In de
        dicated config files
        
        ? Save this as a preset for future projects? Yes
        
        ? Save preset as: ts-vue-demo
        
        

        看一下新項(xiàng)目的層級(jí)目錄

        ╭─~/otherEWokspace/ts-vuex-demo ‹master›
        ╰─➤ tree -L 2 -I node_modules
        .
        ├── README.md
        ├── babel.config.js
        ├── jest.config.js
        ├── package-lock.json
        ├── package.json
        ├── postcss.config.js
        ├── public
        │ ├── favicon.ico
        │ └── index.html
        ├── src
        │ ├── App.vue
        │ ├── assets
        │ ├── components
        │ ├── main.ts
        │ ├── router.ts
        │ ├── shims-tsx.d.ts
        │ ├── shims-vue.d.ts
        │ ├── store.ts
        │ └── views
        ├── tests
        │ └── unit
        ├── tsconfig.json
        └── tslint.json
        

        tsconfig.json

        對(duì) lib 、 target 、 module 進(jìn)行解釋

        {
         "compilerOptions": {
         "target": "esnext",
         "module": "esnext",
         "strict": true,
         "jsx": "preserve", // 開(kāi)啟對(duì) jsx 的支持
         "importHelpers": true,
         "moduleResolution": "node",
         "experimentalDecorators": true,
         "esModuleInterop": true,
         "allowSyntheticDefaultImports": true,
         "sourceMap": true,
         "baseUrl": ".",
         "types": [
         "webpack-env",
         "jest"
         ],
         "paths": {
         "@/*": [
         "src/*"
         ]
         },
         "lib": [
         "esnext",
         "dom",
         "dom.iterable",
         "scripthost"
         ]
         },
         "include": [
         "src/**/*.ts",
         "src/**/*.tsx",
         "src/**/*.vue",
         "tests/**/*.ts",
         "tests/**/*.tsx"
         ],
         "exclude": [
         "node_modules"
         ]
        }
        
      6. target --- 被 tsc 編譯后生成 js 文件代碼風(fēng)格
      7. module --- 被 tsc 編譯后生成 js 文件的模塊風(fēng)格
      8. lib --- 原 ts 文件支持的代碼庫(kù)
      9. 我們來(lái)看一下示例:

        // index.ts
        export const Greeter = (name: string) => `Hello ${name}`;
        

        "module": "commonjs", "target": "es5"

        // index.js
        "use strict";
        
        Object.defineProperty(exports, "__esModule", { value: true });
        
        exports.Greeter = function (name) { return "Hello " + name; };
        
        

        "module": "es2015", "target": "es5"

        // index.js
        export var Greeter = function (name) { return "Hello " + name; };
        

        "module": "es2015", "target": "es6"

        // index.js
        export const Greeter = (name) => `Hello ${name}`;
        

        "module": "commonjs", "target": "es6"

        // index.js
        "use strict";
        Object.defineProperty(exports, "__esModule", { value: true });
        exports.Greeter = (name) => `Hello ${name}`;
        

        如果lib沒(méi)有指定默認(rèn)注入的庫(kù)的列表。默認(rèn)注入的庫(kù)為:

      10. 針對(duì)于 target:ES5:DOM,ES5,ScriptHost
      11. 針對(duì)于 target:ES6:DOM,ES6,DOM.Iterable,ScriptHost
      12. tslint

        類似于 eslint ,對(duì) ts 代碼進(jìn)行檢測(cè)。

        vscode 需要安裝tslint 插件 ,并在 vscode 的用戶配置中加入以下配置,用來(lái)在保存時(shí)自動(dòng)解決 ts 的錯(cuò)誤。

        // settings.json
         "editor.codeActionsOnSave": {
         "source.fixAll.tsLint": true
         }
        

        ❗️ vue cli3 已經(jīng)安裝了tslint依賴

        使用prettier 插件,對(duì)項(xiàng)目進(jìn)行代碼風(fēng)格的統(tǒng)一和規(guī)范

        npm i tslint-config-prettier -D

        添加 tslint.json  extends 字段如下:

        "extends": ["tslint:recommended", "tslint-config-prettier"]

        設(shè)置 vscode

      13. 勾選 tslintIntegration ,使 prittier 支持格式化 ts 文件
      14. "editor.formatOnSave": true 保存時(shí)自動(dòng)格式化
      15. 也可以使用 shift + option + f 進(jìn)行格式化

        在根目錄下添加 .prttierrc 文件 (應(yīng)對(duì) prittier 格式化 vue 文件中的 ts 文件時(shí),沒(méi)辦法使用 tslint 規(guī)則進(jìn)行格式化,需要對(duì)它單獨(dú)處理,以免 tslint 報(bào)錯(cuò))

        { "singleQuote": true }

        shims-vue.d.ts

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

        聲明所有以 .vue 結(jié)尾的文件,默認(rèn)導(dǎo)入 vue ,默認(rèn)導(dǎo)出 Vue,用以在項(xiàng)目中ts文件識(shí)別 .vue 結(jié)尾文件。

        在 main.ts 中,引入一個(gè) vue 組件必須以 .vue 結(jié)尾。

        import Vue from 'vue';
        import App from './App.vue';
        import router from './router';
        import store from './store';
        
        Vue.config.productionTip = false;
        
        new Vue({
         router,
         store,
         render: (h) => h(App),
        }).$mount('#app');
        
        

        Vue class

        vue-property-decorator

        寫一個(gè) todolist 組件順便來(lái)介紹 vue-property-decorator,為了方便頁(yè)面構(gòu)建,使用 element-ui

        element-ui 使用 ts 開(kāi)發(fā),默認(rèn)有 .d.ts 的聲明文件

        npm i element-ui
        // main.ts
        
        import ElementUI from 'element-ui';
        import 'element-ui/lib/theme-chalk/index.css';
        
        Vue.use(ElementUI);
        
        

        在 /src/compenents/ 新建 todoList.vue , 代碼如下:

        <template>
         <div class="todo_list">
         <el-card class="box-card">
         <div slot="header">
         <el-row :gutter="18">
         <el-col :span="18">
         <el-input
         v-model="todo"
         placeholder="請(qǐng)輸入內(nèi)容"
         ></el-input>
         </el-col>
         <el-col :span="2">
         <el-button
         type="primary"
         icon="el-icon-circle-plus-outline"
         @click="addItem"
         >add</el-button>
         </el-col>
        
         </el-row>
        
         </div>
         <div
         v-for="(item,index) in todoList"
         :key="item"
         class="text item"
         @click="removeItem(index)"
         >{{ item }}</div>
         </el-card>
         <label
         class="text"
         style="margin-top:20px"
         >{{todoLength}} records</label>
         </div>
        </template>
        
        
        <script lang="ts">
        import { Component, Prop, Vue, Emit } from 'vue-property-decorator';
        
        @Component
        export default class HelloWorld extends Vue {
         public todo: string = '';
        
         @Prop({ default: [] }) private readonly todoList!: string[];
        
         get todoLength(): number {
         return this.todoList.length;
         }
        
         @Emit()
         private addItem(): string | undefined {
         if (this.todo) {
         return this.todo;
         }
         }
        
         @Emit('removeItem')
         private removeItem(index: number): number {
         return index;
         }
        }
        </script>
        
        <!-- Add "scoped" attribute to limit CSS to this component only -->
        <style scoped lang="scss">
        .todo_list {
         display: flex;
         justify-content: center;
         flex-direction: column;
         align-items: center;
         .box-card {
         width: 480px;
         }
        
         .text {
         font-size: 14px;
         text-align: left;
         }
        
         .item {
         margin-bottom: 18px;
         }
        }
        </style>
        

        對(duì) ts 代碼的用法指出以下幾點(diǎn):

        1. prop 建議寫成 xxx!: type 的形式,不然要寫成 xxx : type | undefined
        2. @Emit 可以不傳參數(shù),emit 出去的事件名默認(rèn)是修飾的函數(shù)名,但是當(dāng)函數(shù)的命名規(guī)則為 camelCase 時(shí)需要注冊(cè)的函數(shù)名必須是 kebab-case
        3. @Emit 傳參是由修飾的函數(shù) return value

        改造 Home.vue 如下:

        <template>
         <div class="home">
         <todoList
         :todoList="[]"
         @add-item="addTodoList"
         @removeItem="addTodoLisItem"
         />
         </div>
        </template>
        
        <script lang="ts">
        import { Component, Vue } from 'vue-property-decorator';
        import todoList from '@/components/todoList.vue'; // @ is an alias to /src
        import { State, Getter, Action } from 'vuex-class';
        
        @Component({
         components: {
         todoList
         }
        })
        export default class Home extends Vue {
         
         public addTodoList(val: string) {
         console.log(val);
         
         }
        
         private created() {
         console.log('i add life cycle funciton -- created');
         }
        
         private addTodoLisItem(index: number) {
         console.log(index);
         }
        }
        </script>
        
        

        Vuex

        有關(guān) ts 中的 vuex 的寫法要從vuex-class 說(shuō)起,在 官方的 vue-property-decorator 中也推薦使用該庫(kù)。

        npm i vuex-class
        

        在 src 文件夾中新建 store 文件夾, 在 store 新建 index.ts,todoList.ts

        // index.ts
        
        import Vue from 'vue';
        import Vuex from 'vuex';
        
        import todolist from './todoList';
        
        Vue.use(Vuex);
        
        export default new Vuex.Store({
         modules: { todolist }
        });
        
        
        // todoList.ts
        
        import { Commit, Dispatch, GetterTree, ActionTree, MutationTree } from 'vuex';
        
        const ADD_TODOLIST = 'ADD_TODOLIST';
        const REMOVE_ITEM = 'REMOVE_ITEM';
        
        export interface RootState {
         version: string;
        }
        
        interface Payload {
         [propName: string]: any;
        }
        
        interface TodoListType {
         todoList: string[];
        }
        
        interface Context {
         commit: Commit;
         dispatch: Dispatch;
        }
        
        const dataSource: TodoListType = {
         todoList: []
        };
        
        const getters: GetterTree<TodoListType, RootState> = {
         getTodoList(state: TodoListType): string[] {
         return state.todoList;
         }
        };
        
        const mutations: MutationTree<TodoListType> = {
         ADD_TODOLIST: (state: TodoListType, item: string) => {
         console.log(item);
         state.todoList.push(item);
         },
         REMOVE_ITEM: (state: TodoListType, removeIndex: number) => {
         state.todoList = state.todoList.filter((item: string, index: number) => {
         return removeIndex !== index;
         });
         }
        };
        
        const actions: ActionTree<TodoListType, RootState> = {
         addList: async ({ commit }: Context, item: string) => {
         await Promise.resolve(
         setTimeout(() => {
         commit(ADD_TODOLIST, item);
         }, 100)
         );
         },
         removeItem: async ({ commit }: Context, { index }: Payload) => {
         await Promise.resolve(
         setTimeout(() => {
         commit(REMOVE_ITEM, index);
         }, 100)
         );
         }
        };
        
        export default {
         namespaced: true,
         state: dataSource,
         getters,
         mutations,
         actions
        };

        刪除原來(lái)與 main.ts 同級(jí)的 store.ts

        對(duì) todoList.ts 需要注意以下幾點(diǎn):

      16. 對(duì)于 getters 、mutations 、actions 響應(yīng)的 type 可以使用 command + 左鍵點(diǎn)擊 進(jìn)入聲明文件查看,也可以不指定 type ,但是建議寫上
      17. 對(duì)于 Payload 解構(gòu)  tslint 報(bào)錯(cuò)的,可以為 Payload 添加類型聲明
      18. interface Payload {
         [propName: string]: any;
        }
        
        

        代碼中的 dataSource 本意為 state ,但是不能用 state 命名,tslint 會(huì)和形參 state 沖突

        改造 /views/Home.vue 如下:

        <template>
         <div class="home">
         <todoList
         :todoList="todoList"
         @add-item="addTodoList"
         @removeItem="addTodoLisItem"
         />
         </div>
        </template>
        
        <script lang="ts">
        import { Component, Vue } from 'vue-property-decorator';
        import todoList from '@/components/todoList.vue'; // @ is an alias to /src
        import { State, Getter, Action } from 'vuex-class';
        
        @Component({
         components: {
         todoList
         }
        })
        export default class Home extends Vue {
         @State(state => state.todolist.todoList) private todoList!: string[];
        
         @Action('todolist/addList') private addList!: (val: string) => void;
         @Action('todolist/removeItem') private removeItem!: (index: number) => void;
        
         public addTodoList(val: string) {
         console.log(val);
         this.addList(val);
         }
        
         private created() {
         console.log('i add life cycle funciton -- created');
         }
        
         private addTodoLisItem(index: number) {
         this.removeItem(index);
         }
        }
        </script>
        
        

        有關(guān) vuex-class 的調(diào)用有以下幾點(diǎn)注意

      19. @State 如果有分模塊,必須使用 state => state.xxx.xxx 的形式獲取state
      20. @Action 中函數(shù)的聲明,形參必須和方法保持一致
      21. 所有的代碼到此為止,使用 npm run serve 即可查看應(yīng)用,保留原有 routes 文件,保持應(yīng)用的健壯性。

        寫在最后

        1. 本文只是介紹了一個(gè)簡(jiǎn)單構(gòu)建 ts-vue 應(yīng)用的例子,對(duì)于框架的健壯和可擴(kuò)展性有需要慢慢考慮,比如 webpack 的配置,適應(yīng)測(cè)試,生產(chǎn)等各種環(huán)境的區(qū)分,axois 的封裝,等等。
        2. 對(duì)于vue + ts 的配方,文章還有很多 vue 的特性沒(méi)有去兼容,比如 this.refs 的使用,比如 vue-property-decorator 其他特性的使用。
        3. 由于官方文檔對(duì) ts 的介紹有限,所以以上代碼肯定有不足的地方,希望大家指正。

        聲明:本網(wǎng)頁(yè)內(nèi)容旨在傳播知識(shí),若有侵權(quán)等問(wèn)題請(qǐng)及時(shí)與本網(wǎng)聯(lián)系,我們將在第一時(shí)間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com

        文檔

        使用VueCli3+TypeScript+Vuex一步步構(gòu)建todoList的方法

        使用VueCli3+TypeScript+Vuex一步步構(gòu)建todoList的方法:前言 Vue3.x 即將來(lái)襲,使用 TypeScirpt 重構(gòu),TypeScript 將成為 vue 社區(qū)的標(biāo)配,出于一名程序員的焦慮,決定現(xiàn)在 Vue2.6.x 踩一波坑。 vue 官方文檔已經(jīng)簡(jiǎn)略地對(duì) typescript 的支持進(jìn)行了介紹,我們使用 Vue Cli3 直接生成項(xiàng)目 創(chuàng)建項(xiàng)目
        推薦度:
        標(biāo)簽: VUE todo list
        • 熱門焦點(diǎn)

        最新推薦

        猜你喜歡

        熱門推薦

        專題
        Top
        主站蜘蛛池模板: 免费观看的毛片手机视频| 国内精品免费久久影院| 免费大黄网站在线观看| 免费国产成人午夜私人影视| 亚洲乱码无限2021芒果| 亚洲无人区码一二三码区别图片| 最近2018中文字幕免费视频| 国产免费av片在线播放| 亚洲综合在线视频| 一级特黄aa毛片免费观看| 国产自产拍精品视频免费看| 亚洲国产精品福利片在线观看| 中文字幕亚洲综合小综合在线| 国产精品免费久久| 久久久久久久尹人综合网亚洲| 大地资源在线资源免费观看| 无码久久精品国产亚洲Av影片| 99热精品在线免费观看| 亚洲一区电影在线观看| 好男人视频社区精品免费| 精品国产日韩亚洲一区91| 亚洲国产激情一区二区三区| 亚洲视频在线观看2018| 日本特黄特色aa大片免费| 免费人成又黄又爽的视频在线电影| 69影院毛片免费观看视频在线| 亚洲va在线va天堂成人| 国产一级理论免费版| 九九热久久免费视频| 国产大片免费观看中文字幕| 有码人妻在线免费看片| 亚洲av片劲爆在线观看| 夜夜嘿视频免费看| 91精品成人免费国产| 亚洲国产成人九九综合| 免费观看亚洲人成网站| 免费国产在线视频| 亚洲国产精品一区二区成人片国内| 最近2019免费中文字幕视频三| 亚洲精华液一二三产区| 亚洲av之男人的天堂网站|