目录

基于vite创建vue3.2 + typescript项目

1.安装和导入pinia(用于todolist案例的数据共享)

2.安装elementPlus和sass,sass-loader(进行快速构建页面样式)

3.组件化开发todolist

4.创建types文件夹,并创建todo.ts的类型规范文件向外共享

5.在store的todo.ts数据共享模块进行初始化数据

6.创建utils模块封装本地存储todolist数据的模块localStorageUtils.ts

7.在item组件渲染假数据(利用pinia)

8.实现各项功能

8.1.header组件输入框回车后增加数据(这里用到store里面添加数据的方法)

8.2item组件实现删除数据的功能

8.3实现其他功能(数组方法和pinia等知识点的应用)

案例涉及的一些知识点:

1.在setup语法糖使用toRefs解构(vue3.0的...toRefs())

2.defineProps的写法

3.typescript接口在vue的使用  ,快速获取表单数据的v-model指令

4.数组方法(unshift,splice,forEach,filter)

4.1.unshift方法(数组头部加入新数据,push是后面追加)

4.2.splice方法:数组删除元素方法

4.3.forEach遍历数组(可以每次遍历都对数组数据进行操作)

4.4.filter过滤筛选数组得到新数组(数组声明里面的数据类型arr : Array)


基于vite创建vue3.2 + typescript项目

见官网:Vite中文网

npm init vite@latest

1.安装和导入pinia(用于todolist案例的数据共享)

‘’官网:Pinia

npm i pinia -S

在main.ts导入:

import { createPinia } from 'pinia'
const app = createApp(App)
app.use(createPinia())

创建store文件夹,并创建todo.ts作为需要数据共享的模块

import { defineStore } from "pinia";

export const todoStore = defineStore('todos', {
  state: () => {
    return {

    }
  },
  getters: {

    },
  },
  actions: {

  }
})

2.安装elementPlus和sass,sass-loader(进行快速构建页面样式)

安装sass-loader和sass

npm i sass sass-loader -S

安装elementPlus:

官网:一个 Vue 3 UI 框架 | Element Plus

npm install element-plus --save

需要安装unplugin-vue-components 和 unplugin-auto-import这两款插件

npm install -D unplugin-vue-components unplugin-auto-import

参照官网进行安装配置自动按需导入:基于vite的配置

最后在页面测试是否生效。

3.组件化开发todolist

将上面拆分为四个组件

  • Header:输入框
  • List:任务的容器
  • item:任务
  • footer:底部信息和按钮

利用elementPlus快速构建页面

4.创建types文件夹,并创建todo.ts的类型规范文件向外共享


/* 定义一个接口,约束state的数据类型 */

export interface Todo {
  id: number,
  title: string,
  isCompleted: boolean
}

5.在store的todo.ts数据共享模块进行初始化数据

具体定义store的方法可以参照pinia官网

import { defineStore } from "pinia";
/* 引入接口 */
import { Todo } from '../types/todo'

export const todoStore = defineStore('todos', {
  state: () => {
    return {
      /* 数据应该用数组来存储,
数组中的每一个数据都是一个对象,
对象中应该有三个属性(id,title,isCompleted) */
      todos: [
      {  id: 1,title: '迪丽热巴', isCompleted: false},
      {  id: 1,title: '迪丽热巴', isCompleted: false},
      {  id: 1,title: '迪丽热巴', isCompleted: false}
] as Todo[]
    }
  },
  getters: {
    },
  },
  actions: {

  },
})

6.创建utils模块封装本地存储todolist数据的模块localStorageUtils.ts

import { Todo } from "../types/todo";
/* 保存数据到浏览器的缓存中 */
export function saveTodos(todos: Todo[]) {
  localStorage.setItem('todos_key', JSON.stringify(todos))
}
/* 从浏览器的缓存中读取数据 */
export function readTodos(): Todo[] {
  return JSON.parse(localStorage.getItem('todos_key') || '[]')
}

7.在item组件渲染假数据(利用pinia)

v-for指令

<script setup lang='ts'>
import { todoStore } from "../store/todo";
const store = todoStore()

</script>

<template>
  <!-- 鼠标进入和鼠标离开事件 -->
  <div class="item" v-for="(todo, index) in store.todos" :key="todo.id">
    <el-checkbox :label="todo.title" size="large" v-model="todo.isCompleted" />
    <div class="btn">
      <el-button type="danger" round size="small">删除</el-button>
    </div>
  </div>
</template>

8.实现各项功能

8.1.header组件输入框回车后增加数据(这里用到store里面添加数据的方法)

先在store的todo.ts的action节点创建添加数据的方法:

  actions: {
    /* 添加数据的方法 */
    addTodo(todo: Todo) {
      this.todos.unshift(todo)
      /* 存储数据到本地 */
      saveTodos(this.todos)
    }
}

  store.addTodo(todo)

<script setup lang='ts'>
import { Todo } from '../types/todo'
import { onMounted, ref } from "vue";
import { todoStore } from "../store/todo";
import { readTodos } from "../utils/localStorageUtils";
const store = todoStore()

const title = ref('')
const id = ref(3)

onMounted(() => {
  store.todos = readTodos()
})

/* 回车的事件回调函数,用来添加数据 */
const add = () => {
  /* 获取到的表单数据 */
  const text = title.value
  if (!text.trim()) return
  /* 此时有数据,创建一个todo对象 */
  const todo = {
    id: ++id.value,
    title: text,
    isCompleted: false
  } as Todo
  /* 调用增加数组数据的方法 */
  store.addTodo(todo)
  /* 清空文本框 */
  title.value = ''
}

</script>

<template>
  <el-input placeholder="请输入你的任务,按回车确认" @keyup.enter="add" v-model="title" />
</template>

8.2item组件实现删除数据的功能

同理先在store的todo.ts的action节点创建删除数据的方法:

  actions: {
    /* 删除数据的方法 */
    delTodo(index: number) {
      if (window.confirm('确定要删除任务吗?')) {
        /* 数组删除元素方法,splice(index,len,[item])
        如果len为0则数组不变
        */
        this.todos.splice(index, 1)
      }
    }
}

在item组件:

<script setup lang='ts'>
import { todoStore } from "../store/todo";
const store = todoStore()

</script>

<template>
  <!-- 鼠标进入和鼠标离开事件 -->
  <div class="item" v-for="(todo, index) in store.todos" :key="todo.id">
    <el-checkbox :label="todo.title" size="large" v-model="todo.isCompleted" @change="store.isAllChecked" />
    <div class="btn">
      <el-button type="danger" round size="small" @click="store.delTodo(index)">删除</el-button>
    </div>
  </div>
</template>

<style lang='scss'>
.item {
  border-bottom: 1px solid #409eff;
  position: relative;

  .btn {
    position: absolute;
    right: 0;
    bottom: 0;
  }
}

.item:hover {
  background-color: #aad1f7;
}
</style>

8.3实现其他功能(数组方法和pinia等知识点的应用)

footer组件:

<script setup lang='ts'>
import { todoStore } from "../store/todo";

const store = todoStore()

</script>

<template>
  <el-checkbox size="large" v-model="store.status" @change="store.isChecked" /> 已完成 {{ store.isCompleteds }} / 全部 {{
      store.todos.length
  }}
  <el-button type="danger" style="margin-left:120px" @click="store.clearAllCompletedTodos">清除已完成的任务</el-button>
</template>

<style lang='scss' scoped>
</style>

store的todo.ts状态管理模块:

import { defineStore } from "pinia";
/* 引入接口 */
import { Todo } from '../types/todo'
import { saveTodos } from "../utils/localStorageUtils";

export const todoStore = defineStore('todos', {
  state: () => {
    return {
      /* 数据应该用数组来存储,数组中的每一个数据都是一个对象,对象中应该有三个属性(id,title,isCompleted) */
      /* 全选状态 */
      status: false,
      todos: [] as Todo[]
    }
  },
  getters: {
    /* 选中个数 */
    isCompleteds(state) {
      /* 用数组filter方法过滤选择的数据组成新数组 */
      const arr: Array<Todo> = state.todos.filter(item => item.isCompleted == true)
      /* 返回数组的长度就是数组的多少条数据 */
      return arr.length
    },
  },
  actions: {
    /* 添加数据的方法 */
    addTodo(todo: Todo) {
      this.todos.unshift(todo)
      /* 存储数据到本地 */
      saveTodos(this.todos)
    },
    /* 删除数据的方法 */
    delTodo(index: number) {
      if (window.confirm('确定要删除任务吗?')) {
        /* 数组删除元素方法,splice(index,len,[item])
        如果len为0则数组不变
        */
        this.todos.splice(index, 1)
      }
    },

    /* 全选按钮是否选中 */
    isChecked() {
      if (this.status) {
        /* 遍历数组逐个改变其选择状态 */
        this.todos.forEach(item => {
          item.isCompleted = true
        })
      } else if (!this.status) {
        this.todos.forEach(item => {
          item.isCompleted = false
        })
      }
    },
    /* 控制全选按钮选中 */
    isAllChecked() {
      if (this.isCompleteds == this.todos.length) {
        this.status = true
      } else {
        this.status = false
      }
    },

    /* 清除所有选中的数据 */
    clearAllCompletedTodos() {
      /* 筛选出未选中的数组数据组成新数组 */
      const arr: Array<Todo> = this.todos.filter(item => item.isCompleted == false)
      this.todos = arr
      /* 存储数据到本地 */
      saveTodos(this.todos)
    }
  },
})

效果图:

案例涉及的一些知识点:

1.在setup语法糖使用toRefs解构(vue3.0的...toRefs())

toRefs创建多个ref对象,即响应式供外界使用

在vue3.0中

  • return  ...toRefs(对象名)
  • 这样在模板中就可以直接title这样使用,不用再使用state.todos,直接todos就行

在vue3.2setup语法糖中没有return则需要改变写法,如下:

import { reactive, toRefs } from "vue"
const state = reactive<{ todos: Todo[] }>({
    todos:[
      {  id: 1,title: '迪丽热巴', isCompleted: false},
      {  id: 1,title: '迪丽热巴', isCompleted: false},
      {  id: 1,title: '迪丽热巴', isCompleted: false}
    ]
})


//vue3.0的写法:
  return{
  ...toRefs(state)
} 

//vue3.2setup语法糖写法,因为语法糖没有return

/* 第一种写法 */
let { todos } = toRefs(state)
/* 第二种写法 */
let todos = toRefs(state).todos

2.defineProps的写法

/* 第一种类型写法 */
defineProps<{ todos: Array<Todo> }>()
/* 第二种写法 */
defineProps({
  todos: Array<Todo>
}) 

3.typescript接口在vue的使用  ,快速获取表单数据的v-model指令

定义接口的ts文件:


/* 定义一个接口,约束state的数据类型 */

export interface Todo {
  id: number,
  title: string,
  isCompleted: boolean
}

在组件内使用:

<script setup lang='ts'>
import { Todo } from '../types/todo'
import {  ref } from "vue";

const title = ref('')
const id = ref(3)


/* 回车的事件回调函数,用来添加数据 */
const add = () => {
  /* 获取到的表单数据 */
  const text = title.value
  if (!text.trim()) return
  /* 此时有数据,创建一个todo对象 */
  const todo = {
    id: ++id.value,
    title: text,
    isCompleted: false
  } as Todo
  /* 清空文本框 */
  title.value = ''
}

</script>

<template>
  <el-input placeholder="请输入你的任务,按回车确认" @keyup.enter="add" v-model="title" />
</template>

4.数组方法(unshift,splice,forEach,filter)

4.1.unshift方法(数组头部加入新数据,push是后面追加)

arr.unshift(数据)

4.2.splice方法:数组删除元素方法

数组删除元素方法,splice(index,len,[item]),如果len为0则数组不变

arr.splice(索引, 1)

4.3.forEach遍历数组(可以每次遍历都对数组数据进行操作)

/* 遍历数组逐个改变其选择状态 */
        this.todos.forEach(item => {
          item.isCompleted = true
        })

4.4.filter过滤筛选数组得到新数组(数组声明里面的数据类型arr : Array<string>)

const 新数组 = arr.filter(循环数组每一项=>筛选条件)

 /* 清除所有选中的数据 */
    clearAllCompletedTodos() {
      /* 筛选出未选中的数组数据组成新数组 */
      const arr: Array<Todo> = this.todos.filter(item => item.isCompleted == false)
      this.todos = arr
      /* 存储数据到本地 */
      saveTodos(this.todos)
    }

Logo

前往低代码交流专区

更多推荐