惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

AI
AI
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
Google DeepMind News
Google DeepMind News
T
Tenable Blog
博客园_首页
S
Securelist
Spread Privacy
Spread Privacy
Google Online Security Blog
Google Online Security Blog
Forbes - Security
Forbes - Security
Engineering at Meta
Engineering at Meta
U
Unit 42
L
LINUX DO - 热门话题
量子位
T
Threat Research - Cisco Blogs
博客园 - 【当耐特】
C
Cyber Attacks, Cyber Crime and Cyber Security
K
Kaspersky official blog
MyScale Blog
MyScale Blog
P
Proofpoint News Feed
The Last Watchdog
The Last Watchdog
Google DeepMind News
Google DeepMind News
GbyAI
GbyAI
Martin Fowler
Martin Fowler
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
Security Latest
Security Latest
Scott Helme
Scott Helme
V
Vulnerabilities – Threatpost
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
I
InfoQ
Know Your Adversary
Know Your Adversary
Cisco Talos Blog
Cisco Talos Blog
The Register - Security
The Register - Security
T
The Blog of Author Tim Ferriss
aimingoo的专栏
aimingoo的专栏
V2EX - 技术
V2EX - 技术
T
Tailwind CSS Blog
月光博客
月光博客
Recent Announcements
Recent Announcements
G
Google Developers Blog
F
Full Disclosure
W
WeLiveSecurity
宝玉的分享
宝玉的分享
腾讯CDC
G
GRAHAM CLULEY
Vercel News
Vercel News
Simon Willison's Weblog
Simon Willison's Weblog
美团技术团队
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
Help Net Security
Help Net Security

Leon.D’s Blog

使用Element.animate添加文字与图片动画 Howdz起始页开发记录 利用G渲染器实现的音频可视化方案 Vue3实现自定义右键菜单 Dashboard自定义面板项目介绍 开发Online Code Editor过程的一些记录 Howdyjs组件库迁移Vue3设计与总结 使用D3.js将离散的点形成平滑曲线及其应用 使用Taro-next将个人网盘功能扩展到微信小程序 断点续传与个人网盘系统的前后端设计 个人组件库展示站点搭建总结 Github Webhooks与Koa2实现简单的前端自动化部署 浏览器导航首页设计 CSS实现判断鼠标进入方向 简易电商系统开发记录(Nuxtjs+Koa) 考试系统设计总结
Vue3上手, 使用vite实现一个简单的Todolist应用
2020-05-16 · via Leon.D’s Blog

Vite

Vite is an opinionated web dev build tool that serves your code via native ES Module imports during dev and bundles it with Rollup for production.

目前,Vue-cli 还未能直接搭建 vue3 应用,需要在 vue2 的项目上通过执行vue add next命令进行升级。

而 Vite 是官方提供的一个可以快速搭建 vue3 新工具,它是一个简易的 http 服务器,无需通过 webpack 打包即可实时解析 vue3 文件,并能实现热更新。

现在最新版的 vite 已经提供了一个简易模板,可以直接使用一下命令快速搭建

安装与启动

$ npx create-vite-app <project-name>
$ cd <project-name>
$ npm install
$ npm run dev

具体参考官方仓库: https://github.com/vuejs/vite#getting-started

Typescript

vite 最新版默认已经可以直接对 typescript 进行解析编译,直接在 vue 文件中的script标签下加入lang="ts"即可。

Sass

执行命令安装 sass, npm i sass -D, 然后在 vue 文件的style标签下加入lang="scss"即可,这些与以前 vue2 都是一样的。

Vuex

支持 vue3 的 vuex 最新版现在还未正式发版,需要使用npm i vuex@next -D来安装。
Vuex 的新语法进行了一些变更,你需要使用 Vuex.createStore 来创建,其他语法没有区别。

import Vuex from "vuex";
// or => import { createStore } from 'vuex'
export default Vuex.createStore({
  state: {},
  mutations: {},
  actions: {},
  modules: {},
});

然后在 main.js 引入这个文件并 use

import { createApp } from "vue";
import App from "./App.vue";
import store from "./store/index.js";
import "./assets/base.css";
createApp(App).use(store).mount("#app");

Vue Compostion Api

Vue3 最大的一个变化就是使用Vue Compostion Api, 现在官方已经提供了 中文文档

本次只用到了其中很少一部分的 API,而且可能使用方式不一定准确,仅供参考,望见谅。

功能设计

  • 对 TodoList 的操作:完成、取消、添加、删除
  • 可记录不同日期的 TodoList
  • 对记录了 TodoList 的日期进行标注

现在先来看一下最终项目 DEMO 成果

点击头部的日期会弹出日期选择,可选择其他日期。

实现

主要组件Card.vue组件,然后里面包含一个日期选择组件DatePicker.vue 为了练习一下 vuex 在 vue3 的使用,将当前的选择日期记录在了 vuex 中。

主要逻辑代码

// Card.vue
import { ref, reactive, computed, watch } from "vue";
import { useStore } from "vuex";
import { Todo, getTodoList, setTodoList } from "../model/todo";
import DatePicker from "./DatePicker.vue";
const weekArr: string[] = [
  "Sunday",
  "Monday",
  "Tuesday",
  "Wednesday",
  "Thursday",
  "Firday",
  "Saturday",
];
export default {
  name: "Card",
  components: {
    DatePicker,
  },
  directives: {
    focus(el) {
      el.focus();
    },
  },
  props: {
    date: String,
    showAddBtn: Boolean,
  },
  setup(props) {
    const store = useStore();
    const state = {
      editingValue: ref(""),
      showDatePicker: ref(false),
    };
    let todoList = reactive([]);
    watch(
      () => props.date,
      (val) => {
        todoList.length = 0;
        todoList.push(...getTodoList(props.date));
        // state.showDatePicker.value = false
      },
      {
        immediate: true,
      }
    );
    const weekDay = computed(() => weekArr[new Date(props.date).getDay()]);
    const formatterDate = computed((): string => {
      const arr: string[] = new Date(props.date).toDateString().split(" ");
      return `${arr[1]} ${arr[2]}, ${arr[3]}`;
    });
    const handleChecked = (item: Todo): void => {
      item.isChecked = !item.isChecked;
      setTodoList(props.date, todoList);
      store.commit("refreshTodoListDateArr");
    };
    const handleRemove = (index: number): void => {
      todoList.splice(index, 1);
      setTodoList(props.date, todoList);
      store.commit("refreshTodoListDateArr");
    };
    const handleAdd = (): void => {
      state.editingValue.value = "";
      todoList.push({
        content: "",
        isChecked: false,
        isEditing: true,
      });
    };
    const handleEditSubmit = (item: Todo, index: number): void => {
      if (item.isEditing) {
        if (state.editingValue.value) {
          item.content = state.editingValue.value;
          item.isEditing = false;
        } else {
          todoList.splice(index, 1);
        }
        setTodoList(props.date, todoList);
        store.commit("refreshTodoListDateArr");
      }
    };
    return {
      weekDay,
      formatterDate,
      todoList,
      handleChecked,
      handleRemove,
      handleAdd,
      handleEditSubmit,
      ...state,
    };
  },
};

组件功能实现都比较简单,本次只为了熟悉语法,所以具体代码逻辑在这就不进行讲解了。

项目打包

使用npm run build或者npx vite build即可打包项目。

Vite 的打包基于 Rollup

需要注意的是,vite 也是想 vue-cli 那样提供了配置文件的,在根目录下添加vite.config.js即可,例如本地打包后项目是通过 https://kongfandong.cn/todo 来访问的,如果使用默认的打包配置,会出现资源 404 的问题。这时需要给打包配置资源路径/todo,加入以下配置:

// vite.config.js
module.exports = {
  base: "/todo",
};

Vite 还提供了很多其他的配置,具体请参考: https://github.com/vuejs/vite/blob/master/src/node/config.ts

一个插曲

一开始,我使用 vuex 是使用getCurrentInstance获取 vue 的实例想像 vue2 那样类似this.$store.state来使用 vuex 的,就像下面的代码

import { computed, getCurrentInstance } from "vue";
export default {
  setup() {
    const { ctx } = getCuurentInstance();
    const selectedDate = computed(() => ctx.$store.state.selectedDate);
    return {
      selectedDate,
    };
  },
};

这样 ts 会报错,提示 ctx 的类型没找到,通过查源码发现 vue 并没有把 ctx 的类型抛出。然后我就改成了

import { computed, getCurrentInstance } from "vue";
export default {
  setup() {
    const instance: any = getCuurentInstance();
    const ctx = instance.ctx;
    const selectedDate = computed(() => ctx.$store.state.selectedDate);
    return {
      selectedDate,
    };
  },
};

然后一切如愿进行,开发环境下什么问题也没有了。但是,到了打包之后运行,浏览器就报错了

index.js:9 Uncaught TypeError: Cannot read property 'state' of undefined
    at index.js:9
    at n (index.js:1)
    at Object.get value [as value] (index.js:1)
    at Object.get (index.js:1)
    at Object.get (index.js:1)
    at index.js:9
    at Vn (index.js:1)
    at Proxy.<anonymous> (index.js:9)
    at Proxy.<anonymous> (index.js:1)
    at nt (index.js:1)
(anonymous) @ index.js:9
...

报错 state 没找到,程序上的 vuex 的$store 是 undefined。然后我查了好久也没找到解决办法,于是只能在 github 上提个 issue。

最后得到了解答,原来在setup()中是不能使用getCurrentInstance的!

具体 Issue: https://github.com/vuejs/vite/issues/156

最终的解决办法,引入 vuex 的 useStore 方法,就可以在 setup 中使用 vuex 了。

最后代码改为:

import { computed } from "vue";
import { useStore } from "vuex";
export default {
  setup() {
    const store = useStore();
    const selectedDate = computed(() => ctx.$store.state.selectedDate);
    return {
      selectedDate,
    };
  },
};

总结

这个小 Demo 的实现过来还是遇到了不少问题,但还是一一解决了,可以让我对 vue3 与 typescript 进行了初步的了解。目前只是因为还不太熟悉,但感觉 vue3 未来发展潜力还是很大的。

还有 Vite 这个工具好像也是很强大的,目测 Vue3 官方后面有可能会直接推荐使用该工具进行开发了,有可能会放弃的 Webpack 了。