Vue3实战系列:结合 Ant-Design-of-Vue 实践 Composition API
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.vue
和 router/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的更多相关文章
- Vue3实战系列:Vue3.0 + Vant3.0 搭建种子项目
最近在用 Vue3 写一个开源的商城项目,开源后让大家也可以用现成的 Vue3 大型商城项目源码来练练手,目前处于开发阶段,过程中用到了 Vant3.0,于是就整理了这篇文章来讲一下如何使用 Vue3 ...
- 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 ...
- Vue.js高效前端开发 • 【Ant Design of Vue框架进阶】
全部章节 >>>> 文章目录 一.栅格组件 1.栅格组件介绍 2.栅格组件使用 3.实践练习 二.输入组件 1.输入框组件使用 2.选择器组件使用 3.单选框组件使用 4.实践 ...
- Vue.js高效前端开发 • 【Ant Design of Vue框架基础】
全部章节 >>>> 文章目录 一.Ant Design of Vue框架 1.Ant Design介绍 2.Ant Design of Vue安装 3.Ant Design o ...
- Ant design在vue,react的引入
文章地址: https://www.cnblogs.com/sandraryan/ 最近由于 一些不可描述的原因 要研究一下Ant design这个前端框架. 祭上官网: https://ant.de ...
- 蒲公英 · JELLY技术周刊 Vol.21 -- 技术周刊 · React Hooks vs Vue 3 + Composition API
蒲公英 · JELLY技术周刊 Vol.21 选 React 还是 Vue,每个人心中都会有自己的答案,有很多理由去 pick 心水的框架,但是当我们扪心自问,我们真的可以公正的来评价这两者之间的差异 ...
- Ant Design Pro Vue 时间段查询 问题
<a-form-item label="起止日期" :labelCol="{lg: {span: 7}, sm: {span: 7}}" :wrapper ...
- ant design for vue 刷新页面,根据当前路由选中相应菜单
<a-menu theme="dark" mode="horizontal" class="menu__a" @select=&quo ...
- ant design for vue 关于table的一些问题
1.为table添加分页: :pagination="pagination" pagination: { defaultPageSize: 10, showTotal: (tota ...
随机推荐
- 《神经网络的梯度推导与代码验证》之LSTM的前向传播和反向梯度推导
前言 在本篇章,我们将专门针对LSTM这种网络结构进行前向传播介绍和反向梯度推导. 关于LSTM的梯度推导,这一块确实挺不好掌握,原因有: 一些经典的deep learning 教程,例如花书缺乏相关 ...
- vue bus 中央事件总线
1.全局定义bus 新建src/eventBus.js 文件 import Vue from 'vue' export default new Vue() // 全局引入mai.jsvue中央事件总 ...
- 如何解决SpringBoot工程中的错误:java.sql.SQLNonTransientConnectionException: CLIENT_PLUGIN_AUTH is required
出错原因:MySQL依赖及MySQL驱动包高于在使用的MySQL数据库版本. 比如,我本地数据库版本是:Server version: 5.2.3-falcon-alpha-community-nt ...
- 转载:把你的精力专注在java,jvm原理,spring原理,mysql锁,事务,多线程,大并发,分布式架构,微服务,以及相关的项目管理等等,这样你的核心竞争力才会越来越高
https://developer.51cto.com/art/202001/608984.htm 把你的精力专注在java,jvm原理,spring原理,mysql锁,事务,多线程,大并发,分布式架 ...
- 2.AVFormatContext和AVInputFormat
参考https://blog.csdn.net/leixiaohua1020/article/details/14214705 AVFormatContext: 用来存储视音频封装格式(flv,mp4 ...
- Navicat Premium 15.0.17 破解激活(DFoX 注册机)
Navicat Premium v15.0.17 安装程序和注册机已放入百度网盘,下载地址在本文最后 1. 下载并安装 Navicat Premium 15 在官网下载 Windows 版本的 Nav ...
- 记一次函数异常(getopt_long)
前言 以下参考博客以及man手册. getopt_long函数,getopt_long函数包含了getopt函数的功能,并且还可以指定"长参数"(或者说长选项),与getopt函数 ...
- [LeetCode]215. 数组中的第K个最大元素(堆)
题目 在未排序的数组中找到第 k 个最大的元素.请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素. 示例 1: 输入: [3,2,1,5,6,4] 和 k = 2 输出 ...
- Docker实战(5)升级Docker版本后的报错
出现情况:因我升级了Centos内核后docker服务无法开启,所做重装处理但还是无效,最终将docker服务做了升级,升级步骤我会放置下面,但在启动老版本容器又出现Error response fr ...
- web网站——nginx,LNMP部署03
nginx功能: (1)web服务器: 默认网页目录为:/usr/share/nginx/html (2)反向代理服务器: nginx代替客户端访问后端服务器,后端服务器只知道是nginx的请求,并将 ...