Vue 3 出来之后,很多人有如下想法,“又要学新东西啦”、“我学不动了”等等。

但是事物总有它的两面性,前端知识更新的很快,利好勤奋好学的同学。计算机行业的迭代速度很快,前端在计算机领域里,算是前浪被拍在沙滩上比较快的。

我很羡慕还在学校的同学,因为现在的大学生,信息的获取量比我当年在大学的时候大得多,我希望你们能珍惜这样的机会,好好的学习新知识,希望你们进入社会不要被毒打。

学习一门新的技术,我认为最好的方式就是通过 Demo 去制造使用场景,通览一遍 API,需要做到什么程度呢?

大概就是什么场景用什么 API 都能了如于心,再大白话一点就是可以将之前用 Vue2.x 写的代码,用 Vue 3 无差别重构一遍。

构建 Vue3.0 的三种方式

就目前而言,构建 Vue 3 的项目有三种方式。

1、命令行工具 (CLI)

对于 Vue 3,你应该使用 npm 上可用的 Vue CLI v4.5 作为 @vue/cli@next。要升级,你应该需要全局重新安装最新版本的 @vue/cli

yarn global add @vue/cli@next
# OR
npm install -g @vue/cli@next

2、Vite

Vite 是一个 web 开发构建工具,由于其原生 ES 模块导入方法,它允许快速提供代码。

通过在终端中运行以下命令,可以使用 Vite 快速设置 Vue 项目。

使用 npm:

npm init vite-app <project-name>
cd <project-name>
npm install
npm run dev

3、Webpack

很早的时候,Vue-CLI 还没支持 Vue 3 项目的创建,Vue 团队制作了一个 Webpack 的项目配置放在 Github,可以直接克隆下来使用。

git clone https://github.com/vuejs/vue-next-webpack-preview.git demov3
cd demov3
npm install
npm run dev

不推荐使用这种方式,现在都有上面两种了~~

(以前看星星看月亮的时候叫人家“小甜甜”,现在新人胜旧人,叫人家“牛夫人”)

代码实践

我们选择比较新鲜的 Vite 去构建项目,要玩就玩最潮的。我的本地 Node 版本是 v12.6.0,尽量保持一致。

构建项目

npm init vite-app todo-v3
cd todo-v3
npm install // 建议使用淘宝镜像 cnpm install
npm run dev

启动之后如下所示,代表成功了:

入口页面

首先映入眼帘的是 main.js 的变化:

// Vue 3.0
import { createApp } from 'vue'
import App from './App.vue'
import './index.css' createApp(App).mount('#app')
// Vue 2.x
import Vue from 'vue'
import App from './App.vue' new Vue({
render: h => h(App)
}).$mount('#app')

第一段代码是 Vue 3 的创建 Vue 实例形式,通过 createApp 的形式,你别说,和 React 真的挺像的。

第二段是 Vue 2.x 的创建 Vue 实例形式,通过 new 的形式创建。

添加路由 Vue-Router

截止目前,vue-router-next 更新到了 v4.0.0-beta.12 版本。

你如果用 cnpm install vue-router 安装路由,是会下载到 vue-router 3.x 的版本,我们需要使用:

cnpm install vue-router@next -S

安装完毕之后,我们开始配置项目路由,在 src 目录下新建 rourer 文件夹,在文件夹下新建 index.js 文件,添加如下内容:

import {createRouter, createWebHashHistory} from 'vue-router'

export default createRouter({
history: createWebHashHistory(),
routes: []
})

Vue 2.x 的路由模式通过 mode 选项为 history 或 hash 去控制。

而在 Vue 3 中,通过 createRouter 创建路由实例,history 属性作为控制路由模式的参数,createWebHashHistory 方法返回的是 hash 模式,createWebHistory 返回的是 history 模式,本项目采用 hash 模式。

同样,我们需要在 mian.js 中引入 router 实例:

import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import './index.css' createApp(App).use(router).mount('#app')

添加全局状态 Vuex

vuex 更新到了 v4.0.0-beta.4 版本,所以我们需要用如下指令安装:

cnpm i vuex@next -S

接下来在 src 目录下创建 store 文件夹,再新建 index.js 文件,添加代码如下:

// Vue 3
import { createStore } from 'vuex' export default createStore({
state() {
return {
author: "十三",
};
},
});

对比 Vue 2.x 写法:

// Vue 2.x
import Vuex from 'vuex' Vue.use(Vuex) export default new Vuex.Store({
state,
mutations,
actions,
modules: {}
})

同样是使用新的写法,通过 vuex 内部抛出的 createStore 方法,创建一个 Vuex 实例。

接下来我们将它引入到 main.js 中:

import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
import './index.css' // 链式调用
createApp(App).use(router).use(store).mount('#app')

引入 Antd for Vue3 版本组件库

Antdv2.x是唐金州老师(杭州校宝在线)研发的新一代适配 Vue 3.0 的组件库,我们来尝尝鲜,这边我们通过如下命令后下载:

cnpm i --save ant-design-vue@next -S

mian.js 内引入 ant-design-vue 组件如下所示:

import { createApp } from 'vue'
import Antd from 'ant-design-vue';
import App from './App.vue'
import router from './router'
import store from './store'
import 'ant-design-vue/dist/antd.css';
import './index.css' // 本教程采用的是全局引入组件库 createApp(App).use(router).use(store).use(Antd).mount('#app')

测试一下是否成功,顺便解释一下 Vue 3 如何声明变量,以及如何通过方法改变变量,代码如下:

<template>
<a-button @click="add" type="primary">
点我加{{ count }}
</a-button>
<a-button @click="add2('a')" type="primary">
点我加a{{ state.a }}
</a-button>
<a-button @click="add2('b')" type="primary">
点我加b{{ state.b }}
</a-button>
</template> <script>
import { ref, reactive } from 'vue'
export default {
setup() {
const count = ref(0)
const state = reactive({
a: 0,
b: 0,
})
const add = () => {
count.value += 1
}
const add2 = (type) => {
state[type] += 1
}
return {
state,
count,
add,
add2
}
}
}
</script>

如上述代码所示,Vue 3 新增的 setup 方法,颠覆了之前传统的 options 属性方式,我们可以将业务逻辑都写在 setup 方法中。

我们有两种声明变量的形式:

  • ref:它用于声明简单的基础类型变量,如单个数字、boolean、字符串等等。
  • reactive:它用于对象引用类型的复杂变量。

所有声明好的变量和方法,如果想在 template 模板里使用的话,必须在 setup 方法里 return,否则无法调用。记住返回什么就是声明,如返回 count,模板中就用 {{ count }},返回 state,模板中就使用 {{ state.a }} 。效果如下所示:

待办事项 TODO

首先我们新建 views 文件夹用于放置页面组件,在 views 内新建 todo.vue 文件,如下所示:

<template>
<div id="components-layout-demo-basic">
<a-layout>
<a-layout-header>待办事项</a-layout-header>
<a-layout-content>内容</a-layout-content>
</a-layout>
</div>
</template> <script>
import { ref, reactive } from 'vue'
export default {
setup() { }
}
</script> <style scoped>
#components-layout-demo-basic {
min-height: 100vh;
max-width: 40%;
margin: 0 auto;
background-color: #ededed;
}
#components-layout-demo-basic .ant-layout-header,
#components-layout-demo-basic .ant-layout-footer {
background: #7dbcea;
text-align: center;
color: #fff;
}
</style>

引入 antd-v 的布局组件,再给一些基础样式。

然后前往 App.vuerouter/index.js 做如下改动:

// App.vue
<template>
<router-view></router-view>
</template> <script>
export default {
name: 'App'
}
</script>
import {createRouter, createWebHashHistory} from 'vue-router'

export default createRouter({
history: createWebHashHistory(),
routes: [
{
path: '/todo',
component: () => import('../views/todo.vue')
}
]
})

最后页面出现如下所示,代表配置成功:

添加新增待办事项输入框:

<template>
<div id="components-layout-demo-basic">
<a-layout>
<a-layout-header>待办事项</a-layout-header>
<a-layout-content>
<a-input-search
v-model:value="todo"
placeholder="请输入要代办的事项"
size="large"
@search="addTodo"
>
<template v-slot:enterButton>
<a-button>新增</a-button>
</template>
</a-input-search>
</a-layout-content>
</a-layout>
</div>
</template>
<script>
import { ref, reactive } from 'vue'
import { ref, reactive } from 'vue'
export default {
setup() {
const todo = ref('') const addTodo = (value) => {
console.log(value)
}
return {
todo,
onSearch
}
}
}
</script>

如下图所示:

添加“待办事项”和“已办事项”模板,代码如下:

<template>
<div id="components-layout-demo-basic">
<a-layout>
<a-layout-header>待办事项</a-layout-header>
<a-layout-content>
<a-input-search
v-model:value="todo"
placeholder="请输入要代办的事项"
size="large"
@search="addTodo"
>
<template v-slot:enterButton>
<a-button>新增</a-button>
</template>
</a-input-search>
<h2 class="title">待办事项</h2>
<a-card title="标题">
<template v-slot:extra>
<a-switch />
</template>
内通
</a-card>
<h2 class="title">已办事项</h2>
<a-card title="标题">
<template v-slot:extra>
<a-switch />
</template>
内通
</a-card>
</a-layout-content>
</a-layout>
</div>
</template> <script>
import { ref, reactive } from 'vue'
export default {
setup() {
const todo = ref('') const addTodo = (value) => {
console.log(value)
}
return {
todo,
onSearch
}
}
}
</script> <style scoped>
#components-layout-demo-basic {
min-height: 100vh;
max-width: 40%;
margin: 0 auto;
background-color: #ededed;
}
#components-layout-demo-basic .ant-layout-header,
#components-layout-demo-basic .ant-layout-footer {
background: #7dbcea;
color: #fff;
text-align: center;
}
.title {
margin: 0;
padding: 10px;
}
</style>

效果如下:

接下来我们来添加代办的相应逻辑:

<template>
<div id="components-layout-demo-basic">
<a-layout>
<a-layout-header>待办事项</a-layout-header>
<a-layout-content>
<a-input-search
v-model:value="todo"
placeholder="请输入要代办的事项"
size="large"
@search="addTodo"
>
<template v-slot:enterButton>
<a-button>新增</a-button>
</template>
</a-input-search>
<h2 class="title">待办事项</h2>
<a-card :title="`${index + 1}、${item.time}`" v-for="(item, index) in todos" :key="item.id">
<template v-slot:extra>
<a-switch v-model:checked="item.done" @change="handleCheck(item, true)" />
</template>
{{ item.content }}
</a-card>
<h2 class="title">已办事项</h2>
<a-card :title="`${index + 1}、${item.time}`" v-for="(item, index) in dones" :key="item.id">
<template v-slot:extra>
<a-switch v-model:checked="item.done" @change="handleCheck(item, false)" />
</template>
内通
</a-card>
</a-layout-content>
</a-layout>
</div>
</template> <script>
import { ref, reactive, computed } from 'vue'
export default {
setup() {
const todo = ref('')
const time = `${new Date().getFullYear()}-${new Date().getMonth()}-${new Date().getDate()}` const state = reactive({
todoList: [
{
id: 1,
done: false,
time: time,
content: '前往老八食堂,共进午餐'
},
{
id: 2,
done: false,
time: time,
content: '和giao哥合唱一曲'
},
{
id: 3,
done: false,
time: time,
content: '做点阳间的需求'
}
]
})
// 添加待办事项
const addTodo = (value) => {
if(!value) {
message.error('请输入待办事项')
return
}
state.todoList.push({
content: value,
id: Date.now(),
time: time,
done: false
})
todo.value = ''
}
// 通过计算属性,计算出生成的代办事项列表
const todos = computed(() => {
return state.todoList.filter(item => !item.done)
})
// 通过计算属性,计算出生成的已办列表
const dones = computed(() => {
return state.todoList.filter(item => item.done)
})
// 修改状态方法
const handleCheck = (item ,status) => {
item.done = status
} return {
todo,
addTodo,
state,
todos,
dones,
handleCheck
}
}
}
</script> <style scoped>
#components-layout-demo-basic {
min-height: 100vh;
max-width: 40%;
margin: 0 auto;
background-color: #ededed;
}
#components-layout-demo-basic .ant-layout-header,
#components-layout-demo-basic .ant-layout-footer {
background: #7dbcea;
color: #fff;
text-align: center;
}
.title {
margin: 0;
padding: 10px;
}
</style>

setup 内使用 computed 方法,接收一个回调函数,回调函数内的变量都会被监听,比如上述 state.todoList 已经被监听了,我们在 handleCheck 方法内修改待办事项的状态,也会被 computed 监听,所以就会刷新 template 模板,效果如下:

总结

Vue 3.0 还有很多值得我们探索的知识,上述内容只是简单的教大家如何入门搭建一个项目,并且如何通过新的 API 去结合组件库进行实践,后续我也会继续整理其他的实践技巧,源代码已经开源到 GitHub vue3-examples仓库中,仓库地址:https://github.com/newbee-ltd/vue3-examples,此仓库将不定期更新各种 Vue3.0 相关的知识及各种整合 Demo 及 Vue3 使用小技巧,大家可以关注一下,有什么建议也欢迎大家给我留言。

Vue3实战系列:结合 Ant-Design-of-Vue 实践 Composition API的更多相关文章

  1. Vue3实战系列:Vue3.0 + Vant3.0 搭建种子项目

    最近在用 Vue3 写一个开源的商城项目,开源后让大家也可以用现成的 Vue3 大型商城项目源码来练练手,目前处于开发阶段,过程中用到了 Vant3.0,于是就整理了这篇文章来讲一下如何使用 Vue3 ...

  2. ant design for vue 解决 vue.esm.js?c5de:628 [Vue warn]: Invalid prop: custom validator check failed for prop "defaultValue". 的错误

    错误重现: 在使用ant design for vue 的选择器插件的时候, 设置默认为为id(为数字) 报错: 解决办法: id为数字, 而defaultValue 的key 值必须为字符串, 将i ...

  3. Vue.js高效前端开发 • 【Ant Design of Vue框架进阶】

    全部章节 >>>> 文章目录 一.栅格组件 1.栅格组件介绍 2.栅格组件使用 3.实践练习 二.输入组件 1.输入框组件使用 2.选择器组件使用 3.单选框组件使用 4.实践 ...

  4. Vue.js高效前端开发 • 【Ant Design of Vue框架基础】

    全部章节 >>>> 文章目录 一.Ant Design of Vue框架 1.Ant Design介绍 2.Ant Design of Vue安装 3.Ant Design o ...

  5. Ant design在vue,react的引入

    文章地址: https://www.cnblogs.com/sandraryan/ 最近由于 一些不可描述的原因 要研究一下Ant design这个前端框架. 祭上官网: https://ant.de ...

  6. 蒲公英 &#183; JELLY技术周刊 Vol.21 -- 技术周刊 &#183; React Hooks vs Vue 3 + Composition API

    蒲公英 · JELLY技术周刊 Vol.21 选 React 还是 Vue,每个人心中都会有自己的答案,有很多理由去 pick 心水的框架,但是当我们扪心自问,我们真的可以公正的来评价这两者之间的差异 ...

  7. Ant Design Pro Vue 时间段查询 问题

    <a-form-item label="起止日期" :labelCol="{lg: {span: 7}, sm: {span: 7}}" :wrapper ...

  8. ant design for vue 刷新页面,根据当前路由选中相应菜单

    <a-menu theme="dark" mode="horizontal" class="menu__a" @select=&quo ...

  9. ant design for vue 关于table的一些问题

    1.为table添加分页: :pagination="pagination" pagination: { defaultPageSize: 10, showTotal: (tota ...

随机推荐

  1. django学习(二)

    1.反向解析 什么是方向解析呢? 通过一些方法得到一个结果,该结果可以直接访问对应url出发视图函数. 先给一个路由和视图函数起一个别名.但是我们要注意的是反向解析的别名是不可以冲突的!!!不然会出现 ...

  2. Stack (30)(模拟栈,输出中间数用set)

    Stack is one of the most fundamental data structures, which is based on the principle of Last In Fir ...

  3. 深入了解Netty【六】Netty工作原理

    引言 前面学习了NIO与零拷贝.IO多路复用模型.Reactor主从模型. 服务器基于IO模型管理连接,获取输入数据,又基于线程模型,处理请求. 下面来学习Netty的具体应用. 1.Netty线程模 ...

  4. 实际项目中遇到EF实体类的操作问题及操作方法

    之前一直做ASP,都是直接写数据库操作语句,但是现在使用linq或者EF了,具体数据库操作不会了,遇到几个问题,然后经过查找资料解决了,记录一下. 一.遇到序列化问题 遇到循环引用问题,我的项目是一个 ...

  5. java之5分钟插入千万条数据

    虽说不一定5分钟就插入完毕,因为取决去所插入的字段,如果字段过多会稍微慢点,但不至于太慢.10分钟内基本能看到结果. 之前我尝试用多线程来实现数据插入(百万条数据),半个多小时才二十多万条数据. 线程 ...

  6. Python爬取NBA虎扑球员数据

    虎扑是一个认真而有趣的社区,每天有众多JRs在虎扑分享自己对篮球.足球.游戏电竞.运动装备.影视.汽车.数码.情感等一切人和事的见解,热闹.真实.有温度. 受害者地址 https://nba.hupu ...

  7. UI自动化时,解决selenium中无法点击Element:ElementClickInterceptedException

    在跑自动化时,页面上有2个下拉框,两个下拉框无论屏蔽哪一段都会成功,但是同时放开跑时会报错,百度给的解释是上面的下拉框元素覆盖了下面下拉框的元素定位,才会导致报错 百度的解决办法有2种: elemen ...

  8. Spring注解不生效原因总结

    在Spring的注解学习中发现使用(@Resource.@PostConstruct. @PreDestroy)这三个注解时不生效.使用@Resource发生空指针异常,说 明被注解对象没有被成功注入 ...

  9. xml的复习

    xml的复习 1.概念:可扩展标记语言 2.功能: *存储数据    1.配置文件     2.在网络中传播 3.xml与html区别: xml语法严格,HTML语法松散 xml存储数据,HTML展示 ...

  10. Redis安装即python使用

    一:简介 redis是一个key-value存储系统.和Memcached类似,它支持存储的value类型相对更多,包括string(字符串).list(链表).set(集合).zset(sorted ...