1、vue开发中常用的指令有哪些?

2、vuediff算法的原理

首先比较新旧节点的标签名,

3、vue mixin解决了什么问题,原理以及缺点?

export const counterMixin = {
	data(){
		return {
			count: 0;
		}
	},
	methods:{
		increment(){
			this.count++;
		},
		decrement(){
			this.count--;
		}
	}
}

然后,在需要使用计数器功能的组件中,我们可以通过mixins选项引入counterMixin

<template>
	<button @click="increment">Increment</button>
	<span>{{ count }}</span>
	<button @click="decrement">Decrement</button>
</template>
<script>
import {counterMixin} from "./counterMixin.js";

export default{
	mixins: [counterMixin]
}
</script>

这样组件ABC都可以共享计数器逻辑,如果需要修改计数器逻辑只需要修改counterMixin。

4、vue3有哪些改变?

5、说一下generator的原理

generator是es6引入的一种新的函数类型,它可以让函数在执行时暂停,后续又可在需要时恢复执行。generator是一种特殊的迭代器,后续有可在需要时恢复执行。generator是一种特殊的迭代器,用于生成一系列的值。generator的原理可以分为以下几个步骤:

function* generationFn(){
	yield "Iteration 1";
	yield "Iteration 2";
}
const iterator = generatorFn();

console.log(iterator)
console.log(iterator.next());

6. 谈谈你对vue的理解

vue.js是一个渐进式js框架,用于构建用户界面。简洁易学、易于上手。

7. 双向数据绑定的原理

vue的数据绑定机制的通过数据劫持和发布/订阅模式实现的。单数据发生变化,会自动更新视图,并通过虚拟DOM对比算法来提高性能。这个性能可以有效简化开发过程,提高代码的可维护性和可读性。

在vue中,每个组件实例都有一个对应的响应式数据对象。当数据发生变化时,会自动更行视图,这个西洋参数据对象通过数据劫持的方式实现。

8. 使用 Object.defineProperty() 跟Proxy进行数据劫持分别有什么缺点?

9. Computed 和 Watch 的区别

computed主要偏向于对计算的值进行缓存,提升性能
watch主要是对监听数据变化,对数据变化做出一个逻辑操作

10. Computed 和 Methods 的区别

computed计算属性是机遇他们的依赖进行缓存的,只有在它的相关依赖发生变化时,才会重新求值
method调用总是会执行该函数

11. slot是什么?有什么作用?原理是什么?

slot是插槽,是vue组件内部的模板引擎使用slot元素作为承载分发内容的出口。
原理:
当子组建vm实例化时,获取到父组件传入的slot标签的内容,存放在vm.$slot中,默认插槽为vm.$slot.default,具体插槽名为vm.$slot.xx。当组件执行渲染函数时,遇到slot标签,使用$slot中的内容进行替换,此时可以为插槽传递数据,若存放数据,则可以称插槽为作用域插槽。

<template>
<div>
	<ChildComponent>
		<template v-slot:header>
			<h2>hello</h2>
		</template>
	</ChildComponent>
</div>
</template>

<template>
<div>
	<slot name="header">
		
	</slot>
	<slot>
	</slot>
</div>
</template>

12. 说一下mvc、mvp以及mvvm的区别和使用场景

优点:MVC模式可以将要处理的数据、数据的呈现方式和用户交互分离出来,极大的降低了应用程序各个模块间的耦合度,提高了代码的可维护性以及可拓展性。MVC模式的每个部分各司其职,代码更加清晰。

缺点:MVC模式存在的问题在于视图和控制器之间的紧密耦合,是的一个部分的该表需要牵扯到其他部分的修改。

使用场景:简单的web程序

优点:MVP模式的presenter起到了连接视图层和模型层的桥梁,可以非常有效的降低视图和模型层之间的耦合度,使得代码跟容易拓展和维护。
缺点:mvp的缺点在于他的实现难度表较高,需要实现观察者模式并在交互的过程中处理复杂的事件流。
使用场景:大型的GUI应用程序

mvvm将视图层和模型层分离,引入viewmodel来管理ui控件,viewmodel是一种特殊的控制器,它将视图和模型紧密的连接在一起,viewmodel负责视图层的更新和绑定,处理用户事件并更新,从而实现数据流的双向绑定。
优点:mvvm模式的最大优点就是是现实双向绑定,并且可以将界面的数据与业务逻辑分离,有效解决了mvc和mvp的缺点。提高代码的可维护性和可测试性。
缺点:mvvm模式的最大缺点就是实现比较复杂,需要依赖处理数据的框架,需要额外的学习成本。
使用场景:web程序和大型单页应用程序。

在MVC中,控制器(Controller)负责从模型获取数据并更新视图。而在MVP中,Presenter从模型获取数据,并将数据传递给视图进行显示。

13. 如何保存页面的当前的状态

14. 常见的事件修饰符及其作用

15. v-if、v-show、v-html 的原理

16. v-model 是如何实现的,语法糖实际是什么?

v-model是vue常见的指令之一,用于双向绑定表单元素的值和数据对象的值。它的语法糖实际上是将v-bind和v-on指令结合在一起使用,简化了模板中数据绑定和事件绑定的书写方式。
例如:

<input v-model="message">

等价于

<input :value="message" @input="message = $event.target.value" >

这里的v-model相当于将属性绑定和事件绑定结合在一起,是的输入框的值随着数据对象属性的改变而改变,同时数据对象随着输入框的值的改变而改变。

17. v-model 可以被用在自定义组件上吗?如果可以,如何使用?

可以,

<template>
<div>
	<input :value="value" @input="updateValue($event.target.value)">
</div>
</template>
<script>
<export default{
	props: {
		value: ""
	},
	methods: {
		updateValue(value){
			this.$emit("input", value);
		}
	}
}
</script>

%% 子组件 %%

<template>
<div>
	<custom-input v-model="message"/>
</div>
</template>
<script>
import CustomInput from "./custominput.vue";

export default {
	components: {
		CustomInput
	},
	data(){
		return{
			message: ""
		}
	}
}
</script>

18. data为什么是一个函数而不是对象

js中的对象是引用类型的数据,当多个实力引用用同一个对象时,只要一个实例对这个对象进行操作,其他实例的数据也会发生变化。而在vue中,更多的是想要复用组件,那就需要每个组件都有自己的数据,这样组件之间才不会互相干扰。所以组件的数据不能写成对象的形式,而是要想要携程函数的形式。数据一函数放回值的形式返回,每次复用组件的时候,就会返回一个新的data,每个组件都有自己的私有数据控件。

19. $nextTick 原理及作用

20. Vue template 到 render 的过程

21. Vue data 中某一个属性的值发生改变后,视图会立即同步执行重新渲染吗?

不会立即同步执行重新渲染,vue实现响应式并不是数据发生变化后dom立即变化。而是按到策略去进行dom的更新。检测到数据变化,vue将开启一个队列,并缓冲在同一事件中循环中发的所有数据变更。

22. Vue 中给 data 中的对象属性添加一个新的属性时会发生什么?如何解决?

不会更新,因为在vue实例创建的时候,obj.b并没有声明,没有被vue转换为响应式属性,不会触发视图的更新,这时候需要使用xue全局的api $set():

addObjB(){
	this.$set(this.obj, "b", 'obj.b')
	console.log(this.obj)
}

$set()方法相当于手动的把obj.b处理成一个响应式属性,这时候视图也会跟着改变

23. 描述下Vue自定义指令

在vue2.0中,代码复用和抽象的主要形式是组件。然而,有的情况下,你仍然需要对普通DOM元素进行底层操作,这时候就会用到自定义指令。
一般需要对DOM元素进行底层操作使用,尽量只用操作DOM展示,不修改内部的值。当使用自定义指令直接修改value值时绑定v-model的值也不会同步更新;如必须修改可以在自定义指令中使用keydown事件,在vue组件中使用change事件,回调中修改vue数据。

24. 子组件可以直接改变父组件的数据吗?

不可以。引用$emit派发一个自定义事件,父组件接收后由父组件修改

25. Vue是如何收集依赖的?

vue.js通过响应式系统收集依赖。当数据发生变化时,vue.js能够自动更新相关的dom
在vue中,当一个组件的数据被访问时,vue会将这个数据用观察者记录下来,当这个数据发生变化时,vue就知道哪些组件需要重新渲染。vue利用了js的getter和setter来实现这个依赖追踪的过程。

26、对 React 和 Vue 的理解,它们的异同

27. Vue的优点

  1. 简单易学
  2. 轻量
  3. 数据双向绑定

28. assets和static的区别

29. delete和Vue.delete删除数组的区别

delete只是把删除的元素的值变成了empty/undefined,其他元素的键值还是不变的
vue.delete直接删除了数组,改变了键值

30. vue如何监听对象或者数组某个属性的变化

用$watch

// 监听对象属性的变化
var vm = new Vue({
  data: {
    obj: {
      name: 'Alice',
      age: 30
    }
  },
  created: function () {
    // 监听对象的name属性
    this.$watch('obj.name', function (newValue, oldValue) {
      console.log('obj.name changed from ' + oldValue + ' to ' + newValue);
    });
  }
});

// 修改对象属性的值
vm.obj.name = 'Bob'; // 控制台输出: "obj.name changed from Alice to Bob"

// 监听数组元素的变化
var vm2 = new Vue({
  data: {
    arr: [1, 2, 3]
  },
  created: function () {
    // 监听数组的第一个元素
    this.$watch('arr[0]', function (newValue, oldValue) {
      console.log('arr[0] changed from ' + oldValue + ' to ' + newValue);
    });
  }
});

// 修改数组元素的值
vm2.arr[0] = 4; // 控制台输出: "arr[0] changed from 1 to 4"

31. Vue模版编译原理

vue的模板template无法被浏览器解析并渲染,要将template转换为js函数。

这个过程为:

32. 对keep-alive的理解,它是如何实现的,具体缓存的是什么?

如果需要在组件切换时,保存一些组件的状态防止多次渲染,就可以使用keep-alive组件包裹需要保存的组件。

<keep-alive>是vue.js提供的一个抽象组件,用于在组件之间动态地保留组件的状态或避免重新渲染。
集体来说,keep-alive组件会缓存其内部的动态组件,而不会将他们销毁。这样当这些缓存的组件再次被切换到时,vue会直接从缓存中取出组件,而不是重新创建和渲染他们。这样可以显著提高应用的性能和用户体验,尤其是频繁切换组件时。

<template>
  <div>
    <button @click="toggleComponent">Toggle Component</button>
    <keep-alive>
      <component :is="currentComponent"></component>
    </keep-alive>
  </div>
</template>

<script>
export default {
  data() {
    return {
      currentComponent: 'ComponentA'
    };
  },
  methods: {
    toggleComponent() {
      this.currentComponent = this.currentComponent === 'ComponentA' ? 'ComponentB' : 'ComponentA';
    }
  },
  components: {
    ComponentA: {
      template: '<div>Component A</div>'
    },
    ComponentB: {
      template: '<div>Component B</div>'
    }
  }
};
</script>

在这个例子中,keep-alive组件会缓存componentA和componentB,当点击按键切换组件时,vue会根据需要从缓存中取出相应的组件,而不会重新创建和销毁他们。

33.Vue中封装的数组方法有哪些,其如何实现页面更新

封装的数组的方法:

具体来说,vue.js使用了一种叫做响应式系统的机制来实现页面更新,当你修改vue实例的数据时,vue会跟踪
这些数据的依赖关系,并且在数据发生变化时,自动更新相关的视图。

34.说一下Vue的生命周期

35.Vue 子组件和父组件执行顺序

加载渲染过程:

1.父组件 beforeCreate

2.父组件 created

3.父组件 beforeMount

4.子组件 beforeCreate

5.子组件 created

6.子组件 beforeMount

7.子组件 mounted

8.父组件 mounted

更新过程:

\1. 父组件 beforeUpdate

2.子组件 beforeUpdate

3.子组件 updated

4.父组件 updated

销毁过程:

1. 父组件 beforeDestroy

2.子组件 beforeDestroy

3.子组件 destroyed

4.父组件 destoryed

36.created和mounted的区别

37.一般在哪个生命周期请求异步数据

一般在created钩子函数调用异步请求,因为在created钩子函数中:

38.keep-alive 中的生命周期哪些

activated和deactivated

39.讲一下v-if和v-for的优先级

v-for具有更快的优先级,确保在循环中动态控制每个项的渲染,而不是整个循环块。

40.Vue-Router 的懒加载如何实现

非懒加载:

import List from "@/components/list.vue"
const router = new VueRouter({
	routes: [
		{
			path: "/list",
			component: List
		}
	]
})

方案一,使用箭头函数+import动态加载

const List = () => import("@/components/list.vue")
const router = new VueRouter({
	routes:[
	{
		path: "/list",
		component: List
	}]
})

方案二,使用剪头函数加require动态加载

const touter = new Router({
	routes:[
		{
			path: "/list",
			component: resolve => require(["@/components/list"], resolve)
		}
	]
})

方案三,使用webpack的require.ensure技术,实现按需加载

const List = r=> require.ensure([], ()=>r(require("@/components/list")), 'list');
const router = new Router({
	routes: [
		{
			path: "/list",
			component: List,
			name: 'list'
		
		}
	]
})

41.路由的hash和history模式的区别

42.如何获取页面的hash变化

watch:{
	$route: {
		handler: function(val, oldval){
		}
	},
	deep: true
}

43. $route 和$router 的区别

44.如何定义动态路由?如何获取传过来的动态参数?

// 配置路由
{
	path: "/user/:userid",
	component: User
}

// 使用
<router-link :to="'/user/'+userId" replace>用户
</router-link>

<router-link :to="{name: 'user', params: {name: wade}}"></router-link>

<script>
this.$router.push({name: "user", params: {name: wade}})
this.$router.push('/user/'+ wade)
</script>
<router-link :to="path: '/profile', query:{name: 'why'}">doc</router-link>
<script>
this.$router.push({
	path: "/profile",
	query: {
		name: "why"
	}
})
</script>

//使用

// 方法1:
<router-link :to="{ name: 'users', query: { uname: james }}">按钮</router-link>

// 方法2:
this.$router.push({ name: 'users', query:{ uname:james }})

// 方法3:
<router-link :to="{ path: '/user', query: { uname:james }}">按钮</router-link>

// 方法4:
this.$router.push({ path: '/user', query:{ uname:james }})
  
// 方法5:
this.$router.push('/user?uname=' + jsmes)

45.Vue-router 路由钩子在生命周期的体现

46.Vue-router跳转和location.href有什么区别

47.params和query的区别

48.Vue-router 导航守卫有哪些

49.Vuex 的原理

vuex是一个专门为vue.js开发的状态管理库,它提供了一个集中式的状态管理机制,用于管理vue应用中的所有组件的共享状态。vuex的核心思想是将组件的共享状态抽离出来,以单独的状态树的形式存储,然后通过定义一系列的mutations、actions、getters来操作的这个状态输。state是应用状态,mutations用于修改state中的状态,actions则用于处理异步操作或批量的同步操作,最终通过mutations来改变state。getters则用于state中的数据进行计算或过滤。

50.Vuex中action和mutation的区别

51.Vuex 和 localStorage 的区别

52.Redux 和 Vuex 有什么区别,它们的共同思想

区别

共同思想

53.为什么要用 Vuex 或者 Redux

54.Vuex有哪几种属性?

55.Vuex和单纯的全局对象有什么区别?

56.为什么 Vuex 的 mutation 中不能做异步操作?

vuex中所有的状态更新的唯一途径都是mutation,异步操作通过action来提交mutation实现,这样可以方便地跟踪每一个状态的变化,有利于我们调试和维护。

每个mutation执行完成后都会对应的一个新的状态变更,这样就可进行更好的进行状态追踪,如果是异步就没办法进行状态追踪。

57.Vuex的严格模式是什么,有什么作用,如何开启

在严格模式下,无论发生什么状态变更,并且不是由mutation函数引起的,就会抛出错误。保证所有状态都能被调试工具跟踪到。

58.如何在组件中批量使用Vuex的getter属性

使用mapGetters辅助函数,利用对象展开运算符将getter混入computed对象中。

import {mapGetters} from "vuex";

export default{
	computed: {
		...mapGetters(['total', 'discountTotal'])
	}
}

59.如何在组件中重复使用Vuex的mutation

使用mapMutations辅助函数,在组件中这么使用

import {mapMutations} from "vuex"
methods:{
	...mapMutations({
		setNumber: "SET_NUMBER"
	})
}

然后调用this.setNumber(10)相当调用this.$store.commit("SET_NUMBER", 10)

60.defineProperty和proxy的区别

vue 2.x中使用的是.defineProperty()

vue 3.x中引入proxy

61.Vue3.0 为什么要用 proxy

62.Vue 3.0 中的 Vue Composition API

vue2是基于options api风格的,通过填充option的data、methods、computed等属性来完成一个vue组件

<template>
	<button @click="increment">
	Count: {{count}}
	</button>
</template>
<script>
import {ref, computed, onMounted} from "vue"

export default{
	setup(){
		const count = ref(0);
		function increment(){
			count.value++;
		}
		onMounted(()=>console.log("component moundted"))
		return {
			count,
			increment
		}
	}

}
</script>

63.Composition API与React Hook很像,区别是什么

64.vue和react的区别

65.对虚拟DOM的理解?

从本质上说虚拟DOM是一个js对象,通过对象的方式表示DOM结构,配合不同的渲染工具,使得跨平台渲染成为可能,将多次DOM修改的结果一次性的更新到页面上,从而有效的减少页面渲染的次数,减少修改DOM的重绘重排次数,提高渲染难性能。

66.虚拟DOM的解析过程

67.为什么要用虚拟DOM

68.虚拟DOM真的比真实DOM性能好吗

一般是

69.Vue Router history 模式为什么刷新出现404

因为浏览器在刷新页面回向服务器发送get请求,但是服务器并没有相应的资源来匹配这个请求,因为在history模式下,所有路由都是在前端路由实现的,并没有对应的后端资源

可以在服务器进行配置,让所有路由都指向同一个入口文件
nginx

server{
	listen 80;
	server_name yourdomain.com;

	location / {
		root /usr/share/nginx/html;
		index index.html;
		try_files $uri $uri/ /index.html;
	}
}

70.Vue Router history 模式上线需要注意什么事项

71.用vue-router hash模式实现锚点

const router = new VueRouter({
	mode: "hash",
	routes:[
		// ...
	]
})

this.$router.push({path: "/yourpath#youranchor"})

mounted(){
	const anchor = document.getElementById("youranchor")
	if(anchor){
		anchor.scrollIntoView()
	}
}

72.说下虚拟DOM和diff算法,key的作用

虚拟DOM是指js对象模拟的DOM树结构,包括节点的类型、属性和子节点等信息。当状态发生变化时,vue、react会使用新的状态生成一个新的虚拟DOM树,并通过对比新旧虚拟DOM树的差异,计算出需要更新的节点,最终只更新需要更新的节点,从而提高性能。

diff算法找出二者的差异,key的作用是给每个虚拟DOM节点添加一个唯一的标识符,可以通过key值快速对比是否是同一个节点,避免不必要的DOM操作。

73.vue2和vue3有哪些区别?

74.vue项目中style样式中为什么要添加 scoped

限定范围,防止污染其他组件的样式

75.mounted生命周期和keep-alive中activated的优先级

mounted生命周期高于activated

76.Vue 3.0 使用的 diff 算法相比 Vue 2.0 中的双端比对有以下优势

77.vue 父子组件传值有哪些方式

父到子

78.Vue2.x 和 Vue3 响应式上的区别?Vue 数据绑定是怎么实现的

79.详解函数式组件

如果一个组件无状态,没有实例,没有this上下文,那么他就是一个函数式组件。在性能有一定的优势。

81.详解 Vue template 模板编译

vue的模板编译是将vue的模板代码转化为可执行的js代码的过程。vue模板在运行前会被编译成渲染函数,避免了每次渲染时重新解析模板的消耗。渲染函数具有高效执行速度,从而减少了每次更新时的性能消耗。有点

82.详解虚拟 DOM 与 Vue DIFF 算法原理