zl程序教程

您现在的位置是:首页 >  前端

当前栏目

Vue八股笔记自用2

Vue笔记 自用
2023-09-14 09:13:38 时间

路由
Vue-router的懒加载如何实现
箭头函数+import动态加载
const List = () => import(‘@/components/list.vue’)
const router = new VueRouter({
routes: [
{ path: ‘/list’, component: List }
]
})

箭头函数+require动态加载
const router = new Router({
routes: [
{
path: ‘/list’,
component: resolve => require([‘@/components/list’], resolve)
}
]
})

方案三:使用webpack的require.ensure技术,也可以实现按需加载。这种情况下,多个路由指定相同的chunkName,会合并打包成一个js文件。
// r就是resolve
const List = r => require.ensure([], () => r(require(‘@/components/list’)), ‘list’);
// 路由也是正常的写法 这种是官方推荐的写的 按模块划分懒加载
const router = new Router({
routes: [
{
path: ‘/list’,
component: List,
name: ‘list’
}
]
}))

如何获取页面的hash变化
监听$route的变化
window.location.hash读取#值

r o u t e 和 route和 routerouter的区别
$route是路由信息对象,包括path, params, hash, query, fullPath, matched, name等参数。
$router是路由实例对象,包括了路由的跳转方法,钩子函数等

hash和history
hash模式实际上是通过window.addEventListener(‘hashchange’)监听hash值的变化,从而让vue-router渲染对应的组件
history模式是利用history…pushState()这个状态,通过状态变化通知router呈现的组件。
如何定义动态路由,如何获取传过来的动态参数。
params方式
配置路由格式/router/:id
传递的方式:在path后面跟上对应的值

//在APP.vue中
用户

//在index.js
{
path: ‘/user/:userid’,
component: User,
},

// 方法1:
按钮</router-link

// 方法2:
this.$router.push({name:‘users’,params:{uname:wade}})

// 方法3:
this.$router.push(‘/user/’ + wade)

query方式
在对象中使用query的key作为传输方式
传递后形成的路径:/route?key=value
//方式1:直接在router-link 标签上以对象的形式
档案

// 方式2:写成按钮以点击事件形式
<button @click=‘profileClick’>我的
profileClick(){
this.$router.push({
path: “/profile”,
query: {
name: “kobi”,
age: “28”,
height: 198
}
});
}

vue-router路由钩子
全局路由钩子
Vue-router全局有三个路由钩子;
router.beforeEach 全局前置守卫,进入路由之前
router.beforeResolve 全局解析守卫 在beforeRouteEnter调用之后调用
router.afterEach 全局后置钩子 进入路由之后
具体使用:
beforeEach(判断是否登录,没登陆就跳到登录页)
router.beforeEach((to, from, next) => {
let ifInfo = Vue.prototype.KaTeX parse error: Expected '}', got 'EOF' at end of input: … Vue.prototype.loginUrl;
}
} else {
return next();
}
})

afterEach (跳转之后滚动条返回顶部)
router.afterEach((to, from) => {
window.scrollTo(0, 0)
})

单个路由独享钩子
beforeEnter如果不想全局配置守卫的话,可以为某些路由单独配置守卫,有三个参数:to, from, next
export default [
{
path: ‘/’,
name: ‘login’,
component: login,
beforeEnter: (to, from, next) => {
console.log(‘即将进入登录页面’)
next()
}
}
]

组件内钩子
beforeRouteUpdate, beforeRouteEnter, beforeRouteLeave
这三个钩子都有参数:to, from, next
beforeRouteEnter: 进入组件前触发
beforeRouteUpdate: 当前地址改变并且该组件被复用时触发,举例来说,带有动态参数的路径foo/:id, 在/foo/1和/foo/2之间跳转时,由于会渲染同样的foa组件,这个钩子在这种情况下就会被调用
beforeRouteLeave:离开组件被调用

触发钩子的完整顺序
beforeRouteLeave:路由组件的组件离开路由前钩子,可以取消路由离开
beforeEach:路由全局前置首位i,可用于登录验证、全局路由loading等
beforeEnter:路由独享守卫
beforeRouteEnter:路由组件的组件进入路由前钩子
beforeResolve: 路由全局解析守卫
afterEach: 路由全局后置钩子
beforeCreate -> created -> beforeMount -> deactivated ->mounted -> activated
执行beforeRouteEnter回调函数next

vue-router跳转和Location.href的区别
location.href跳转刷新页面 而vue-router跳转不会
router.push(/url)跳转,使用了diff算法,实现了按需加载,减少了dom的损耗

params 和 query 区别
query刷新不丢失而params刷新丢失
Vuex
Vuex中的状态存储是响应式的,当Vue组件从store读取状态时,若store中的状态发生变化,那么相应的组件也会更新
改变store中的状态的唯一途径就是显式的提交(commit)mutation。这样可以方便地跟踪每一个状态的变化。

Vue Components时vue组件,组件会触发(dispatch)一些事件或动作,也就是图中的actions;
在vuex中,actions会把组件发来的动作提交(commit)到Mutations中
然后mutations就去改变(mutate) state里的数据
state中的数据被改变后,就会重新render到vue components中,组件展示更新后的数据。
actions负责处理Vue components接收到的所有交互行为。包含同步异步操作,向后台请求api的操作就在这个模块中进行,该模块支持action的链式触发。
getters类似于组件中的computed,可以对state的数据进行一些处理,且也是响应式的。

vuex的简单应用
登陆前,state里的userInfo为空,登陆后存入
下面就是在created中调用函数,而函数向actions dispatch了一个动作,这个动作是为了在actions中请求api。

{{realName}}

export default{
computed(){
//第三步
realName:this.$store.getters.realName
},

created(){
//第一步
this.reqUserInfo()
},
methods:{
reqUserInfo(){
//第二步使用action不想之前state、getters一样直接点调用,而是用dispatch关键字来派发action
this.$store.dispatch(‘getUserInfo’)
}
}

}

下面是actions里的操作
async getUserInfo(context){
//1.从接口里异步获取数据
const res = await axios.get(‘/接口url’)

  //2.将获取到的数据,通过commit提交一个mutation,去更改state里面的userInfo
  context.commit( SET_USER_INFO,{userInfo:res.userData})

},

然后在mutations中更改state里的userInfo即可
SET_USER_INFO(state, payload) {
state.userInfo = payload.userInfo
}

更改之后getters也会基于改变后的数据进行处理
realName:(state)=>{ return state.userInfo.userName+‘’ },

辅助函数(mapGetters, mapMutations, mapState, mapActions)
mapState
computed: {
value(){
return this.val++
},
…mapState([‘likes’,‘friends’,‘token’,‘userInfo’])

}

// 等价于
userInfo(){
return this.$store.state.userInfo
},

token(){
return this.$store.state.token
},

friends(){
return this.$store.state.friends
},

likes(){
return this.$store.state.likes
},

mapMutations
methods:{
…mapMutations([‘addAge’])
}

// 相当于
methods:{
addAge(payLoad){

this.$store.commit(‘addAge’,payLoad)
}
}

//传参

<button @click=“AddAge({number:1})”>增加一岁
复制代码
mapGetters
computed: {
valued(){
return this.value++
},
…mapGetters([‘realName’,‘myMoney’])
}

mapActions
methods:{
…mapActions([‘getUserInfo’,‘getToken’])
}
//相当于
methods:{
getUserInfo(){
return this.KaTeX parse error: Expected 'EOF', got '}' at position 35: …UserInfo’) }̲, getToken(…store.dispatch(‘getToken’)
},
}

Vuex module
我们将Vuex中的store分成大大小小的对象,这个对象就叫做module模块,每个module也都有state, actions, mutations, getters。
建立一个moduleA和一个moduleB
export default {
state: {
text: ‘moduleA’
},
getters: {},
mutations: {},
actions: {}
}

export default {
state: {
text: ‘moduleB’
},
getters: {},
mutations: {},
actions: {}
}

在store的主文件index.js中,我们这样引入两个module
import moduleA from ‘./module/moduleA’;
import moduleB from ‘./module/moduleB’;
export default new Vuex.Store({
modules: {
moduleA, moduleB,
},
// …
}

注册了moduleA和moduleB,我们就可以在组件使用了
// …
computed: {
…mapState({
name1: state => state.moduleA.text,
name2: state => state.moduleB.text
}),
},
// …

由此我们可以看出,对于不同module,他的state是独立的,那mutations,getters,actions也是如此吗?
其实并不是,mutations,actions,getters是默认注册在全局命名空间的,也就是说一个module的改变会引起所有module的变化,具体看下面的例子
在moduleA中的mutations修改state里的text
mutations: {
setText(state) {
state.text = ‘A’
}
},

在组件里获取,会发现moduleA和moduleB里的text都被更改了

actions和getters也是同理
暂时没遇到这样的场景,不做总结
放个学习的链接,遇到了再翻看Vuex白话教程第六讲:Vuex的管理员Module(实战篇) - 简书 (jianshu.com)
vuex和localstorage

持久化
vuex的数据存放在内存中,页面刷新数据就会丢失,而localstorage存放在硬盘内,刷新页面不会丢失。
响应式
vuex的数据是经过响应式处理的,而localstorage没有。
应用场景
vuex主要是为了数据的集中管理,用于组件传值,而localstorage一般用于跨页面传输(同域名)。个人认为只有不变的数据且不更换数据源情况下才用localstorage,比如token