关键词:
前面的几篇文章已经大致介绍了 Vue 3 的常用 API,现在综合起来做一个实战演练
配合完整代码食用更香哦,项目地址:https://github.com/wisewrong/test-vue3-demo
一、初始化
首先通过 Vue-CLI 创建一个 Vue 3 项目,详细流程可以参考《Vue3.x 从零开始(一)》
vue create test-vue3-demo
勾选 TypeScript、Router、Vuex,版本选用 Vue 3.x,其他的选项可以自行选择,拿不准就直接回车选择默认
初始化完成后的项目是这样的:
store 目录用来维护基于 Vuex 开发的状态仓库
router 目录维护基于 vue-router 开发的路由配置
main.ts 是项目的入口文件,在这里将 Router 和 Vuex 载入项目中:
二、头部导航( Router )
首先需要创建头部导航 <header> 组件,header 属于公共组件,可以放到 components 目录下
header 上有 Home 和 About 两个页面的导航入口,点击导航可以跳转到对应的页面
这个功能可以通过 vue-router 提供的 <router-link> 来实现
<router-link> 是经过封装的 <a> 标签,它需要接收一个路由地址 to,类似于 <a> 标签的 href
<router-link to="/home">Home</router-link>
如果目标路由地址配置了组件,就能在父组件的 <router-view> 中渲染对应组件
路由的配置文件是 src/router/index.ts ,可以配置路由信息,包括路由地址和对应的组件
不过 <router-link> 只适合导航菜单这种【只需要跳转页面,不需要做其他操作】的场景
更多的时候我们需要在函数中进行路由跳转,这时候可以使用 this.$router.push()
三、登录框弹窗( teleport + slot )
首先来完成弹窗组件 <modal>
从业务上来讲,这个弹窗组件是在 <header> 上打开的,也就是说 <header> 会是 <modal> 的父组件
如果按照传统开发组件的方式,<modal> 会渲染到父组件 <header> 的 DOM 节点下
但从交互的层面来说,弹窗是一个全局性的强交互,组件应该渲染到外部,比如 body 标签
在 Vue 3 中提供了一个新的解决方案 teleport
在组件中用 <teleport> 组件包裹需要渲染到外部的模板,然后通过 to 指定渲染的 DOM 节点
<teleport to="body"> <div> <!-- 组件内容 --> </div> </teleport>
to 接收一个可以被 querySelector 识别的字符串参数,用于查找目标 DOM 节点,该 DOM 节点必须在组件外部
这里将 modal 组件渲染到了body 标签
上面的代码还用到了插槽 <slot>
这个标签允许父组件向子组件插入自定义的模板内容,在 <modal> 组件中可以让父组件编辑弹窗的内容
如果组件中需要配置多个 <slot> 标签,还可以用 name 来给 <slot> 命名
<div class="modal-header"> <slot name="header"> <!-- 这里是 slot-header 的默认模板 --> <span class="modal-title">title</span> <button class="modal-close"></button> </slot> </div>
然后在父组件中通过 <template v-slot:name> 向指定的 slot 插入内容
<template v-slot:header> <div> 这里是 slot-header 的内容 </div> </template>
四、完成弹窗表单( $refs + Vuex )
接下来开发登录窗的表单组件 <sign-in-form>
组件的内容十分简单,就是两个输入框 <input />,不多介绍,重点在于获取表单数据
由于这个 <form> 组件是 <header> 的子组件,所以我们需要在 <header> 获取 <form> 的数据并提交
Vue 中可以通过 ref 属性获取自定义组件的实例
比如上面的代码就在 <sign-in-form> 组件上指定了 ref="signInForm"
然后就能在 header 组件中通过 this.$refs.signinForm 获取到表单组件的实例,并直接使用它的 methods 或者 data
// 没有找到适合 $ref 的类型断言,只好用 any const data = (this.$refs.signInForm as any).getValue(); // getValue 是 signInForm 组件中的 methods
现在获取到了登录信息,正常来说需要用登录信息请求登录接口,如果用户名和密码正确,接口会返回用户信息
这里我们就跳过请求接口的过程,直接把登录信息当做用户信息
用户信息对于整个项目来说是一个共用信息,我们可以选择暂存在 localStorage 或 sessionStorage 中,也可以使用 Vuex 来管理
如果在使用 Vue-CLI 创建项目时勾选了 Vuex,就能在 src/store/index.ts 中维护公共变量和方法
然后在组件中通过 this.$store 来使用 Vuex 提供的 API
Vuex 中有 State、Getter、Mutation、Action、Module 五个核心属性
其中 State 就像是 Vue 组件中的相应数据 data,Getter 类似于计算属性 computed
然后 Mutation 和 Action 都可以看做 methods,区别在于:
Mutation 是同步函数,用来更新 state(在严格模式下只能通过 mutation 来更新 state)
// Vuex const state = user: ‘wise wrong‘ ; const mutations = // 所有 mutation 的第一个参数都是 state,后面的参数在调用时传入 updateUser(state, payload) state.user = payload; ; // 组件中通过 commit 来调用 mutations export default // ... methods: handler() this.$store.commit(‘updateUser‘, ‘new user‘); , ;
而 Action 可以看做 Mutation 的父级,用来提交 Mutation,而且可以包含异步函数
// Vuex const actions = // action 的第一个参数是 context,其中包含 commit,用来调用 mutation fetchUser(context, payload) fetch(‘/api‘, payload) .then((res) => // 调用 mutation context.commit(‘updateUser‘, res.data); ) .catch() // 组件中通过 dispatch 来调用 action export default // ... methods: handler() this.$store.dispatch(‘fetchUser‘, id: 123); , ;
回到我们的项目上来,由于我们用的是 TypeScript,所以需要提前定义 state 的类型
// 用户信息 export interface UserState user: string; password: string; // state 的根类型 export interface RootState userInfo: UserState;
然后创建 state.ts 和 mutations.ts
然后在组件中通过 commit 调用 mutation 以更新用户信息:
由于在 Vuex 4 中删除了对全局属性 $store 的类型支持,所以上面的截图中 $store 被标红,代码也无法运行
为解决该问题,可以在 src 目录下创建一个 shims-vuex.d.ts 文件,手动声明 $store
import Store from ‘vuex‘; declare module "@vue/runtime-core" interface ComponentCustomProperties $store: Store;
但我更推荐使用 Vue 提供的辅助函数 map
对于 state,我们可以在 computed 中使用 mapState 将需要的 state 映射到当前组件
import mapState from ‘vuex‘; export default // ... computed: // 组件本身的计算属性 localComputed () /* ... */ , // 使用对象展开运算符将 state 混入当前组件 ...mapState([ ‘userInfo‘, // 以数组的形式传入 state 的键名 ]) , methods: test() // 以计算属性的形式使用 state console.log(this.user);
同样的,对于 mutations 可以通过 mapMutations 混入 methods 中
import mapMutations from ‘vuex‘; export default // ... methods: // 组件本身的方法 test() // 以 methods 的形式调用 mutation this.updateUserInfo(); , ...mapMutations([ // 混入名为 updateUserInfo 的 mutation ‘updateUserInfo‘, ])
上面 this.$store.commit 的调用方式就可以替换成:
到这里为止已经具备了一个简单的 Vue 项目的雏形
接下来会打造一个综合性的 Todo List,并真正用上 Composition API
三个小时vue3.x从零到实战(前)(vue3.x基础)(代码片段)
目录:三个小时vue3.x从零到实战(前)(vue3.x基础)三个小时vue3.x从零到实战(中)(vue3.x高级语法)三个小时vue3.x从零到实战(后)(vue3.x配套工具及项目化构建)三个小时vue3... 查看详情
三个小时vue3.x从零到实战(中)(vue3.x高级语法)(代码片段)
目录:三个小时vue3.x从零到实战(前)(vue3.x基础)三个小时vue3.x从零到实战(中)(vue3.x高级语法)三个小时vue3.x从零到实战(后)(vue3.x配套工具及项目化构建)三个小时vue3... 查看详情
三个小时vue3.x从零到实战(vue3.x经典案例46个)(代码片段)
目录:三个小时vue3.x从零到实战(前)(vue3.x基础)三个小时vue3.x从零到实战(中)(vue3.x高级语法)三个小时vue3.x从零到实战(后)(vue3.x配套工具及项目化构建)三个小时vue3... 查看详情
三个小时vue3.x从零到实战(后)(vue3.x配套工具及项目化构建)(代码片段)
目录:三个小时vue3.x从零到实战(前)(vue3.x基础)三个小时vue3.x从零到实战(中)(vue3.x高级语法)三个小时vue3.x从零到实战(后)(vue3.x配套工具及项目化构建)三个小时vue3... 查看详情
三个小时vue3.x从零到实战(typescript的搭建使用及资料)(代码片段)
目录:三个小时vue3.x从零到实战(前)(vue3.x基础)三个小时vue3.x从零到实战(中)(vue3.x高级语法)三个小时vue3.x从零到实战(后)(vue3.x配套工具及项目化构建)三个小时vue3... 查看详情
(十四)vue3.x核心之getcurrentinstance
...一个很重要的方法,获取当前组件的实例、上下文来操作router和vuex等。2、使用:由vue提供,按需引入:importgetCurrentInstancefrom'vue';下一章:(十五)Vue3.x中我们将采用mitt实现全局事件总上一章:(十三)Vue3.x中的emits选项p... 查看详情
从零开始系列之vue全家桶安装使用vuex(代码片段)
什么是vuex?vuex:Vue提供的状态管理工具,用于同一管理我们项目中各种数据的交互和重用,存储我们需要用到数据对象。 即data中属性同时有一个或几个组件同时使用,就是data中共用的属性。中大型单页应用必备。小型单页... 查看详情
[转]从零构建vue2+vue-router+vuex开发环境到入门,实现基本的登录退出功能(代码片段)
这是一个创建于738天前的主题,其中的信息可能已经有所发展或是发生改变。前言vue2正式版已经发布将近一个月了,国庆过后就用在了公司的两个正式项目上,还有一个项目下个月也会采用vue2进行重构选择它没什么理由,如果... 查看详情
从零开始,用elementui躺坑vue-router原理分析
上一篇,小编讲到在vue-router中是通过mode这一参数控制路由的实现模式的。今天就让我们深入去观摩vue-router源码是如何实现路由的路由起源-后端路由路由这个概念最先是后端出现的。在以前用模板引擎开发页面时,经常会看到... 查看详情
从零开始系列之vue全家桶带新手小白一起搭建第一个个人网站项目
未经允许,严禁转载,全文由blackchaos提供。 在安装好了前面大部分需要的插件,我们开始进行第一个个人项目。结合vue+vuex+vue-cli+vue-router+webpack使用。 1.我们先写用vue-router来单页面切换路由。先进入src文件夹。在component... 查看详情
vue3.x新增特性(代码片段)
.../选择vue的版本◉Babel◯TypeScript◯ProgressiveWebApp(PWA)Support◉Router◉Vuex◯CSSPre-processors◉Linter/Formatter◯UnitTesting◯E2ETesting2.vitevite是一个前端构建工具速度秒开vite内核基于rollup构建项目vite使用原生ESmodule模块系统生成文件基于vi 查看详情
vue3.x新增特性(代码片段)
.../选择vue的版本◉Babel◯TypeScript◯ProgressiveWebApp(PWA)Support◉Router◉Vuex◯CSSPre-processors◉Linter/Formatter◯UnitTesting◯E2ETesting2.vitevite是一个前端构建工具速度秒开vite内核基于rollup构建项目vite使用原生ESmodule模块系统生成文件基于vi 查看详情
从零开始,零基础,一点一点探索vue-router(vue2.0)
首先我们用vue-cli搭建一个vue开发的脚手架,删除它的原来的代码,开始写自己的代码,实现最简单的router功能: 一,开始新建几个自己需要的页面,随便写点东西<template><divid="movie">I‘mmoive!</div></template><... 查看详情
vuejs学习——vue+vuex+vue-router项目搭建
...希望你都熟读了vue+vuex+vue-router的官方文档。下面我们就开始吧。Vue搭建 这里我假设我们的电脑都安装了nodejs,那么我现在开始吧。 我们先新建一个文件(V 查看详情
从零开始利用vue-cli搭建简单音乐网站
1、利用vue-router实现页面跳转程序可以正常运行之后,下面我们需要配置路由实现页面的局部刷新,这一功能将用来实现网站页面的跳转。打开程序目录,进入"src outerindex.js",可以看到程序已经配置了一个路由和其相关联的组件... 查看详情
从零开始使用vite+vue3+pinia+naiveui搭建简单后台管理系统
参考技术A打开vite.config.js文件,引入组件然后在plugins内添加配置这里naiveui使用的是按需自动引入,具体可参考官方文档:按需引入(TreeShaking)-NaiveUI笔者添加了一些打包的配置,不需要可以忽略。配置完成后的样子:在src目录... 查看详情
从零开始做ssh项目(代码片段)
使用hibernate测试加载数据、删除数据和修改数据等功能时,针对的是与数据库表user对应的User。为了简化对其他数据表对应的实体类的持久化操作,可以在项目中创建一个BaseHibernateDAO类,将数据的加载、添加、修改、删除等持久... 查看详情
vuex-router-sync 有啥用?
】vuex-router-sync有啥用?【英文标题】:whatisvuex-router-syncfor?vuex-router-sync有什么用?【发布时间】:2017-10-2513:19:39【问题描述】:据我所知vuex-router-sync仅用于将route与vuexstore同步,开发人员可以访问route,如下所示:store.state.route.... 查看详情