vue|vue2+ts项目/vue3+ts项目🧨🧨

ts+ vue2

一、环境搭建

  1. 创建项目 vue create xxx
  2. 默认选择安装了vue2.0
  3. 启动项目
  4. 在项目下安装 vue add @vue/script
  5. npm i vuex
  6. 搭建完成

二、创建子组件

xml 复制代码
<template>
    <div class="header-wrapper">
        <div class="header-item">
            <div class="img-item">
                <img src="../assets/img/kjj.png"/>
            </div>
            <span>Vue2.0 + TypeScript</span>
        </div>
        <div class="select-item">
            <el-dropdown trigger="click" @command="doNew">
                  <span class="el-dropdown-link">
                    新建<i class="el-icon-arrow-down el-icon--right"></i>
                  </span>
                <el-dropdown-menu slot="dropdown">
                    <el-dropdown-item icon="el-icon-plus">文本便签</el-dropdown-item>
                </el-dropdown-menu>
            </el-dropdown>
            <div class="space-item"></div>
            <div>
                <el-dropdown trigger="click" @command="doChange" >
                    <el-badge class="mark" :value="doFilter(-1)">
                      <span class="el-dropdown-link">
                        全部<i class="el-icon-caret-bottom el-icon--right"></i>
                      </span>
                    </el-badge>
                    <el-dropdown-menu slot="dropdown">
                        <el-dropdown-item class="clearfix" command=-1>
                            全部
                            <el-badge class="mark" :value="doFilter(-1)"/>
                        </el-dropdown-item>
                        <el-dropdown-item class="clearfix" command=0 divided>
                            工作
                            <el-badge class="mark" :value="doFilter(0)"/>
                        </el-dropdown-item>
                        <el-dropdown-item class="clearfix" command=1>
                            生活
                            <el-badge class="mark" :value="doFilter(1)"/>
                        </el-dropdown-item>
                        <el-dropdown-item class="clearfix" command=2>
                            学习
                            <el-badge class="mark" :value="doFilter(2)"/>
                        </el-dropdown-item>
                    </el-dropdown-menu>
                </el-dropdown>
            </div>

        </div>
    </div>

</template>

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

    @Component
    export default class MenuBar extends Vue {
        value: string = ''

        //点击新建,出现编辑框
        doNew() {
            // 点击新增初始化tranMemo,不然transMemo的初值是null
            this.$store.state.transMemo = new ItemData(-1, 0);
            this.$store.state.isshow = true
        }

        doFilter(cid: number): number {
            if (cid === -1) {
                return this.$store.state.actionHelper.memoList.length
            } else {
                return this.$store.state.actionHelper.memoList.filter((ele) => {
                    return ele.categoryId == cid;
                }).length
            }

        }
        doChange(val){
            this.$store.state.fliterCateId = val;
        }
    }
</script>

<style scoped lang="scss">
    .header-wrapper {
        width: 100%;
        display: flex;
        justify-content: space-between;
        align-items: center;

        .space-item {
            height: 60px;
            width: 40px;
            background-color: #409EFF;
        }

        .header-item {
            display: flex;
            align-items: center;
            height: 60px;

            .img-item {
                height: 40px;
                width: 40px;

                img {
                    height: 100%;
                    width: 100%;
                    border-radius: 50%;
                    border: 1px solid red;
                }
            }

            span {
                display: inline-block;
                font-size: 20px;
                font-weight: bold;
                color: #fff;
                margin-left: 10px;
            }

        }

        .select-item {
            display: flex;
            flex-direction: row;
            align-items: center;
        }
    }
</style>

2. 标签组件 MemoItem

xml 复制代码
<template>
  <div class="memo-container">
    <div class="memo">
      <div class="mark"></div>
      <div class="memo-heading">
        <h5 class="title">{{ memo.title }}</h5>
        <ul class="tools">
          <li class="edit" @click="showEdit"></li>
          <li class="delete" @click="doDel"></li>
        </ul>
      </div>
      <h6 class="memo-info">
        <span class="timeStamp">{{ memo.createTime }}</span>
        <span class="category"
          >分类:{{
            $store.state.aHelper.getCategoryName(memo.categoryId)
          }}</span
        >
      </h6>
      <div class="content">
        <div class="text">{{ memo.content }}</div>
      </div>
    </div>
  </div>
</template>
<script lang="ts">
import ItemData from "@/model/ItemData";
import { Vue, Component, Prop } from "vue-property-decorator";
@Component
export default class MemoItem extends Vue {
  @Prop() memo!: ItemData;
  doDel(): void {
    if (!window.confirm(`确认删除【${this.memo.title}】的笔记吗?`)) return;
    //   确认后,就删除
    this.$store.state.aHelper.remove(this.memo.id);
  }
  showEdit(): void {
    // 1.创建副本
    let newMemo = JSON.parse(JSON.stringify(this.memo));
    // 2.传递给transmemo
    this.$store.commit('showEditMemo', newMemo);
  }
}
</script>

3. 编辑组件 MemoEditor

xml 复制代码
<template>
    <el-dialog
            :visible.sync="$store.state.isshow"
            width="30%"
            append-to-body
            :show-close="false">
        <el-card class="box-card">
            <template #header>
                <div class="card-header">
                    <el-input type="text" placeholder="标题" v-model="memo.title"></el-input>
                    <el-dropdown @command="handleCommand" class="el-dropdown-item">
                          <span class="el-dropdown-link">{{memo.categoryId  == 0 ? '工作': memo.categoryId == 1? '生活':'学习' }}
                            <i class="el-icon-arrow-down el-icon--right"></i>
                          </span>
                        <el-dropdown-menu slot="dropdown">
                            <el-dropdown-item command=0>工作</el-dropdown-item>
                            <el-dropdown-item command=1>生活</el-dropdown-item>
                            <el-dropdown-item command=2>学习</el-dropdown-item>
                        </el-dropdown-menu>
                    </el-dropdown>
                    <div class="el-button-item">
                        <el-button class="button" type="text" @click="doSave" icon="el-icon-message"></el-button>
                        <el-button class="button" type="text" @click="doCancel" icon="el-icon-circle-close"></el-button>
                    </div>
                </div>
            </template>
            <div>
                <el-input
                        type="textarea"
                        :rows="2"
                        placeholder="请输入内容"
                        v-model="memo.content">
                </el-input>
            </div>
        </el-card>
    </el-dialog>
</template>

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

    @Component
    export default class MemoEditor extends Vue {
        memo: ItemData = new ItemData(-1, 0);

        created(): void {
            this.memo = this.$store.state.transMemo
        }

        handleCommand(val) {
            this.memo.categoryId = val;
        }

        doCancel() {
            this.$store.state.isshow = false
        }

        doSave() {
            if (this.memo && this.memo.categoryId > -1 && this.memo.title.trim().length > 0 && this.memo.content.trim().length > 0) {
                if (this.memo.id <= -1) {
                    this.$store.state.actionHelper.addData(this.memo)
                } else {
                    this.$store.state.actionHelper.editData(this.memo)
                }
                this.$store.state.isshow = false
            } else {
                window.alert('数据输入不完整!')
            }
        }
    }
</script>

<style scoped lang="scss">
    .item {
        margin-bottom: 18px;
        font-size: 14px;
    }

    /deep/ .el-card__header {
        padding: 10px 0 10px 10px;
    }

    .card-header {
        display: flex;
        justify-content: space-between;
        align-items: center;
    }

    /deep/ .el-card__body {
        padding: 10px;
    }

    .second-item {
        font-size: 14px;
        display: flex;
        justify-content: space-between;
        padding: 5px 10px;
    }

    /deep/ .el-textarea__inner {
        height: 300px;
        resize: none;
    }

    .el-card {
        width: 100%;
    }

    .el-button-item {
        width: 80px;
    }

    .el-dropdown-item {
        width: 120px;
        margin-left: 15px;
    }
</style>
xml 复制代码
<template>
    <div class="list-item">
        <MemoItem v-for="item in filterMemo()" :key="item.id" :memo="item"/>
    </div>
</template>

<script lang="ts">
    import {Vue, Component} from 'vue-property-decorator'
    import MemoItem from "@/components/MemoItem.vue";
    import ItemData from "@/model/ItemData";

    @Component({
        components: {
            MemoItem
        }
    })
    export default class MemoList extends Vue {
        memoArr:Array<ItemData> = this.$store.state.actionHelper.memoList;
        filterMemo():Array<ItemData> {
            if(this.$store.state.fliterCateId == -1){
                return this.memoArr;
            }else{
               return  this.memoArr.filter((item)=>{
                  return  item.categoryId == this.$store.state.fliterCateId
               })
            }
        }

    }
</script>

<style scoped lang="scss">
    .list-item {
        display: flex;
        flex-wrap: wrap;
    }
</style>

三、vue2.0特点

1. 2.0的组件导入方式,采用注解

2. 现红色提示,可能是变量未赋值等,更改package.json

json 复制代码
   "rules": {
      "no-unused-vars": 0,
      "vue/no-unused-components": [
        "off",
        {
          "ignoreWhenBindingPresent": true
        }
      ],
      "prefer-const": "off"
    }

3. 在书写css样式时,采用了scss语法,安装相关组件,注意版本问题

kotlin 复制代码
"node-sass": "^4.14.1",
 "sass-loader": "^7.3.1",
 npm install node-sass@4.14.1 -D
 npm install sass-loader@7.3.1 -D

4.main.ts文件内容

javascript 复制代码
import Vue from 'vue'
import App from './App.vue'
import './assets/css/global.css'
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
import store from './store/index'

Vue.config.productionTip = false
Vue.use(ElementUI)

new Vue({
  store,
  render: h => h(App),
}).$mount('#app')

四、实现功能

1. 创建跨组件共享数据文件store

typescript 复制代码
import Vue from 'vue'
import Vuex from 'vuex'
import ActionHelper from "@/store/ActionHelper";

Vue.use(Vuex)
let store = new Vuex.Store({
    state: {
        isshow: false,
        actionHelper: new ActionHelper(),
        transMemo: null,// 传递数据的桥梁
        fliterCateId: -1
    },
    mutations: {
        showEditMemo(state: any, editMemo: any) {
            state.transMemo = editMemo;
            state.isshow = true;
        }
    }
})
export default store

2. 设计便签的数据模型:MemoItem类

typescript 复制代码
class ItemData {
    id: number
    categoryId: number
    title: string
    content: string
    createTime: string

    constructor(id: number = -1, categoryId: number = -1, title: string = '', content: string = '', createTime: string) {
        this.id = id;
        this.categoryId = categoryId;
        this.title = title;
        this.content = content;
        this.createTime =this.toselfDate(Date.now()) ;
    }

    toselfDate(dateSpan: number): string {
        let date = new Date(dateSpan);
        let str = date.getFullYear() + '-' + (date.getMonth() + 1) + '-' + date.getDate() + ' ' + date.getHours() + ':' + date.getMinutes();
        return str;

    }
}
export  default  ItemData

3. 设计枚举的数据模型

arduino 复制代码
enum CateEnum {
    Work,
    Life = 1,
    Study
}
export  default CateEnum

4. 创建操作localstorage的类DataHelper

typescript 复制代码
// DataHelper主要实现对localstorage的操作
// 0.构造类
class DataHelper {
    dataKey: string
    primaryKey: string

    constructor(dataKey: string, primaryKey: string) {
        this.dataKey = dataKey;
        this.primaryKey = primaryKey
    }

    // 1.读数据
    readData(): any {
        // 1.读取数据
        let strData: string | null = localStorage.getItem(this.dataKey);
        // 2.将json转成json对象
        let arrData: any = [];
        if (strData != null) {
            arrData = JSON.parse(strData);
        }
        return arrData;
    }

    // 2.存数据
    saveData(arrData: Array<Object>): void {
        // 1.将json对象装成字符串
        let strData: string = JSON.stringify(arrData);
        // 2.存储
        localStorage.setItem(this.dataKey, strData);

    }

    // 3.新增数据
    addData(newDataObj: any): number {
        //  1. 读取本地现有的数据
        let dataArray = this.readData();
        if (dataArray == null) {
            dataArray = [];
        }
        //  3.自动生成主键,id
        let newId = dataArray.length > 0 ? dataArray[dataArray.length - 1].id + 1 : 1;

        //  4.将id添加到对象中
        dataArray.id = newId;
        //  5.将数组保存到本地

        dataArray.push(newDataObj);
        this.saveData(dataArray);
        //  6.返回newId的值
        return newId;
    }

    // 4.删除数据
    removeData(id: string | number): boolean {
        // 1.获取本地数据
        let arrData: any = this.readData();
        // 2.查找下标 删除
        let index = arrData.findIndex((ele: any) => {
            return ele[this.primaryKey] == id;
        })
        // 3.重新保存删除后的数据
        if (index > -1) {
            arrData.splice(index, 1);
            this.saveData(arrData);
            return true;
        }
        return false;
    }
}
export  default  DataHelper;

5. 在main.ts测试DataHelper的方法

ini 复制代码
// 0.测试构造的itemdata类
// let itemData = new ItemData(1,1,'标题','内容');
// console.log(itemData)
// 1.测试构造的枚举类型
// let itemData = new ItemData(1,CateEnum.Work,'标题','内容');
// console.log(itemData)
// ****************DataHelper***********
// 2.测试新增数据(新增的数据id都是-1)
// let itemData = new ItemData();
// let dh:DataHelper = new DataHelper('keyData', 'id');
// console.log(dh.addData(itemData))
// 3.删除数据
// let dh:DataHelper = new DataHelper('keyData','id');
// dh.removeData('-1');
// 4.测试读数据
// let dh:DataHelper = new DataHelper('keyData','id');
// console.log(dh.readData());

6. 创建操作类ActionHelper

ini 复制代码
import DataHelper from "@/store/DataHelper";
import ItemData from "@/model/ItemData";

class ActionHelper {
    // 1.在Datahelper的基础上再次封装
    dh: DataHelper = new DataHelper('keyData', 'id');
    // 2.定义一个便签数组
    memoList: Array<ItemData>;

    constructor() {
        // 便签数组的初始化数据,就是从本身读取数据,相当于vue的create方法,读取数据
        this.memoList = this.dh.readData();
    }

    // 读取数据
    readData(): Array<ItemData> {
        let arrData = this.dh.readData();
        // 将获取的数据,装成itemdata类型
        let arrItem = arrData.map((ele) => {
            // @ts-ignore
            let item: ItemData = new ItemData(); // item是itemData类型的空对象
            // 0.第一种方式 // 给空对象赋值
            // item = ele;
            // 1.第二种方式 // 给空对象赋值
            item.id = ele.id;
            item.categoryId = ele.categoryId;
            item.title = ele.title;
            item.content = ele.content;
            item.createTime = ele.createTime;
            return item;
        })
        return arrItem;
    }

    // 新增
    addData(item: ItemData): number {
        // 0.新增笔记到本地
        item.id = this.dh.addData(item);
        //  1.将笔记添加到memoList
        this.memoList.push(item);
        //  2.将笔记数组从新保存本地
        this.dh.saveData(this.memoList);
        return item.id;
    }

    // 修改
    editData(item: ItemData): void {
        // 0.先找到下标
        let editItem = this.memoList.find((ele) => {
            return ele.id == item.id;
        })
        //    1.修改对象
        if (editItem) {
            editItem.categoryId = item.categoryId;
            editItem.title = item.title;
            editItem.content = item.content;
        }
        //    2.保存对象
        this.dh.saveData(this.memoList);
    }

    // 删除
    delData(id: number): void {
        // 0.找下标
        let index = this.memoList.findIndex((ele) => {
            return ele.id == id;
        })
        if (index > -1) {
            this.memoList.splice(index, 1);
        }
        this.dh.saveData(this.memoList);
    }
}

export default ActionHelper;

7. 在main.ts中测试

ini 复制代码
//**************ActionHelper*************
// 0.测试新增(数据的id正常递增)
// let ah:ActionHelper = new ActionHelper();
// let item:ItemData = new ItemData();
// ah.addData(item);
// 1.测试修改(修改不存在的对象,会覆盖)
// let ah:ActionHelper = new ActionHelper();
// let item:ItemData = new ItemData(1,1,'我爱你11','我爱学习');
// ah.editData(item);
// 2.测试删除
// let ah:ActionHelper = new ActionHelper();
// ah.delData(1);

8. 实现新增功能

arduino 复制代码
-   点击新增,实现弹框 点击新增的时候,设置全局的isshow值是true
javascript 复制代码
//点击新建,出现编辑框
doNew() {
    // 点击新增初始化tranMemo,不然transMemo的初值是null
    this.$store.state.transMemo = new ItemData(-1, 0);
    this.$store.state.isshow = true
}

9. 实现保存功能

diff 复制代码
-   保存第一步对数据进行校验
-   分为新增保存
-   分为修改保存
kotlin 复制代码
doSave() {
    if (this.memo && this.memo.categoryId > -1 && this.memo.title.trim().length > 0 && this.memo.content.trim().length > 0) {
        if (this.memo.id <= -1) {
            this.$store.state.actionHelper.addData(this.memo)
        } else {
            this.$store.state.actionHelper.editData(this.memo)
        }
        this.$store.state.isshow = false
    } else {
        window.alert('数据输入不完整!')
    }
}

10. 实现修改功能

diff 复制代码
-   点击修改的时候,出现弹框
-   修改时,弹框内出现数据 在点击修改的时候,创建当前标签数据的副本,并且把数据传到共享数据文件中
javascript 复制代码
doEdit():void{
    // 创建副本
    let newMemo = JSON.parse(JSON.stringify(this.memo));
    // 提交数据到桥梁
    this.$store.commit('showEditMemo',newMemo);
}
diff 复制代码
- 展示组件MemoEditor的时候,在created方法中获取标签副本的值
kotlin 复制代码
created(): void {
    this.memo = this.$store.state.transMemo
}

11. 实现删除功能

javascript 复制代码
doDel() {
    if (!window.confirm(`确认删除【${this.memo.title}的标签吗?】`)) return
    this.$store.state.actionHelper.delData(this.memo.id);
}

12. 统计类别的个数

kotlin 复制代码
doFilter(cid: number): number {
    if (cid === -1) {
        return this.$store.state.actionHelper.memoList.length
    } else {
        return this.$store.state.actionHelper.memoList.filter((ele) => {
            return ele.categoryId == cid;
        }).length
    }

}

13. 点击不同的类别,展示不同的便签内容

diff 复制代码
-   把分类的值,传给全局的变量,fliterCateId
kotlin 复制代码
doChange(val){
    this.$store.state.fliterCateId = val;
}
diff 复制代码
- 在memoList展示便签的时候,做过滤处理
kotlin 复制代码
filterMemo():Array<ItemData> {
if(this.$store.state.fliterCateId == -1){
    return this.memoArr;
}else{
   return  this.memoArr.filter((item)=>{
      return  item.categoryId == this.$store.state.fliterCateId
   })
}
}

五、gitee共享

gitee.com/porous-crys...

六、展示

ts+vue3

一、环境搭建

  1. 创建项目 vue create xxx
  2. 选择安装了vue3.0
  3. 启动项目
  4. 在项目下安装 vue add @vue/script // 安装ts
  5. npm i vuex
  6. 搭建完成

二、创建子组件

  1. 头部组件 MenuBar

  2. 标签组件 MemoItem

  3. 编辑组件 MemoEditor

三、vue3.0特点

  1. vue3.0的组件导入方式

  2. 编辑文件是会出现红色提示,可能是变量未赋值等,更改package.json

json 复制代码
   "rules": {
      "no-unused-vars": 0,
      "vue/no-unused-components": [
        "off",
        {
          "ignoreWhenBindingPresent": true
        }
      ],
      "prefer-const": "off"
    }
  1. 在书写css样式时,采用了scss语法,安装相关组件,注意版本问题
kotlin 复制代码
"node-sass": "^4.14.1",
 "sass-loader": "^7.3.1",
 npm install node-sass@4.14.1 -D
 npm install sass-loader@7.3.1 -D
  1. main.ts文件内容
javascript 复制代码
import {createApp} from 'vue'
import {Elementplus} from './element-ui'
import App from './App.vue';
import './assets/css/global.css'

const app = createApp(App);
// 调用
Elementplus(app);
// 使用
createApp(App).use(Elementplus).mount('#app')
  1. vue3.0采用按需引入element-plus的方式,安装插件
arduino 复制代码
"babel-plugin-import": "^1.13.3",
npm install babel-plugin-import -D
相关推荐
钢铁小狗侠5 分钟前
前端(3)——快速入门JaveScript
前端
咔咔库奇8 分钟前
CSS基础知识04
前端·css
Black蜡笔小新23 分钟前
无插件H5播放器EasyPlayer.js网页web无插件播放器选择全屏时,视频区域并没有全屏问题的解决方案
前端·javascript·音视频
Augenstern、38 分钟前
vue3 element el-table实现表格动态增加/删除/编辑表格行,带有校验规则
前端·javascript·vue.js
A黄俊辉A1 小时前
electron安装遇到的问题
前端·javascript·electron
lvbb661 小时前
ES6更新的内容中什么是proxy
前端·ecmascript·es6
痕忆丶1 小时前
鸿蒙北向开发 : hdmfs-分布式文件系统
前端
赵锦川1 小时前
微信小程序设置屏幕安全距离
前端·javascript·vue.js
花花花12 小时前
RadSystems 自定义页面全攻略:个性化任务管理系统的实战设计
mysql·低代码·typescript·vue·开发工具·radsystems
GISer_Jing2 小时前
Javascript——设计模式(一)
前端·javascript·设计模式