vue小知识(全部)

vue的基础知识

  • v-model作用

    v-model本质:语法糖,可以使用v-model指令在表单元及元素上创建数据的双向绑定。
    
  • vue2.0双向绑定缺陷

      vue2.0的数据响应采用数据劫持结合发布者-订阅者模式的方式,通过object.defineProperty()来劫持各个属性的setter、getter。
    
    1、vue实例创建后,无法检测到对象属性的新增或者删除,仅可追踪到数据是否被修改。
    
    解决:Vue.set(obj, propertName/index, value)
    
    2、无法监听数组的变化,数组push、pop、shift、unshift、splice、sort、reverse方法可以监听。
    
  • vue3.0数据双向绑定

    vue3.0通过proxy实现数据双向绑定。proxy为es6新增的特性(代理),proxy可以让我们能够以简洁易懂的方式控制外部对象的访问。proxy可理解为,在目标对象之前架设一层拦截,外界对对象进行访问,必须通过这层拦截,因此提供机制,可以对外界访问进行过来和改写。
    
  • vuex

    专门为vuejs应用程序设计的状态管理工具,采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生改变。
    

router

  • 全局路由守卫beforeEach(前置)、afterEach(后置)
import router from './router';
router.beforeEach((to, from, next)=>{
   // if未登录todo
   // next({path:"/login"})
   // 已登录
   // next()
});
router.afterEach((to, from)=>{
   // todo
})
  • 路由守卫
import Login from "./Login.vue"
const router = new VueRouter({
   routes:[
      {
         path:"/login",
         component:Login,
         beforeEnter:(to, from, next)=>{
            // todo
         }
      }
   ]
})
  • 组件内守卫(与周期函数同级)
beforeRouteEnter(to, from, next){
   // 渲染组件的对应路由被confirm前调用
   // 不可以获取组件实例this
   // 守卫执行时,组件并未创建
}
beforeRouteUpdate(to, from, next){
   // 当前路由改变,该组件被重复调用
   // 可以访问组件实例this
}
beforeRouteLeave(to, from, next){
   // 导航离开组件对应的路由调用
   // 可以访问组件实例this
}

路由懒加载

懒加载:打包构建应用,JavaScript包非常大,影响页面加载。把不同路由对应组件分割成不同的代码快,路由被访问时才载入对应组件。(提供效率)

const Home = ()=>import("./Home.vue")
const router = new VueRouter({
   routes:[
      {path:"/home", component:Home}
   ]
})

HashRouter 和 HistoryRouter 的区别和原理

  • HashRouter原理

    hash模式的工作原理是hashChange事件,可在window监听hash的变化。在url后面添加#xxx触发事件。vue-router默认是hash模式-使用url的hash来模拟一个完整的url,当url改变的时候,页面不会重新载入,也就是单页面应用,当#后面的hash变化,不会导致浏览器向服务器发出请求,因此不刷新页面,并且会触发hashChange事件,通过监听hash值的改变实现更新页面部分内容的操作。
    
  • HistorRouter原理

    主要使用html5的pushState()和replaceState()两个api结合window.popstate事件(监听浏览器前进后退)来实现。pushState可以改变url地址不会发送请求,replaceState可以读取历史记录栈,可以对浏览器记录进行修改。
    
  • 区别

    1、pushState设置新url可以与当前url一样,也会添加到记录栈,而hash设置的新值必须与原来的不一样才会添加到记录栈。
    2、pushState通过stateObject可添加任意类型的数据到记录中,而hash仅可以添加短字符串。
    3、pushState可额外设置title属性供后续使用。
    4、hash兼容IE8以上,history兼容IE10以上。
    5、history模式需要后端配合将所有访问指向index.html,否则用户刷新页面,会导致404错误。
    
// hash 路由原理
// 监听hashChange方法
window.addEventListener("hashChange",()=>{
   div.innerHTML = location.hash.slice(1)
})
// history 路由原理
// 利用html5的history的pushState方法结合window.popstate事件(监听浏览器前进后退)
function routerChange(pathName){
   history.pushState(null, null, pathName)
   div.innerHTML = location.pathname
}
window.addEventListener("popstate", ()=>{
   div.innerHTML = location.pathname
})

vue函数生命周期

  • beforeCreate

    vue对象属性未绑定,如data属性,computed属性。
    
  • 挂载数据(属性赋值)

    包括data属性与computed的运算。
    
  • create函数

    vue对象属性已绑定,DOM未生成,$el属性未存在。
    
  • beforeMount函数

    模板编译(template)、数据挂载之前执行的函数。this.$el存在值,但数据未挂载到页面。
    
  • 模板编译

    使用vue对象的数据属性替换模板中页面内容。
    
  • mounted函数

    模板编译完成,数据挂载完毕。
    
  • beforeUpdated函数

    组件更新之前执行函数,数据更新后,调用beforeUpdated,注:更新数据需要是模板上出现的数据,否则不会触发。
    
  • updated函数

    组件更新之后执行函数,vue对象对应的dom的内部(innerHTML)改变。
    
  • activated函数(keep-alive组件激活时调用)

  • deactivated函数(keep-alive组件停用时调用)

  • beforeDestroy (组件销毁之前)

  • destroyed(组件销毁之后)

keep-alive组件(实现组件缓存,vue.js的内置组件)

  • 作用

    1、能够将不活跃的组件示例保存在内存中,而不是直接销毁;
    2、抽象组件,不会被渲染到真实dom中,也不会出现在父组件链。
    
  • 使用方法

    1、常用属性include/exclude,允许组件有条件的进行缓存;
    2、两个生命周期activated/ deactivated,判断组件是否处于活跃状态;
    3、运用LRU算法
    
  • 原理

    vue的缓存机制并不是直接存储dom结构,而是dom节点抽象成一个个VNode节点,因此keep-alive的缓存也是基于VNode节点的而不是直接存储dom结构。
    将需要缓存的VNode节点保存在this.cache中,在render时,如果VNode的name符合在缓存条件,则会从this.cache中取出之前缓存的VNode实例进行渲染。
    

vue中的data为何可以是函数

  JavaScript函数可以构成作用域,data是函数时,每个组件实例都有自己的作用域,每个实例相互独立,相互不会影响。

vue中$nextTick作用与原理

  作用:可以获取更新后的DOM
  由于vue DOM更新是异步执行,即修改数据,不会立即更新视图,而是监听数据变化,并缓存在同一事件中,等同一数据循环中的所有数据变化完成后,统一更新视图。确保获取更新后的DOM,因此设置了vue.nextTick().
  原理:在下次DOM更新循环结束之后执行延迟回调,nextTick使用宏任务和微任务。根据执行环境分别尝试采用Promise、mutationObserver、setImmediate(若以上均不行,则采用setTimeout。

vue首屏白屏解决

  1、路由懒加载
  2、vue-cli开启打包压缩与后退配合gzip访问;
  3、进行cdn加速;
  4、开启vue服务渲染模式;
  5、使用webpack的externals属性将不需要打包的库文件分离出去,减少打包后文件的大小;
  6、生产环境中删除不必要的console.log;
  7、添加loading效果,给予一种过渡效果。
// 添加删除 console.log
plugins:[
   new webpack.optimize.UglifyJsPlugin({
      compress:{
         warnings:false,
         drop_debugger:true,
         drop_console:true
      },
      sourceMap:true
   })
]

单页面优缺点

  优点:体验好,快,内容的改变不需要重新加载整个页面,对服务器压力较小;前后端分离;页面效果可以比较酷炫。
  缺点:不利于SEO;导航不可用,如果一定要导航需要自行实现前进、后退;初次加载耗时多;页面复杂度更高。

路由跳转与location.href区别

  location.href简单方便,刷新页面;
  路由跳转方式,无刷新页面,静态跳转。
<!-- 路由跳转 -->
<router-link :to="{name:'home'}">
<router-link :to="{path:'/home'}">

<!-- param参数 -->
<router-link :to="{name:'home', params:{id:0}}">
<router-link :to="{path:'/home:id', params:{id:0}}">

<!-- query参数 -->
<router-link :to="{name:'home', query:{id:0}}">
<router-link :to="{path:'/home', query:{id:0}}">
// 不带参数
this.$router.push("/home")
this.$router.push({name:"home"})
this.$router.push({path:"/home"})

// param参数 (name可用,path不可用)
this.$router.push({name:"home", params:{id:0}})
// 路由配置 path:"/home:id", 不配置path,刷新页面params参数消失

// query参数
this.$router.push({name:'home', query:{id:0}})
this.$router.push({path:'/home', query:{id:0}})

// this.$router.replace() 用法同push
// this.$router.go(n)  正数往前,负数往后

delete 与 vue.delete

  delete删除数组的值,依然会占用内存中位置;
  vue.delete已删除数组中的内存占位。
let arr = [1,2,3]
let arrV = [1,2,3]
delete arr[1]
this.$delete(arrV,2)
console.log(arr)    //【1, empty, 3】
console.log(arrV)    //【1,2】

vuex是什么,属性?

  • 关键:state、mutations、getters、actions、module、store.commit、store.dispatch
  • 解析:vuex集中管理项目的公共数据。
    1. state-存储公共管理的数据;
    2. mutations-定义改变state中数据的方法(不建议异步);
    3. getters-定义store的计算属性;
    4. getters的返回值根据所依赖的数据进行缓存,依赖值发生改变触发重新计算;
    5. action-提交mutation,而不是直接变更状态;
    6. module-将store分割成模块。
  • 注释:mutations:通过store.commit调用;action:通过store.dispatch触发;getters:通过store.getters调用。
import Vue from 'vue'
import Vuex from 'vuex'
// 安装插件
Vue.use(Vuex)
// 创建对象
const store = new Vuex.Store({
	state:{
		name:'xzp'
	},
	mutations:{
		updateState(state, payload){
			state.name = payload
		}
	},
	actions:{
		asyncUpdate(context, payload){
			return new Promise(()=>{
				setTimeout(()=>{
					context.commit('updateState')
				})
			})
		}
	},
	getters:{},
	modules:{}
})
// 暴露对象
export default store

Vue循环key

  • 关键:性能优化、diff算法节点比对
  • 解析:生成虚拟dom,更新dom时,使用diff算法对节点进行比对,举例:li元素需要插入li,若li是上没有key,将全部渲染一遍,若存在key,则比对li元素的key,创建新的li元素,插入,不对其他元素进行修改和渲染。存在问题:下标做key,可能会导致无效刷新,影响效率。操作数组靠前的元素,unshift元素。
  • diff算法:虚拟dom即以对象的形式来模拟dom的树形结构,若数据发生改变,生成新的虚拟dom,同层级比对虚拟dom,若存在不一致,则重新渲染对应真实dom以及该dom的子元素。两端比较,比较头尾的key是否相同,再决定新增或删除元素。

vue2.0双向绑定的原理与缺陷

  • 关键:Object.defineProperty、getter、setter
  • 解析
    1. 响应式:组件的data发生改变,立即触发视图更新
    2. 原理:Vue采用数据劫持结合发布者-订阅者模式来实现数据响应式,通过Object.defineProperty劫持数据的setter与getter,数据发生改变时,发布消息给订阅者,订阅者受到消息后进行相应的处理。通过原生js提供的监听数据的API,数据发生改变时,在回调函数中修改dom。
    3. 核心API:Object.defineProperty,定义对象属性;特点:默认情况下定义数据属性不能修改,描述属性与存取属性不能同时使用
    4. 响应式原理:获取属性值触发getter方法,设置属性值触发setter方法,在setter方法中调用修改dom的方法。
  • 注释:缺点
    1. 单次递归开销巨大,数据量过大,大量递归导致调用栈溢出
    2. 不能监听对象的新增属性和删除属性
    3. 无法正确监听数组的方法,不能通过监听数组下标来监听数据变化
vue.$set(data, key, value) // 新增属性
vue.$delete(data, key) // 删除属性

computed与watch

  • 关键:computed存在缓存、触发条件依赖值的改变、watch无缓存、支持异步、监听数据变化
  • 解析:computed缓存-多次使用到computed计算的属性,只执行一次,除非数据发生变化;不支持异步。
  • 解析:watch不支持缓存,数据变化,即触发相应的操作;支持异步监听;接收两个参数,第一个参数:新的值,第二个参数:变化之前的值;immediate:立即触发回调函数;deep:深度监听,数据内部变化,复杂数据类型中使用,例如数组中的对象发生改变(无法监听到数组和对象内部的变化)。

vue -> $nextTick作用与原理

  • 关键:异步渲染、获取dom、Promise
  • 注解:vue更新dom为异步行为,修改数据后,视图不会立马更新,而是等同一件事循环中所有数据变化完成后,统一更新视图。
  • nextTick作用:该方法会在当前渲染完成后执行,解决异步渲染获取不到更新后dom的问题。原理:本质是返回一个Promise,vue异步执行dom更新,数据改变,vue开启队列,同一个事件循环中观察到数据变化的watcher推送进队列。若watcher多次触发,仅会被推送到队列一次。这种缓冲行为可有限去掉重复数据改变造成的不必要计算和dom操作。

vue组件通信方式

  • 关键:父子通信、自定义属性、props、$emit、eventBus、$on、vuex。
  • 解析
    1. props/$emit(父子组件通信方式)
    2. ref/$refs
    this.$emit('xxx', 1,2,3);
    this.$refs.child.xzp();
    
    1. eventBus事件总线($emit/$on)
    // 入口文件
    export const EventBus = new Vue();
    // 发送
    EventBus.$emit("xxxzzzppp",{a:1})
    // 接收
    EventBus.$on("xxxzzzppp",(data)=>{
      console.log(data.a) // 1
    })
    
    1. 依赖注入(provide/inject)
    // 提供provide
    provide(){
      return {
        name:"xzp",
        age:"22"
      }
    }
    // 接收(后代组件)
    inject:["name", "age"]
    
    1. $parent/$children
    this.$parent.msg;
    this.$children[0].msg;
    
    1. $attrs/$listeners
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值