vue基础知识点

一、Vue知识点

1、基本使用
1.1 数据驱动

​ 理念:当数据发生变化的时候,用户界面也会跟随变化,不用去手动修改dom

1.2 MVVM框架

​ MVVM框架主要包括:是一个架构设计模式,由Model、View、ViewModel三部分组成

​ Model:数据部分

​ View:视图部分

​ ViewModel:中间桥梁,连接View和Model(vue的实例)

​ 作用:实现了数据与视图的分离功能,当数据Model发生改变,ViewModel会监听到变化并通知View也做出改变,当View视图的事件触发,ViewModel也能事件,让Model做出响应。

难点:MVVM的三要素——响应式、模板、渲染

2、模板语法
2.1 Class与Style动态绑定

Class:

Class对象语法
<div :class="{active: true}"></div>	拥有active这个类名
<div :class="{active: isActive===0}"></div> 
后面的判断为true就拥有active类名
Class 数组语法
<div :class="[active?activeClass:'']"></div>
active为true就拥有activeClass类名,否则为空

Style:

Style对象语法
<div :style="{fontsize: ph+'px'}"></div>
<div :style="{color: active===item?'red':'pink'}"></div>
Style数组语法
<div :style="[styleColor,styleSize]"></div>
data() {
	styleColor: {
		color: 'red'		
	},
	styleSize: {
		font-size: '16px'
	}
}

​ Style 对象语法::style="{ color: 'red', fontsize: ph + 'px' }"

​ 变化: :class="{ color: select===item?'red':'pink'}" 判断select是否等于item,正red假pink

3、条件渲染v-if与v-show

v-if是真正的条件渲染,控制元素是否存在,如果为false,则元素是不存在的。

v-show是通过css属性display来控制显示与隐藏。

如果需要频繁控制元素显示与隐藏,使用v-show避免大量DOM操作,提高性能;某元素满足条件,变化比较少使用v-if。

4、计算属性computed

computed是一个对象,里面可以定义函数,但这个函数可以当作属性来直接使用。

优点:避免模板中出现过多的逻辑;具有缓存功能,不像methods每一次都会执行,他会调用缓存的数据,计算属性所依赖的数据发生变化,才会重新取值。

<div>{{fullName}}</div>
computed: {
	fullName() {
		return this.firstname+this.lastname
	}
}
5、侦听器watch

侦听数据发生变化,如果数据发生变化,就执行相应的操作。允许在watch中处理异步操作

处理场景:异步操作或者开销较大的操作,可以开启深度监听,监听对象的属性,deep:true,但是不能获取到old value

watch与computed差异

  1. watch:适合一个值发生变化,对应要做一些其他事情,处理异步操作,一个值影响多个值

    computed:由其依赖的值而来,依赖值发生变化,对应的也发生变化,适合多个值影响一个值

  2. computed计算属性有缓存功能,能使用计算属性尽量使用这个

  3. watch适合异步操作或者开销比较大的操作

watch: {
	users: {
//立即执行, 如果没有这个第一次渲染的时候不会执行,添加的话初始化也会执行侦听器
		immediate: true,
		handler(newValue, oldValue) {
			this.totalcount = newValue.length + '人数'
		}
	}
}
watch: {	
// watch监听uname的变化,同时也改变了message的值,也可以发送其他的异步请求
	uname(value) {
		this.checkUserName(value)
		this.message='在异步请求中'	// 做了一些其他的异步操作
	}
}
computed: {
	fullName() {
		return this.firstname+this.lastname	// 2个值去得到1个值	一定要return
	}
}
5.1、事件及参数
5.1.1、event参数

event是原生的、事件被挂载到当前元素

<button @click="add">+1</button>
<button @click="down(2, $event)">+2</button>
add(event){
	console.log(event)// 不传参、输出原生event
}
down(val, event){	// 需要定义形参来接收
	console.log(event) // 传参输出event
}
6、生命周期
6.1 三大阶段
  1. 挂载阶段(初始化相关属性,watch、methods):beforeCreate、created、beforeMount、mounted
  2. 更新阶段(元素或组件的变更操作):beforeUpdate、updated
  3. 销毁阶段(销毁相关属性):beforeDestroy、destroyed
beforeCreate():创建前,组件实例还没有创建
created():创建后,组件初始化完成,各种数据可以使用,可以使用ajax发送异步请求获取数据
beforeMount():挂载前,未执行渲染,更新,虚拟DOM完成,真实DOM未创建
mounted():挂载后,真实DOM创建完毕,可以访问dom元素发送异步请求获取数据
beforeUpdate():更新前,用于获取更新前各种数据状态
updated():更新后,所有数据完成更新
beforeDestroy():销毁前,用于处理一些定时器的清除
destroyed():销毁后,子实例被销毁,所有事件监听移除
7、组件化开发
7.1、组件描述

将一个页面拆分成多个组件,每一个组件都具有不同的功能。

特点:可复用性,可维护,可组合

7.2、基本使用
Vue.component('componentActive', {template: "<p>我的世界</p>"})
// 在调用时候,遇到驼峰命名的需要使用-来进行拼接
<component-active></component-active>
8、插槽的使用
8.1、基本插槽

在页面中使用组件,组件中是不能存在内容的,如果存在着即为插槽的内容

<div id="app">
    <alert-box>我插入在slot位置</alert-box>
</div>
Vue.component("alert-box", {
    template: `
		<div>
			<h1>我的世界</h1>
			<slot>默认内容</slot>	// 上面的组件使用若没有内容则使用默认内容
		</div>
	`
})

将子组件标签之内的内容传到对应的slot,然后把整体的子组件传过来

8.2、具名插槽

会查找对应name的插槽填充内容,没有name就不填充

<div slot="header">我的插入slot位置</div> <slot name="header">插槽</slot>

注意:我们给template标签添加插槽名称,在其标签中嵌入多个其他标签,从而完成布局

<template slot="header">	
<div>我是插入的内容一</div>
<div>我是插入的内容二</div>
</template>
8.3、作用域插槽

将子组件的数据暴露出去,为父组件根据数据指定不同的模板,更加灵活

render 渲染函数

Vue.set .set

Vue.delete .delete

$on $emit

$once $off

r e f s v m . refs vm. refsvm.refs ref

带参数的过滤器 祁东县

混入mixin

二、Vue-Router基础
1、路由简介
  1. 后端路由
    • 概念:根据不同用户URL请求,返回不同的内容
    • 本质:URL请求地址与服务器资源之间的对应关系
  2. SPA
    • Ajax前端渲染,前端渲染提高性能
    • SPA单页面应用程序,整个网页只有一个页面,通过AJAx实现局部更新
    • 核心技术点:前端路由
    • 原理之一:基于URL地址的hash
  3. 前端路由
    • 概念:根据不同的触发用户事件,显示不同的内容
    • 本质:用户事件与事件处理函数之间的对应关系
2、编程式导航
  • 声明式导航:通过点击链接实现导航的方式,

  • 编程式导航:通过调用API实现,this.$router.push('/login')

    // 字符串(路径名称)router.push('/home')router.push({ path: '/home' })	
    // 对象router.push({ name: '/user', params: {userId: 123}})
    // 命名的路由(传递参数)router.push({path: '/register', query:{uname: 'lisi'}})
    // 带参数查询 /register?uname=lisi
    
3、路由守卫
1、全局前置守卫

​ router.beforeEach((to, from, next) => {})

​ to:去哪个页面 from:来自哪个页面 next:继续执行

router.beforeEach
((to,from,next) => 
{if(to.path == '/login' || to.path == '/register') 
{next()}
else {alert('请先登录,未登录')    next('/login')}})

​ 全局后置守卫(一般不提这个,全局守卫指前置)

​ router.afterEach((to,from) => {})

全局后置守卫不会接受next函数,也不会改变导航本身

2、独享守卫

​ beforeEnter(to, from, next) {} 只对添加的该路由起作用

const router = new VueRouter({    routes: [{        path: '/foo',        component: Foo,        beforeEnter: (to, from, next) => {            if(window.isLogin) {                next()            } else {                next('/login?redirect=' + to.fullPath )            }        }    }]})
3、组件内的守卫
//beforeRouteEnter	在渲染组件前调用,不能获取this,组件实例未被挂载
beforeRouteEnter(to, from, next) {if(window.isLogin) {next()}else {next('/login?redirect=' + to.fullPath)}}
// beforeRouteUpdata  在当前路由改变,但当前组件被复用时调用,可访问实例
thisbeforeRouteUpdate(to, from, next) {next()}
// beforeRouteLeave   离开组件对应的路由,被调用
beforeRouteLeave(to, from, next) {next()}
4、动态添加路由

语法:this.$router.addRoutes([])

5、路由组件缓存——keep-alive
<keep-alive include="goods"> 
// 只对goods这个组件起路由缓存作用,需要在组件添加name属性,这样找到更快    
<router-view></router-view></keep-alive>
// keep-alive有2个钩子函数,activated, deactivated从其他页面进入keep-alive的缓存页面,会触发activated钩子函数,
//可以进行更新操作从缓存页面离开,会触发deactivated在缓存页面时候,点击刷新会触发:created -- mounted -- activated
6、Hash模式与History模式
  • 前端路由中,路径发生变‘化是不会向服务器发生请求的,只有用到ajax才会向服务器发送请求

  • Hash模式

    https://www.baidu.com/#/showlist?id=123

    hash模式中路径带有#,#后面的内容作为路由地址,可以通过?携带参数

  • History模式

    https://www.baidu.com/showlist/123

    history模式是 一个正常的路径模式,需要服务端相应支持

  • Hash与History区别

    Hash模式:基于锚点,以及onhashchange事件,通过锚点的值作为路由地址,地址发生变化触发onhashchange事件

    History模式:基于HTML5中的History API,history.pushState()与history.replaceState()

7、History模式的使用
const router = new VueRouter({mode: "history",
// 默认使用hash    
routes: [{path: '/login', component: Login}]})
8、Nginx服务器
  1. 代理服务器:局域网内部的机器通过代理服务器发送请求到互联网上的服务器。
  2. 反向代理服务器:在服务器端接收到客服端的请求,然后把请求分发给各个具体 的服务器进行处理,然后再讲结果反馈给客户端。
  3. 当单击浏览器中的刷新按钮后,会向服务器发送请求,服务器接收请求后,发现没有找到访问的文件,由于配置了一些 try_files ,所有会将html目录下面的index.html页面的内容返回给浏览器,浏览器根据路由来处理,查找相对于组件进行渲染。

三、Vue-Router原理

1、分析Hash与History工作原理
  • Hash:URL中#后面作为路径地址,当地址改变并不会向服务器发送请求,而是触发hashchange事件,记录下当前路由地址,根据当前路由地址找到对应组件,重新渲染
  • History:通过history.pushState()方法改变地址栏,并且当前地址记录到浏览器历史记录中,并不会向服务器发送请求,监听popstate事件,发现浏览器历史操作的变化,记录改变后的地址,根据路由地址找到对应组件渲染。

模式基本类似:将window.location.hash()直接进行赋值window.location.replate()改为调用了window.location.history.pushState()和window.location.replateState()方法,而History中添加对修改浏览器地址栏的监听popstate是在构造函数进行的。

2、路由配置(动态路由、懒加载)
routes: [	{path: '/user/:id', components: User, redirect: '/index'},	{path: '/feedback', component: () => import('../components/Feedback')}]

四、Vue响应式原理

1、数据驱动

MVVM

2、响应式的核心原理
Vue2.x

监听对象,监听数组、复杂对象,深度监听、缺点

缺点:1:深度监听,需要递归到底,一次性计算量大

​ 2:无法监听新增属性/删除属性(Vue.set/Vue.delete API去做事)

​ 3:无法原生监听数组,需要特殊处理

  1. defineProperty

    // Vue2.x是通过Object.defineProperty数据劫持来改变	单个属性let data={ msg: 'hello' }	// data数据let vm={}	// vue实例// 数据劫持Object.defineProperty(vm,'msg',{    enumerable: true,    configurable: true,    get(){	// 获取        return data.msg    },    set(newValue){        if(newValue===data.msg){            return        }        data.msg=newValue        document.querySelector('#app').textContent=data.msg    }})vm.msg='abc'console.log(vm.msg)
    
  2. defineProperty 监听的是对象中的属性

    let data={msg: 'hello', count: 10}	// (多个属性)let vm={}	// 实例proxyData(data)		// 调用function.proxyData(data) {    Object.keys(data).forEach(key => {	// Object.keys()将对象转为数组,进行循环遍历        Object.defineProperty(vm, key, {            enumerable: true,            configurable: true,            get() {                console.log('get', key, data[key])	// 读取数据方式不一样                return data[key]            },            set(newValue) {                console.log('set', key, newValue)                if(newValue===data[key]) {					return                 }                data[key] = newValue                document.querySelect('#app').textContent=data[key]            }        })    })}vm.msg='hello word' // 先触发setconsole.log(vm.msg)	// 后触发get
    
Vue3.x
// Vue3.x是通过Proxylet data = {    msg: 'hello',    count: 0}let vm = new Proxy(data, {    get(target, key) {        console.log('get key', key, target[key])        return target[key]    }    set(target, key, newValye) {    console.log('set key', key, newValue)    if(target[key] === newValue) {        return    }    target[key]=newValue    document.querySelector('#app').textContent = target[key]	}})vm.msg = 'abc'console.log(vm.msg)
3、发布订阅者模式
// 订阅者、发布者、信号中心let eventHub = new Vue()addTodo:function() {    eventHub.$emit('add-todo')	// 发布}create:function() {    eventHub.$on('add-todo',)	// 订阅}
4、组件化
5、vdom和diff
  • vdom-用 js 模拟DOM结构,计算出最小变量,操作DOM
  • diff算法是vdom的最核心、最关键的部分
  • diff算法能在日常使用,比如key

6、模板编译

7、渲染过程

8、前端路由

五、vue面试基础知识

1、computed和watch
  • computed有缓存,所依赖的data没有发生变化,不会重新计算
  • watch监听引用类型(对象),获取不到oldValue,已经指向newValue
  • watch第一次加载不会更新,需要设置属性 immediate:true
2、v-for
  • v-for与v-if不能一起使用,v-for的优先级高于v-if,会先执行循环才会去判断,不合理

    <li v-if="flag" v-for="item in lists" :keys="lists.id"></li>

3、父子组件通信-兄弟组件通信

父子通信:props– e m i t 调 用 父 组 件 ‘ t h i s . emit 调用父组件`this. emitthis.emit`

兄弟通信: o n 定 义 / on定义/ on/emit调用 定义 event.$on('onAdd', this.addtitle)

​ 调用 event.$emit('onAdd', this.title) addtitle(title){}

​ 在beforeDestroy里及时销毁自定义事件 event.$off('onAdd',this.addtitle)

// event 是一个new Vue实例import Vue from 'vue'export defalute new Vue{}import event from './event' // 引入
4、声明周期
5、$nextTick Vue是异步渲染

Vue是异步渲染的,data改变之后,DOM节点不会立刻去渲染,$nextTick会在DOM渲染之后触发,以获取最新的DOM节点

addItem(){    this.list.push(data.name)    thislist.push(data.name)	// const ulElem = this.$refs.ul1    // console.log(ulElem.childNodes.length)    // Vue是异步渲染的,data发生变化,DOM不会立刻渲染,需要使用$nextTick(),它会等DOM渲染完成再进行回调    this.$nextTick(() => {        const ulElem = this.$refs.ul1    	console.log(ulElem.childNodes.length)    })}

2、页面渲染的时候会将data做一些整合处理,将多出的data修改进行一次渲染

6、自定义v-model数据双向绑定

v-model本质是一个v-bind和v-on语法糖,value+input方法的语法糖,通过model属性的 props+event属性来进行自定义的

<input 	type="text" 		:value="text1" 		@input="$emit('change1', $event.target.value)">export default{	model: {        props: 'text1',        event: 'change1'    },        props: {            text1: String,            default() {return ''}        }}
7、slot
  • 基本使用 :

    父组件使用子组件,子组件标签之中通常不给内容,给的话会代替子组件里面的slot标签内容,不给就会默认使用子组件slot标签内容

    // father.vue<son> {{user.name}} </son>// son.vue<template>    <a>    	<slot>默认内容</slot>    </a></template>
    
  • 作用域插槽:

    作用域插槽:父组件可以使用子组件中定义的data数据,通过在子组件中v-bind定义数据,在父组件中v-slot定义使用名称接收,引用时:slotFather.slotname.name

    // father.vue<son>  <template v-slot="slotFather">  	{{slotFather.slotname.name}}// jack  </template></son>// son.vue<template>    <a>    	<slot :slotname="user">默认内容</slot>    </a></template>data(){    return{        user:{name: 'jack', age: 18}    }}
    
  • 具名插槽:

    具名一样的才会互相插槽

8、动态组件(少)

:is="val.type":用来渲染动态组件

<div v-for="(val,key) in list">	<component :is="val.type"></div>data(){    return{    	list:{1:{type:'xx'}, 2:{type:'jj'}}    }}
9、异步组件(多) 我感觉是懒加载指的路由
  • import()函数

  • 按需加载,异步加载大组件 什么时候用什么时候加载

// 正常引入import NextTick from './NextTick.vue'// 正常组件引入components: {    NextTick, slotDemo}// 使用import引入NextTick: () => import('../NectTick.vue')
10、keep-alive
  • 缓存组件(商品详情页、商品列表页)(tab切换可以使用keep-alive )
  • 频繁切换,不需要重复渲染(频繁切换会渲染销毁,浪费资源),可以使用keep-alive包裹
  • Vue性能优化
11、mixin
  • 多个组件有相同的逻辑,抽离出来
  • mixin并不是完美的解决方法,存在问题
    • 变量来源不明确,不利于阅读
    • 命名容易重复冲突
Vue通信方式
  • props/$emit

    父组件A通过props方式向子组件B传值,B通过$emit方式向A传值

  • e m i t / emit/ emit/on

    触发事件、监听事件

    var Event = new Vue()Event.$emit(事件名, 数据)Event.$on(事件名, data => {})
    
  • Vuex

    是vue的状态管理器,存储的数据是响应式的,并不会保存,需要与localStorage配合

  • a t t r s / attrs/ attrs/listenners

    多级组件嵌套传递数据通常使用vuex,但是仅仅传递数据,不做中间处理,vuex有点大材小用,可以使用——$attrs/$listeners

    a t t r s : 包 含 父 作 用 域 中 不 被 p r o p 所 识 别 的 特 性 绑 定 , 通 过 v − b i n d = “ attrs:包含父作用域中不被prop所识别的特性绑定,通过v-bind=“ attrspropvbind=attrs”传入内部组件

    l i s t e n e r s : 包 含 了 父 作 用 域 中 的 v − o n 事 件 监 听 器 , 通 过 v − o n = “ listeners:包含了父作用域中的v-on 事件监听器,通过v-on=“ listenersvonvon=listeners”

  • provide/inject

    祖先组件通过provide来提供变量,子组件通过inject来注入变量,provide/inject主要解决了跨域组件间的通信问题

    A.vue通过provide:name,将name变量提供给它的所有子组件,B.vue通过inject注入name变量,就可以通过this.name访问变量,但是并不是响应的,A.vue中的值改变,B中的不会变化

  • p a r e n t / parent/ parent/children与ref

    ref: 如果在普通的DOM元素上使用,引用指向就是DOM元素,在子组件上引用就是指向组件实例

    $parent / $children:访问父子实例

    无法跨级或在兄弟间

一、微信小程序
1、基础语法使用
  1. 在data中声明之后,页面中使用都需要{{}} mastauch语法,与vue不同,:src=“data” sec="{{data}}"

路由原理

路由怎么去设置的

子路由、路由懒加载 路由守卫

路由模式怎么设定的

哈希模式和history 的区别

什么时候用哈希什么时候用history

computed和watch 的区别

es6语法:update: function() {} === update() { }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值