目录
mixin—局部
如果组件与mixin冲突怎么办?总结:
mixin造成的问题:
mixin—全局
Vue2与Vue3的区别 Options API的弊端
setup函数有哪些参数?
setup函数的返回值
setup不可以使用this
Vue3中 reactive 和 ref 和 toRefs 和 toRef
readonly只读属性
toRef
computed
Wacth监听
Vue2 watch监听
vue3 watch的使用
Vue3 watchEffect
watchEffect的停止侦听
watchEffect清除副作用
setup中使用 ref 获取dom
vue2 ref 获取dom
认识vue-router
vue3的路由模式
路由守卫vue2 vue3
访问的页面 404 路由怎么配
那啥 开始就声明解释一下mixin,它不叫米新,它叫米克僧嗯,mix + in 额 就说通不通易不易懂,在本文我将以最为通俗的、让能看懂的话术解释V3Api,当然了一些概念还的是全面点!
红框和绿框组件,都有相同的方法,和钩子,那么你将他们相同的剪贴走,建一个文件粘贴
进去(mixin.js 也可以是aa.js),最后导入页面,就是混合原理
配合代码更加贴切,易懂
/*
*
* 子组件uname
*
/
姓名:{{ uname }}
/*
*
* 子组件school
*
/
学校:{{ uname }}
/*
*
* 父组件 引入子组件
*
/
/*
*
* 新建mixin JS文件
*
/
export const MyMiXin = {
// data、methods、如果和组件重复,只会执行组件的内容,mixi不会执行
methods: {
choseName() {
alert(this.uname)
},
fn() {
console.log('mixin方法');
}
},
// 钩子函数事特殊的,它会合并组件的钩子,先执行mixin钩子,在执行组件钩子
created() {
console.log("mixin钩子");
},
}
首先Vue是渐进式框架,不需要必须使用它的api,可替代性很强,你可以只用我的一部分,而不是所有部分
更新中。。。
什么是全局选项? 就是 全局组件,全局过滤器,全局指令,全局mixin
1、Vue.component 注册的 【全局组件】
2、Vue.filter 注册的 【全局过滤器】
3、Vue.directive 注册的 【全局指令】
4、Vue.mixin 注册的 【全局mixin】
相对于Vue2来说,Vue3最大的突破就是 Composition API
。与现有的Vue2 Option API
截然不同
data定义数据、methods中定义方法、computed中定义计算属性、watch中监听属性改变
,也包括生命周期钩子
;假如一个大项目,逻辑很多,那么同一个功能的逻辑就会被拆分的很分散,这个组件的代码是难以阅读和理解的(阅读组件的其他人),碎片化的代码使用理解和维护变得很困难,如果我们能将同一个逻辑关注点相关的代码
收集在一起
会更好,这个位置就是Vue3 setup 函数
// setup函数有哪些参数?
// setup函数有什么样的返回值
// setup(props, context)
setup(props, {attrs, slots, emit}) {//解构context
console.log(props.message);
console.log(attrs.id, attrs.class);
console.log(slots);
console.log(emit);
return {
}
},
props
context
props非常好理解,它其实就是父组件传递过来的属性会被放到props对象中,我们在setup中如果需要使用,那么就可以直接通过props参数获取:
另外一个参数是context
attrs
:所有的非prop的attribute;slots
:父组件传递过来的插槽emit
:当我们组件内部需要发出事件时会用到emit任何人写的文都不会比官方文档还要全,建议撸一遍V3官方文档
this并没有指向当前组件实例
;data、computed、methods
等都没有被解析;无法在setup中获取this
;
reactive 是vue3的一个组合api vue3中新增的最核心的功能就是组合api
reactive vue3建议只用来声明对象 他声明的对象中的每一个属性都是响应式的
他是结合es6的proxy 结合递归给每一个reactive声明的对象数据添加上 setter/getter方法 从而实现数据的响应式
ref是用reactive封装成的一个方法 这个方法我们通常用来声明基本数据类型和数组数据
ref声明的数据是一个对象 值是value ref在使用的时候不需要写value 但是赋值的时候必须写value
toRefs可以解构reactive对象的属性 将属性取出 转换成一个ref对象,假如你要reactive里面的obj.name,在return{}用了 ...toRefs(obj)就可以直接使用name
如果不经过toRefs,直接解构是不具备相应式的
setup() {
const info = reactive({name: "why", age: 18});
// 1.toRefs: 将reactive对象中的所有属性都转成ref,
// 如果不经过toRefs,直接解构是不具备相应式的
let { name, age } = toRefs(info);
return {//具备相应式
name,
age
}
}
总结ref:
什么是解包:
a解构出来相当于 a={value:xx}
使用场景:在父传子时就可以将接受的数据定为只读,子组件不允许直接修改父组件的数据,如果一个子组件有很多父组件(子组件定义结构样式,父组件传递不同的值,以显示不同的页面),子组件修改父组件可能会造成数据混乱,因为多个父组件可能定义了相同的变量,但是可以子传父,不能直接在子组件修改父组件数据
如果我们只希望转换一个reactive对象中的属性为ref, 那么可以使用toRef的方法:
比如在computed() 中不需要赋值一个变量,再比如定义方法必须赋值一个变量choseNameEv可以是aa但是对应的 点击事件也要变化
子组件:(函数写法)
{{ resultName }}
父组件:
效果图:
子组件 ——— (第二种对象写法 )
{{ resultName }}
其实和Vue2差不多,下面是Vu2的
商品价格--- {{sumPrice}}
// Vue2 简写wacth
watch: {
sum (newValue, oldValue) {
console.log("sum的数值的变换新值、老值", newValue, oldValue);
}
},
//完整写法
watch: {
obj: {
handler (newvalue, oldvalue) {
console.log(newvalue, oldvalue)
},
immediate: true, //立即监听
deep: true // 深度监听
}
},
// 监听路由:
wacth:{
"$router.path":(new,old)=>{
console.log(new,old)
}
}
watch(() =>person.name, (newVal, oldVal)=> {
console.log(newVal, oldVal)
})
如果监听person对象里的多个值:wacth小括号中以数组形式书写,在数组中用箭头函数 例如:
watch([() =>person.name, ()=> person.age], (newVal, oldVal)=> {undefined
console.log(newVal, oldVal)
})
//监听ref单一值的变化
watch(监听的值, (newvAL, oLdVal) => {
console.log(newvAL, oLdVal)
})
// 监听ref多个值的变化 数组形式
watch([msg, sum], (newVal, oldVal) => {
console.log(newVal, oldVal)
})
// 监听reactive中的整个person对象
watch(person, (newVal, oldVal)=> {
console.log(newVal, oldVal)
}, {deep: true})
// 监听reactive对象中某一个属性的变化
watch(() =>person.name, (newVal, oldVal)=> {
console.log(newVal, oldVal)
})
//监听person对象里的某一个值,开启深度监听
watch([() => person.job], (newVal, oldVak) => {
console.log(newVal, oldVak)
}, {deep: true})
//监听person对象里的某两个值
watch([() =>person.name, ()=> person.age], (newVal, oldVal)=> {
console.log(newVal, oldVal)
})
注意:wacth监听打印新旧值都是一样的,因为监听的同一条数据,监听的都是同一个引用
{{ obj.age }}
总结:vue3 wacth后是一个小括号,在小括号中操作,如果要监听ref单个的值,监听的值逗号箭头函数,箭头函数里面有两个形参,new,old,可以在对象中直接打印,
监听多个值,可以在监听值的地方使用数组,多个值以逗号分隔
监听ractive复杂对象类型 :wacth小括号,监听的对象逗号箭头函数,箭头函数中有两个值,new,old,在箭头函数对象中可以直接打印,如果要开启深度监听,在箭头函数后面加逗号,逗号后面是对象,对象中开启deep:true
{{ uname }}-{{ age }}
如果在发生某些情况下,我们希望停止侦听,这个时候我们可以获取watchEffect的返回值函数,调用该函数即可。
思路:watchEffect的返回值,在终于条件哪里调用
{{ uname }}:{{ age }}
就是防抖思路,假如用watchEffect检测Ajax请求,例如查询搜索:要在本次点击或输入之前,清除上一次的请求,
主要思路就是watchEffect的 onInvalidate 参数,watchEffect的停止侦听是利用返回值,请求异步检测则需要利用onInvalidate 参数清除上一次请求
{{ age }}
思路:主要是利用 watchEffect箭头函数后的对象里的 flush: "post", watchEffect(
() => { },
{
flush: "post", //默认 flush: "async" 异步
}
);
恭喜你有学到了
vue2获取dom
- React的ReactRouter
- Vue的vue-router
- 目前Vue路由最新的版本是4.x版本。
- vue-router是基于路由和组件的
还是那句话,v3是 Composition API,用那那个引入那个
// 在路由元信息配置守卫 requiredPath为true, 适合守卫多个页面 vue3next() 变成return true
// vue2
router.beforeEach((to, from, next) => {
if (localStorage.getItem('token')) {
next()
} else {
if (to.meta.requiredPath) { //没有token requiredPath为true 守卫不让进,跳入login
next('/login')
} else {
next()
}
}
})
// vue3
router.beforeEach((to, from) => {
// ...
// 返回 false 以取消导航
return false
// return "/login"
})
还是建议将官方文档撸一遍 导航守卫 | Vue Router
// router/index.js
{
// 如果url找不到就会报404
path: "/:pathMatch(.*)",
component: () =>
import ("../views/NotFound.vue")
}
效果: