国产99久久精品_欧美日本韩国一区二区_激情小说综合网_欧美一级二级视频_午夜av电影_日本久久精品视频

最新文章專題視頻專題問答1問答10問答100問答1000問答2000關鍵字專題1關鍵字專題50關鍵字專題500關鍵字專題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關鍵字專題關鍵字專題tag2tag3文章專題文章專題2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章專題3
問答文章1 問答文章501 問答文章1001 問答文章1501 問答文章2001 問答文章2501 問答文章3001 問答文章3501 問答文章4001 問答文章4501 問答文章5001 問答文章5501 問答文章6001 問答文章6501 問答文章7001 問答文章7501 問答文章8001 問答文章8501 問答文章9001 問答文章9501
當前位置: 首頁 - 科技 - 知識百科 - 正文

使用VueCli3+TypeScript+Vuex一步步構建todoList的方法

來源:懂視網 責編:小采 時間:2020-11-27 21:53:24
文檔

使用VueCli3+TypeScript+Vuex一步步構建todoList的方法

使用VueCli3+TypeScript+Vuex一步步構建todoList的方法:前言 Vue3.x 即將來襲,使用 TypeScirpt 重構,TypeScript 將成為 vue 社區的標配,出于一名程序員的焦慮,決定現在 Vue2.6.x 踩一波坑。 vue 官方文檔已經簡略地對 typescript 的支持進行了介紹,我們使用 Vue Cli3 直接生成項目 創建項目
推薦度:
導讀使用VueCli3+TypeScript+Vuex一步步構建todoList的方法:前言 Vue3.x 即將來襲,使用 TypeScirpt 重構,TypeScript 將成為 vue 社區的標配,出于一名程序員的焦慮,決定現在 Vue2.6.x 踩一波坑。 vue 官方文檔已經簡略地對 typescript 的支持進行了介紹,我們使用 Vue Cli3 直接生成項目 創建項目

前言

Vue3.x 即將來襲,使用 TypeScirpt 重構,TypeScript 將成為 vue 社區的標配,出于一名程序員的焦慮,決定現在 Vue2.6.x 踩一波坑。

vue 官方文檔已經簡略地對 typescript 的支持進行了介紹,我們使用 Vue Cli3 直接生成項目

創建項目

❓為什么使用 Vue Cli3 構建項目

官方維護,后續升級減少兼容性問題

使用以下配置進行項目的生成:

  • Babel 對 Ts 進行轉譯
  • TSLint 對 TS 代碼進行規范,后續會使用 prettier 對項目進行編碼的統一
  • 默認安裝 Vuex 和 Router , Router 使用  history 模式
  • 使用 Jest 進行單元測試
  • ╭─~/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
    
    

    看一下新項目的層級目錄

    ╭─~/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

    對 lib 、 target 、 module 進行解釋

    {
     "compilerOptions": {
     "target": "esnext",
     "module": "esnext",
     "strict": true,
     "jsx": "preserve", // 開啟對 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"
     ]
    }
    
  • target --- 被 tsc 編譯后生成 js 文件代碼風格
  • module --- 被 tsc 編譯后生成 js 文件的模塊風格
  • lib --- 原 ts 文件支持的代碼庫
  • 我們來看一下示例:

    // 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沒有指定默認注入的庫的列表。默認注入的庫為:

  • 針對于 target:ES5:DOM,ES5,ScriptHost
  • 針對于 target:ES6:DOM,ES6,DOM.Iterable,ScriptHost
  • tslint

    類似于 eslint ,對 ts 代碼進行檢測。

    vscode 需要安裝tslint 插件 ,并在 vscode 的用戶配置中加入以下配置,用來在保存時自動解決 ts 的錯誤。

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

    ❗️ vue cli3 已經安裝了tslint依賴

    使用prettier 插件,對項目進行代碼風格的統一和規范

    npm i tslint-config-prettier -D

    添加 tslint.json  extends 字段如下:

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

    設置 vscode

  • 勾選 tslintIntegration ,使 prittier 支持格式化 ts 文件
  • "editor.formatOnSave": true 保存時自動格式化
  • 也可以使用 shift + option + f 進行格式化

    在根目錄下添加 .prttierrc 文件 (應對 prittier 格式化 vue 文件中的 ts 文件時,沒辦法使用 tslint 規則進行格式化,需要對它單獨處理,以免 tslint 報錯)

    { "singleQuote": true }

    shims-vue.d.ts

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

    聲明所有以 .vue 結尾的文件,默認導入 vue ,默認導出 Vue,用以在項目中ts文件識別 .vue 結尾文件。

    在 main.ts 中,引入一個 vue 組件必須以 .vue 結尾。

    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

    寫一個 todolist 組件順便來介紹 vue-property-decorator,為了方便頁面構建,使用 element-ui

    element-ui 使用 ts 開發,默認有 .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="請輸入內容"
     ></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>
    

    對 ts 代碼的用法指出以下幾點:

    1. prop 建議寫成 xxx!: type 的形式,不然要寫成 xxx : type | undefined
    2. @Emit 可以不傳參數,emit 出去的事件名默認是修飾的函數名,但是當函數的命名規則為 camelCase 時需要注冊的函數名必須是 kebab-case
    3. @Emit 傳參是由修飾的函數 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

    有關 ts 中的 vuex 的寫法要從vuex-class 說起,在 官方的 vue-property-decorator 中也推薦使用該庫。

    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
    };

    刪除原來與 main.ts 同級的 store.ts

    對 todoList.ts 需要注意以下幾點:

  • 對于 getters 、mutations 、actions 響應的 type 可以使用 command + 左鍵點擊 進入聲明文件查看,也可以不指定 type ,但是建議寫上
  • 對于 Payload 解構  tslint 報錯的,可以為 Payload 添加類型聲明
  • interface Payload {
     [propName: string]: any;
    }
    
    

    代碼中的 dataSource 本意為 state ,但是不能用 state 命名,tslint 會和形參 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>
    
    

    有關 vuex-class 的調用有以下幾點注意

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

    寫在最后

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

    聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com

    文檔

    使用VueCli3+TypeScript+Vuex一步步構建todoList的方法

    使用VueCli3+TypeScript+Vuex一步步構建todoList的方法:前言 Vue3.x 即將來襲,使用 TypeScirpt 重構,TypeScript 將成為 vue 社區的標配,出于一名程序員的焦慮,決定現在 Vue2.6.x 踩一波坑。 vue 官方文檔已經簡略地對 typescript 的支持進行了介紹,我們使用 Vue Cli3 直接生成項目 創建項目
    推薦度:
    標簽: VUE todo list
    • 熱門焦點

    最新推薦

    猜你喜歡

    熱門推薦

    專題
    Top
    主站蜘蛛池模板: 国产在线视频不卡 | 欧美特黄一区二区三区 | 亚洲永久精品一区二区三区 | 成人a毛片久久免费播放 | 久久一本日韩精品中文字幕屁孩 | 国产成人精品一区二区免费 | 亚洲视频大全 | 蜜臀一区 | 亚洲高清在线观看 | 最新国产网址 | 五月天婷婷基地 | 亚洲综合二区 | 国产正在播放 | 国内精品视频一区二区三区 | 色综合天天综合中文网 | 久久久国产精品视频 | 国产真实乱人视频在线看 | 日韩一区二区三区精品 | 永久免费观看的毛片的网站 | 日韩电影第一页 | 免费国产小视频在线观看 | 中文字幕日韩欧美 | 亚洲va欧美ⅴa国产va影院 | 国产欧美精品一区二区三区四区 | 国产一区二区三区在线看 | 国产精品自拍第一页 | 国内精品久久久久 | 精品一区二区三区免费视频 | 国产欧美日本亚洲精品五区 | 日韩精品一区二区三区国语自制 | 广东东莞一级毛片免费 | 欧美aa在线观看 | 2022国产91精品久久久久久 | 日韩免费一区二区三区在线 | 极品毛片| 亚洲图片欧美在线 | 欧美精品在线观看视频 | 黄色在线免费观看网址 | 亚洲精品毛片久久久久久久 | 欧美一区二区二区 | 亚洲国产成人精品久久 |