vue3
Vue是一套用于构建用户界面的渐进式 JavaScript框架
渐进式 JavaScript框架 : 表示我们可以在项目中一点点来引入和使用Vue,而不一定需要全部使用Vue来开发整个项目;
常见的基础指令
v-once : 只执行一次
v-pre : 跳过该元素及其所有子元素的编译
v-cloak : 用于隐藏尚未完成编译的 DOM 模板 搭配css [v-cloak] { display : none ;}
v-memo : 只有满足的值,才会重新渲染页面 [代码实例]
class的绑定[代码实例] 和 style的绑定 [代码实例]
v-on : 事件绑定 传递多个参数 -- 固定值 $event
v-on的修饰符 :
.stop - 调用 event.stopPropagation()。
.prevent - 调用 event.preventDefault()。
.capture - 添加事件侦听器时使用 capture 模式。
.self - 只当事件是从侦听器绑定的元素本身触发时才触发回调。
.{keyAlias} - 仅当事件是从特定键触发时才触发回调。
.once - 只触发一次回调。
.left - 只当点击鼠标左键时触发。.right - 只当点击鼠标右键时触发。.middle - 只当点击鼠标中键时触发。
.passive - { passive: true } 模式添加侦听器
v-if , v-else-if ,v-else 和 v-show
template元素可以当做不可见的包裹元素,并且在v-if上使用,但是最终template不会被渲染出来
区别 :
v-show是不支持template; v-show不可以和v-else一起使用;
v-show元素无论是否需要显示到浏览器上,它的DOM实际都是有存在的,只是通过CSS的display属性来进行切换;
v-if当条件为false时,其对应的原生压根不会被渲染到DOM中;
如果我们的原生需要在显示和隐藏之间频繁的切换,那么使用v-show; 如果不会频繁的发生切换,那么使用v-if;
v-for : 循环
被监听的方法有 : push() , pop() , unshift() , shift() , splice() , reverse() , sort() [这些方法都会直接修改原来的数组]
不会修改原数组的方法,那么就直接替代它 : filter() , concat() , slice()
v-for中的key的作用 : 主要用在vue的虚拟Dom算法:在新旧VNode比较
(key用于虚拟Dom,而虚拟Dom又可以做新旧VNode对比,又会生产有虚拟Dom树 : 可以跨平台编译,可以增强性能)
v-model : 双向数据绑定[都用在表单]
它相当于 : v-bing绑定value属性的值 ; v-on绑定input事件监听到函数中,函数会获取最新的值赋值到绑定的属性中
1.v-model 绑定 checkbox [代码实例]
2.v-model绑定 radio [代码实例]
3.v-model绑定 select [代码实例]
4.修饰符 :
.lazy : 会将绑定的事件切换为 change 事件,只有在提交时(比如回车)才会触发
.trim : 自动过滤用户输入的守卫空白字符
两个个Options Api :(computed,watch)
1.computed 计算属性
特点 : 1.有缓存 ; 2.在调用的时候不用加();
简写模式 : 跟函数写法一样
原始模式 : get 和 set [代码实例]
2.watch 监听器
简写模式 : 跟函数写法一样 , 想要监听那个,就在那个()
原始模式 : [代码实例]
特别模式 : $watch [代码实例]
3.全局组件 : [代码实例]
4.局部组件 : [代码实例]
脚手架
安装 : npm install @vue/cli -g
创建 : Vue create 项目的名称 / vite创建 npm init vue@latest
创建的信息 :
组件之间的通信
1.父传子: props
在组件上可以写一些元素, 子组件可以通过props来接收到
A: props的默认写法 : 数组 [弊端 : 不能对类型进行验证 , 没有默认值的] [代码实例]
B: props的对象写法-数组写法 : [代码实例]
2.子传父: $emit
子组件通过$emit发出自定义事件,父组件接收自定义事件
普通形式 : [代码实例]
vue3新特性 : [代码实例]
3.祖孙组件的传递
祖先采用 : Provide 发送 一般都是写成函数形式
孙子采用 : Inject 接收 [代码实例]
4.全局事件总线
vue3已经没有提供全局事件总线的$on,$off,$once方法了
这里我们采用这个库 : npm i hy-event-store
emit : 发送 on : 监听 off : 移除
使用的方法 : [代码实例]
插槽
子组件 用 <slot> 标签来表示插槽 , 属性name 表示插槽的名字
父组件 插入 指定那个插槽 用 : v-slot:名字 简化 : #名字
作用域插槽 子组件通过在 <slot>标签上传递信息 , 父组件通过props接受
1.普通插槽 [代码实例]
3.作用域插槽 [代码实例]
零散知识点 :
1.$refs的使用 : 直接获取到元素对象或者子组件实例 [代码实例]
2.动态组件的使用 : 以前我们可以通过v-if来让哪些组件显示;现在有了动态组件了
动态组件 , 通过一个特殊的attribute is 来实现 : <component is=' '> </component>
传值和监听事件都是一样的写法 [ is 的来源是子组件的name的值 ] [代码实例]
3.keep-alive 保存组件的状态,不会被销毁掉
3个属性 :
使用了它后,会出现2个声明周期 : activated 和 deactivated [代码实例]
4.分包 : 组件的分包可以通过 defineAsyncComponent 来实现异步组件 [异步组件就是为了可以分包使用]
5.组件的v-model : [代码实例] 不常用的!
6.mixin的基本使用
mixin的全局混入 :
vue3的 Composition API开始
setup 函数 : 它代替了 : options API 的 methods、computed、watch、data、生命周期等等
它的两个参数 : props 和 context
props : 是父组件传递过来的属性会被放到props对象中,我们在setup中如果需要使用,那么就可以直接通过props参数获取
context,我们也称之为是一个SetupContext,它里面包含三个属性 :
返回值 : 可以在模板template中被使用,也就是说我们可以通过setup的返回值来替代data选项;
第一个API : reactive
reactive 函数 只能处理复杂类型 : object array [ 代码实例 ]
第二个API : ref
原因 : 因为reactive只能使用复杂类型,所以出现了 ref 来使用简单类型(string,boolean,number)[而且 ref 也可以使用复杂类型]
使用 ref 返回的是一个 ref对象 ,我们的值是对象里面的value : 一般 ref对象.value [代码实例]
注意 :
1.在模板中使用,vue会自动帮我们解包,不需要 .value [解包 : 自动取出其中的value]
2.在setup中,需要 ref对象.value
3.ref 是一个浅层的解构 : 在template使用的时候可以不用.value , 在template修改一定需要.value [ 代码实例 ]
总结 : ref 和 reactive Api
reactive :
一般是应用于本地的数据 ;
多个数据之间是有联系的 ;
ref :
一般都是定义本地的一些简单数据;
定义从网络请求获得的数据 [ref对象.value = [请求数据]]
第三个API :readonly
vue是一个单向数据流(规范) : 父组件传递的数据,子组件只能使用,不能修改;
原因 : 正常子组件却是可以修改父组件传递的数据的 ; 所以vue3产生了 readonly 来防止 子组件的修改行为
解决 : 如果子组件确实想修改 : 应该发送数据, 让父组件来修改 [这样做才知道哪个子组件来修改父组件的值]
错误实例 (没采用单向数据流) : [ 代码实例 ]
正确实例(采用readonly) : [ 代码实例 ]
注意 : 经过readonly 处理后的对象是不能被修改的 , 但是原本的对象我们可以修改
第四.Reactive判断的API 和 ref判断的API
isRef
判断值是否是一个ref对象
shallowRef
创建一个浅层的ref对象[ref创建的对象,也是一个深层的响应式的]
triggerRef
手动触发和shallowRef创建的浅层的,变为深层的
第五个API : toRefs 和 toRef
原因 : 我们通过reactive创建出来的数据,想要对它进行解构; 但是解构出来的值,就失去了响应式了
解决 : toRefs 就来解决失去响应式的问题
toRefs(值1) : 值1 : 对象
想要单独解构一个值 : 使用 toRef
toRef(有值1和值2) : 第一个值是对象 , 第二个值是要解构对象中的哪个数据
第六个API : ref 获取元素和组件
想要获取,我们要在onMounted中,才可以获取到.因为 setup 出现的时候,template还没编译呢 [ 代码实例 ]
第七个API : provide 和 inject 祖孙传递数据
provide(值1,值2) : 值1(提供的属性名称) ; 值2(提供的属性值)
inject(值1,值2) : 值1(provide提供的属性名称) 值2(可以提供默认值)
computed 计算函数 [代码实例]
watch 和 watchEffect 监听函数
watch
1.watch 监听ref的简单类型(默认都是深度监听) [代码实例]
2.watch 监听ref的复杂类型(需要加上deep,才可以监听到,但是得不到原对象) [代码实例]
由于第二种情况,我们得不到值,这里建议监听复杂类型的,我们要使用reactive,不要用ref
3.watch 监听reactive (并且可以得到原对象) [代码实例]
watchEffect [ 代码实例 ]
1.watchEffect传入的函数会被立即执行一次,并且在执行的过程中会收集依赖;
2.只有收集的依赖发生变化时,watchEffect传入的函数才会再次执行;
3.watchEffect会返回一个值,想要停止的时候,调用它就好了
生命周期函数
setup的语法糖
1.组件导入后,不需要用components 注册, 可以直接使用
2.顶层绑定会暴露给末班, 也就是不需要使用 return 了
3.接受父组件传递过来的东西 : defineProps 函数 [不需要导入,可以直接使用]
4.发送自定义事件 : defineEmits 函数 [不需要导入,可以直接使用]
5.defineExpose :
在setup的语法糖中,想要把方法,属性暴露出去,需要使用 defineExpose ,
暴露出去后,父组件可以通过 ref 来获取子组件,从而来调用子组件的方法和属性
vue的路由器
一般我们直接用脚手架选线的,就有给我们配置了
1.路由分包也叫路由懒加载 : 其实就是为了打包后分开,不合在app.js的包里面.所以才有懒加载,可以优化渲染速度.
懒加载可以给他们加上打包后的名称 : component: () => import(/* webpackChunkName: "about" */ '../views/AboutView.vue')
2.如何使用?
1. <router-view></router-view> 来展示路由页面的
3.路由的重定向 + 路由的name和meta属性 + 没有匹配到路由 + 子路由 [ 代码实例 ]
4.动态路由 -- useRoute - params [ 代码实例 ]
5.编程式路由 -- useRouter - query [ 代码实例 ]
叫做编程式路由 : 就是因为实在script中写到代码,所以才这样叫编程式路由
router.push : 跳转
router.replace :跳到新页面(没有历史记录)
router.back() 返回
router.forward() 前进
6.动态添加路由
一般都是在后台管理系统出现,目前后台管理系统有2种做法 :
1.根据不同角色,生产不同的菜单 ; 对应的菜单的路由还是有注册的
2.根据不同角色,生产不同的菜单 ; 菜单和路由都是动态注册的 === 这就应用到了动态添加路由
// 1.动态管理路由
let isAdmin = true
if (isAdmin) {
// 一级路由
router.addRoute({
path: "/admin",
component: () => import("../Views/Admin.vue")
})
// 添加home,下面的vip子页面
router.addRoute("home", {
path: "vip",
component: () => import("../Views/HomeVip.vue")
})
}
7.路由导航守卫
to : 进入的页面。from :离开的页面
beforeEach
// 路由导航守卫
// 进行任何的路由跳转之前, 传入的beforeEach中的函数都会被回调
// 需求: 进入到订单(order)页面时, 判断用户是否登录(isLogin -> localStorage保存token)
// 情况一: 用户没有登录, 那么跳转到登录页面, 进行登录的操作
// 情况二: 用户已经登录, 那么直接进入到订单页面
router.beforeEach((to, from) => {
// 1.进入到任何别的页面时, 都跳转到login页面
// if (to.path !== "/login") {
// return "/login"
// }
// 2.进入到订单页面时, 判断用户是否登录
const token = localStorage.getItem("token")
if (to.path === "/order" && !token) {
return "/login"
}
})
其他的导航守卫 : 地址
状态管理工具 : vuex 和 pinia
能用 pinia 尽量别用 vuex
vue2 + vuex [ 全部推荐使用映射 ]
state(数据) : [ 代码实例 ]
getters(计算属性) : [ 代码实例 ]
mutations : [ 代码实例 ]
修改 state 的数据,必须通过 mutation 来修改 [ 只写同步操作!!! 想发送异步的 : 采用actions]
mutations的出现也是为了 devtools 来捕捉快照
actions(方法) : [ 代码实例 ]
action 类似于 mutation,不同于 :
action提交的是mutation,而不是直接变更状态;
action可以包含任意异步操作
在store里面通过 commit 来提交 mutation
在使用的时候通过dispatch来提交action
modules : [ 代码实例 ]
vue3 + vuex [不推荐使用!!!,vue3推荐pinia]
state(数据) : [ 代码实例 ] 推荐使用基本,不用映射
getters(计算属性) : [ 代码实例 ] 推荐使用基本,不用映射
参数1:state 参数2:getters
mutations : [ 代码实例 ] 推荐使用基本,不用映射
修改 state 的数据,必须通过 mutation 来修改 [ 只写同步操作!!! 想发送异步的 : 采用actions]
mutations的出现也是为了 devtools 来捕捉快照
mutations 在使用的时候通过 commit('') 来提交
actions(方法) : [ 代码实例 ] 推荐使用基本,不用映射
action 类似于 mutation,不同于 :
action提交的是mutation,而不是直接变更状态;
action可以包含任意异步操作
在store里面通过 commit 来提交 mutation
在使用的时候通过dispatch来提交action
发送网络请求 : [ 代码实例 ]
modules : [ 代码实例 ]
在模块中的话,getters,会有第三个参数 : rootState 得到的是根的state
vue3 + pinia [强烈推荐使用]
没有mutations ; ts支持 ; 不用module ; 非常简单好用
npm i pinia
创建和使用 : [ 代码实例 ]
state(数据) - getters(计算属性) : [ state 和 getters 的代码实例 ]
重置方法 : $reset
修改信息 : $patch
actions(方法) : [代码实例]
axios网络请求库 npm i axios
2.get请求(params) 和 post请求(data) 的 2种方式 : [ 代码实例 ]
3.创建axios实例 [ 代码实例 ]
原因:
当我们从axios模块中导入对象时, 使用的实例是默认的实例;
当给该实例设置一些默认配置时, 这些配置就被固定下来了.
但是后续开发中, 某些配置可能会不太一样;
比如某些请求需要使用特定的baseURL或者timeout等.
本文来自博客园,作者:杨建鑫,转载请注明原文链接:https://www.cnblogs.com/qd-lbxx/p/16589087.html