vue学习
1、v-if和v-show区别
v-if按照条件
是否渲染,v-show是通过display
的属性值block或none 控制的
比较:v-if完整的销毁和重新创建,v-show通过css切换
使用场景:频繁切换使用v-show,运行时较少改变用v-if
2、route和router的区别
router是用来操作路由
的,route是用来获取路由信息
router是VueRouter的一个实例,包含所有的路由,包括路由的跳转方法,钩子函数
route是一个跳转的路由对象,每个路由都会有一个route对象,是一个局部的对象。
$router的用法
//常规方法
this.$router.push("/login");
//使用对象的形式 不带参数
this.$router.push({ path:"/login" });
//使用对象的形式,参数为地址栏上的参数
this.$router.push({ path:"/login",query:{username:"jack"} });
使用对象的形式 ,参数为params 不会显示在地址栏
this.$router.push({ name:'user',params: {id:123} });
$route的用法
主要的属性有:
this.$route.path 字符串,等于当前路由对象的路径,会被解析为绝对路径,如/home/ews
this.$route.params 对象,包含路由中的动态片段和全匹配片段的键值对,不会拼接到路由的url后面
this.$route.query 对象,包含路由中查询参数的键值对。会拼接到路由url后面
this.$route.router 路由规则所属的路由器
this.$route.name 当前路由的名字,如果没有使用具体路径,则名字为空
3、keep-alive实现原理
定义:是Vue中内置的一个抽象组件,它本身不会渲染一个DOM元素,也不会出现在父组件链中,当它包裹的动态组件时,会缓存不活动的组件实例,而不是销毁它们
用法
路由表中定义属性keepAlive: true
{
path: "/index",
name: 'index',
component: () => import(/* webpackChunkName: "index" */ '@/pages/index'),
meta: {
title: '首页',
keepAlive: true
},
},
<keep-alive>
<router-view v-if="$route.meta.keepAlive"></router-view>
</keep-alive>
<router-view v-if="!$route.meta.keepAlive && isRouterAlive"></router-view>
组件可以接收三个属性:
include
- 字符串或正则表达式。只有名称匹配的组件会被缓存。exclude
- 字符串或正则表达式。任何名称匹配的组件都不会被缓存。max
- 数字。最多可以缓存多少组件实例。
<!-- 逗号分隔字符串 -->
<keep-alive include="a,b">
<component :is="view"></component>
</keep-alive>
<!-- 正则表达式 (使用 `v-bind`) -->
<keep-alive :include="/a|b/">
<component :is="view"></component>
</keep-alive>
<!-- 数组 (使用 `v-bind`) -->
<keep-alive :include="['a', 'b']">
<component :is="view"></component>
</keep-alive>
注意:想要缓存的组件一定要给定name属性,并且要和include,exclude给定的值一致
使用keepalive组件后,被缓存的组件生命周期会多activated
和deactivated
两个钩子函数,它们的执行时机分别是 <keep-alive>
包裹的组件激活时调用和停用时调用。
4、Vue生命周期
Vue生命周期共分为8个阶段:创建前/后,载入前/后,更新前/后,销毁前/后。
设置keep-alive缓存特殊的两个阶段activated(组件激活时)、deactivated(组件停用时)。
- 首次进入组件时:beforeRouteEnter > beforeCreate > created> mounted > activated > … … > beforeRouteLeave > deactivated
- 再次进入组件时:beforeRouteEnter >activated > … … > beforeRouteLeave > deactivated
缓存后如何获取数据
// 方案一(推荐)
beforeRouteEnter(to, from, next){
next(vm=>{
console.log(vm)
// 每次进入路由执行
vm.getData() // 获取数据
})
},
// 方案二
activated(){
this.getData() // 获取数据
},
// 注意:服务器端渲染期间avtived不被调用
5、vue请求数据放在created好还是mounted里好
建议放在created里
created:在模板渲染成html前调用,即通常初始化某些属性值
,然后再渲染成视图。
mounted:在模板渲染成html后调用,通常是初始化页面完成后
,再对html的dom节点进行一些需要的操作。
如果在mounted钩子函数中请求数据可能导致页面闪屏
问题
其实就是加载时机问题,放在created里会比mounted触发早一点,如果在页面挂载完之前请求完成的话就不会看到闪屏了。
请求的数据对DOM有影响,那么使用created,
如果请求的数据对DOM无影响,可以放在mounted。
6、vue中$nextTick(() => {})用法及原理
Vue 实现响应式并不是数据发生变化之后 DOM 立即变化,而是按一定的策略进行 DOM 的更新。$nextTick 是在下次 DOM 更新循环结束之后执行延迟回调,在修改数据之后使用 $nextTick,则可以在回调中获取更新后的 DOM
在Vue生命周期的created()钩子函数进行的DOM操作一定要放在Vue.nextTick()的回调函数中
7、父子组件的执行顺序
- 加载渲染过程
父beforeCreate->父created->父beforeMount->子beforeCreate->子created->子beforeMount->子mounted->父mounted - 子组件更新过程
父beforeUpdate->子beforeUpdate->子updated->父updated - 销毁过程 - 销毁父组件时,先将子组件销毁后才会销毁父组件 ;
父beforeDestroy->子beforeDestroy->子destroyed->父destroyed
总结
created:html加载完成之前执行。执行顺序:父组件-子组件
mounted:html加载完成后执行。执行顺序:子组件-父组件
methods:事件方法执行
watch:watch是去监听一个值的变化,然后执行相对应的函数,默认无数据改动不执行 需要配置{immediate:true}
初始化会执行一次
computed:computed是计算属性,也就是依赖其它的属性计算所得出最后的值,默认初始化是执行一次的
created():dom还未生成,仅仅触发一次;
mounted:dom渲染完毕,仅仅执行一次;
activated():在使用时keep-live主要目的是可以使用缓存,避免组件重新渲染;只要进入组件激活就会触发。
在 Vue 2 中,这些选项执行的顺序
- props :父组件传递给子组件的属性会首先被处理。
- data :在处理完 props 之后,Vue 会处理数据对象中的所有属性,并将它们添加到 Vue 实例中。
- computed :计算属性会在处理完 data 之后被计算,并添加到 Vue 实例中。
- watch :侦听器会在 computed 之后被处理,并添加到 Vue 实例中。
- created :在处理完所有选项后,Vue 实例会调用 created 钩子,并完成实例化。
- mounted :在实例挂载到DOM元素之后,Vue 实例会调用 mounted 钩子。
- methods :实例方法会在 mounted 之后被处理,并添加到 Vue 实例中。
8、Vue路由
1、创建路由
import Vue from 'vue'
import Router from 'vue-router'
Vue.use(Router)
//创建路由对象
const createRouter = () => new Router({
scrollBehavior: () => ({ y:0 }), //页面的位置
routes:[...]
})
const router = createRouter()
//重置路由
export function resetRouter(){
const newRouter = createRouter()
router.matcher = newRouter.matcher
}
2、路由参数
import Layout from '@/layout'
export const constantRoutes = [
{
path: '/',
name: 'home',
component: Layout,
meta: { title: '系统首页', platform: PLATFORM_CODE.OA },
children: [
{
path: '/',
component: () => import('@/views/home/index'),
name: 'home',
meta: { title: '门户', affix: true, platform: PLATFORM_CODE.OA }
}
]
},
{
path: '/login',
component: () => import('@/views/login/index'),
hidden: true
},
{
path: '/404',
component: () => import('@/views/error/404'),
hidden: true
},
{
path: '/401',
component: () => import('@/views/error/401'),
hidden: true
},
{
path: '/print',
component: () => import('@/views/oa/apply/print/print-detail'),
hidden: true
},
...sysRoutes
]
3、全局前置守卫
router.beforeEach(function(to,from,next){
})
三个形参:(从A跳转到B)
1、to:将要访问的路由的信息对象 (B方)
2、from:是将要离开的路由的信息对象(也就是A方)
3、next:是一个函数,调用 next() 表示旅行,允许本次路由导航,如果在fn里面不写 next(),那么全部的路由都不会实现跳转(因为在路由执行之前,先触发了fn回调,然后没有被放行)
9、Vuex
Vuex的作用
vuex是专门为vue.js应用程序开发的状态管理模式,采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生改变。最大的便利就是state响应式。
Vuex的核心概念
State – 存储状态信息
Getters – 状态信息的计算属性 类似computed
Mutations – 修改状态信息
Actions – 状态信息异步处理
Modules-- store对象模块化
流程顺序
视图触发Action
,Action再触发Mutation
触发方式
mutation 的触发通过store.commit
进行
action 的触发通过store.dispatch
进行
角色定位
Mutation 专注于修改state,理论上是修改state的唯一途径,必须同步执行
Action 业务代码、异步请求,可以异步,但不能直接操作state
10、watch和computed差异
watch
是进行数据监听
,然后进行相应的操作,执行方法等conputed和methods的合体使用,比较耗性能
,与vue性能优化相背而驰,尽量减少使用!computed
是数据改变进行相应的数据变化,由老数据迸发新的数据(return返回),会利用缓存机制
对数据进行缓存 ,只有当依赖数据变化的时候才会进行相应的变化
11、Vue实现数据双向绑定的原理
访问器属性
访问器属性是对象中的一种特殊属性,它不能直接在对象中设置,而必须通过defineProperty() 方法单独定义。
var obj = {};
// 为obj定义一个名为hello的访问器属性
Object.defineProperty(obj,'hello',{
get:function(){ return sth},
set:function(val){ // do sth }
})
obj.hello //可以像普通属性一样读取访问器属性
访问器属性的"值"比较特殊,读取或设置访问器属性的值,实际上是调用其内部特性:get和set函数。
get 和 set 方法内部的 this 都指向 obj,这意味着 get 和 set 函数可以操作对象内部的值。另外,访问器属性的会"覆盖"同名的普通属性,因为访问器属性会被优先访问,与其同名的普通属性则会被忽略。
双向绑定的实现
12、Vue路由传参params与query
1、param传参方式类型网络请求的post
,参数不会显示地址栏中,只能配合name
使用,刷新浏览器,参数会丢失。所以路由参数要修改为 '/login/:username'
(官方称为动态路由)
2、query传参比param传参灵活,可以配合name或者path使用,参数会在地址栏中显示(?name=xx&age=xx)
,缺点参数信息暴露,容易被修改。
params 传参
- 编程式
data:{
username: ''
},
login() {
...
this.$router.push({
name: 'home', //注意使用 params 时一定不能使用 path
params: { username: this.username },
})
}
- 声明式
<router-link :to="{ name: 'home', params: { username: username } }">
- 取值
this.$route.params.username
query 传参
- 编程式
data:{
username: ''
},
login() {
...
this.$router.push({
path: '/home',
query: { username: this.username },
})
}
- 声明式
<router-link :to="{ path: '/home', query: { username: username } }">
- 取值
this.$route.query.username
13、页面缓存
1、使用sessionStorage、localStorage
sessionStorage.setItem('key',value)
sessionStorage.getItem('key')
2、使用keep-alive
- 路由配置文件设置
name: 'BookOrder',
meta:{
keepAlive:true
}
- 标注需要缓存的组件,用包裹
<template>
<section class="app-main">
<transition name="fade-transform" mode="out-in">
<keep-alive :include="cachedViews">
<router-view v-if="!$route.meta.link" :key="key" />
</keep-alive>
</transition>
</section>
</template>
<script>
export default {
name: 'AppMain',
computed: {
cachedViews() {
return this.$store.state.tagsView.cachedViews
},
key() {
return this.$route.path
}
}
}
</script>
- vue页面中的name要与Router中name一致
export default {
name: "BookOrder",
data{}
}
持续更新…