vue面试题

复盘vue常见面试题。

1、vue和react、angular的相同点和不同点

React 和 Vue 相同点:
1、使用 Virtual DOM;
2、提供了响应式 (Reactive) 和组件化 (Composable) 的视图组件;
3、将注意力集中保持在核心库,而将其他功能如路由和全局状态管理交给相关的库;

React 和 Vue 不同点:
1、性能
vue和React的性能都非常高。优化:
在 React 应用中,当某个组件的状态发生变化时,它会以该组件为根,重新渲染整个组件子树。如要避免不必要的子组件的重渲染,你需要手动实现;在 Vue 应用中,组件的依赖是在渲染过程中自动追踪的,所以系统能精确知晓哪个组件确实需要被重渲染,开发者不需要考虑组件是否需要重新渲染之类的优化。
2、HTML & CSS
React使用的JSX语法,将HTML、CSS和JS混写;而Vue使用的是templates模板方式,完全融合于经典的Web技术。
3、组件作用域内的 CSS
CSS 作用域在 React 中是通过 CSS-in-JS 的方案实现的 (比如 styled-components、glamorous 和 emotion);在Vue中是通过给style标签加scoped标记实现的。
4、规模
Vue 的路由库和状态管理库都是由官方维护支持且与核心库同步更新的。React 则是选择把这些问题交给社区维护,因此创建了一个更分散的生态系统。但相对的,React 的生态系统相比 Vue 更加繁荣。
5、原生渲染
React Native 能使你用相同的组件模型编写有本地渲染能力的 APP (iOS 和 Android)。能同时跨多平台开发,对开发者是非常棒的。

Angular与Vue的相同点:
Vue 的一些语法和 AngularJS 的很相似 (例如 v-if vs ng-if)。因为 AngularJS 是 Vue 早期开发的灵感来源。

AngularJS和Vue不同点:
1、复杂性:在 API 与设计两方面上 Vue.js 都比 AngularJS 简单得多。
2、灵活性:Vue.js 是一个更加灵活开放的解决方案。
3、数据绑定:AngularJS 使用双向绑定,Vue 在不同组件间强制使用单向数据流。这使应用中的数据流更加清晰易懂。
4、指令和组件:在 Vue 中指令和组件分得更清晰。指令只封装 DOM 操作,而组件代表一个自给自足的独立单元——有自己的视图和数据逻辑。在 AngularJS 中,每件事都由指令来做,而组件只是一种特殊的指令。
5、运行时性能:Vue 有更好的性能,并且非常非常容易优化,因为它不使用脏检查。在 AngularJS 中,当 watcher 越来越多时会变得越来越慢,因为作用域内的每一次变化,所有 watcher 都要重新计算。并且,如果一些 watcher 触发另一个更新,脏检查循环 (digest cycle) 可能要运行多次。

Angular和Vue的不同点
1、Angular事实上必须用TypeScript来开发,而且Angular对于TS的支持非常全面,而Vue暂时对于TS的支持还在改进阶段。
2、Vue的体积更小,一个包含了 Vuex + Vue Router 的 Vue 项目 (gzip 之后 30kB) 相比使用了这些优化的 angular-cli 生成的默认项目尺寸 (~65KB) 还是要小得多。
3、灵活性:vue更灵活。
4、学习曲线:angular学习曲线很陡峭,它的设计目标就是只针对大型的复杂应用。

2、对于MVVM的理解

MVVM是Model-View-Viewmodel的缩写。其中:
Model代表数据模型,数据和业务逻辑都在Model层定义。
View代表UI视图,负责数据的展示。
ViewModel负责监听Model层中数据的变化,并且控制视图的更新,处理用户交互操作。
在MVVM框架中,Model和View并无直接的联系,而是通过ViewModel进行关联的,Model和ViewModel具有双向数据绑定的联系,因此Model中数据发生变化会触发View层的刷新,View中由于用户交互操作改变的数据也会同步到Model中。
这种模式实现了Model和View的数据自动同步,开发者只需要关注业务逻辑,不需要手动操作DOM。

3、v-if和v-show指令有什么区别

v-if控制DOM节点存在与否,即元素的重建和销毁。v-show是通过CSS的display:none/block来控制元素显示与否。当我们需要频繁切换元素的显示和隐藏时,使用v-show可以节省性能上的开销。当只需要一次显示和隐藏,则使用v-if更合理。

4、vue常用的事件修饰符

阻止单击事件冒泡:<a v-on:click.stop="doThis"></a>
阻止默认事件:<form v-on:submit.prevent="onSubmit"></form>
当event.target是当前元素自身时触发,即事件不是从内部元素触发:<div v-on:click.self="doThat">...</div>
添加事件监听器时使用事件捕获模式,即元素自身触发的事件先在此处理,然后才交由内部元素进行处理:

<div v-on:click.capture="doThis">...</div>

点击事件将只会触发一次:<a v-on:click.once="doThis"></a>
滚动事件的默认行为 (即滚动行为) 将会立即触发,而不会等待 onScroll 完成,.passive 会告诉浏览器你不想阻止事件的默认行为,不要把 .passive 和 .prevent 一起使用,因为 .prevent 将会被忽略:<div v-on:scroll.passive="onScroll">...</div>

5、vue组件间的参数传递/通信

父组件传给子组件:子组件通过props方法接受数据;
子组件传给父组件:$emit方法传递参数
例子:
作者:李小白1
来源:优快云
原文:https://blog.youkuaiyun.com/qq449736038/article/details/80898496
5.1、父组件与子组件间的传值

父组件:

 <template>
      <div class="hello">
        <h1 @click="changeMsg">click send message to child by props</h1>    //点击事件触发修改msg值,即可修改子组件的值
        <h2>props demo</h2>
        <children @receiveMsg="receive" :childMsg="msg"></children>    //使用:childMsg="msg"将子组件的变量与父组件的msg绑定起来,@receiveMsg作为子组件给父组件传值emit时的关键字
      </div>
    </template>
    <script type="es6">
    import Children from '@/components/Children'    //引入子组件
    export default {
      name: 'Parent',
      data () {
        return {
          msg: 'hello boy'
        }
      },
      components: {children: Children},    //注册子组件
      methods: {
        changeMsg () {
          this.msg = 'hello girl'
        },
        receive (data) {    //通过触发@receiveMsg事件而调用的函数
          console.log(data)
        }
      }
    }
    </script>

子组件:

<template>
  <div class="hello" style="border:1px solid #666">
    <h1>children component</h1>
    <h1>there is children component,receive message :{{childMsg}}</h1>    //此处使用props变量
    <h2 @click="send">click here send msg to parent</h2>
  </div>
</template>
<script>
export default {
  name: 'children',
  props: ['childMsg'],    //这里定义好变量
  data () {
    return {
      msg: 'child'
    }
  },
  methods: {
    send () {
      this.$emit('receiveMsg', 'from child')    //给父组件发送事件
    }
  }
}
</script>

5.2、非父子组件传值
简单的应用场景下,可以使用一个空的Vue实例作为中央事件总线,即创建一个事件中心,相当于中转站,可以用它来传递事件和接收事件。
main.js

import Vue from 'vue'
import App from './App'
import router from './router'

Vue.config.productionTip = false
Vue.prototype.bus = new Vue()    //此处全局注册一个Vue作为事件中心
/* eslint-disable no-new */
new Vue({
  el: '#app',
  router,
  components: { App },
  template: '<App/>'
})

Brother1.vue

<template>
  <div class="hello" style="border:1px solid #666">
    <h1>Brother1 component</h1>
    <h2 @click="send">click send onb2</h2>
  </div>
</template>
<script>
export default {
  name: 'Brother1',
  data () {
    return {
      msg: 'Brother1'
    }
  },
  methods: {
    send () {
      this.bus.$emit('onb2', 'from brother1') // 触发Brother2.vue监听的onb2事件
    }
  },
  created () {
    this.bus.$on('onb1', (param) => { // 创建时,进行事件onb1监听
      console.log('receive onb1', param)
    })
  },
  beforeDestroy () {
    this.bus.$off('onb1') // 销毁时,事件onb1监听取消
    console.log('onb1 listener was closed')
  }
}
</script>

Brother2.vue

<template>
  <div class="hello" style="border:1px solid #666">
    <h1>Brother2 component</h1>
    <h2 @click="send">click send onb1</h2>
  </div>
</template>
<script>
export default {
  name: 'Brother2',
  data () {
    return {
      msg: 'Brother2'
    }
  },
  methods: {
    send () {
      this.bus.$emit('onb1', 'from brother2') // 触发Brother1.vue监听的onb1事件
    }
  },
  created () {
    this.bus.$on('onb2', (param) => { // 创建时,进行事件onb1监听
      console.log('receive onb2', param)
    })
  },
  beforeDestroy () {
    this.bus.$off('onb2') // 销毁时,事件onb2监听取消
    console.log('onb2 listener was closed')
  }
}
</script>

作者: 踩坑小王子
来源:优快云
原文: https://blog.youkuaiyun.com/Clark_Fitz817/article/details/79193771
官方推荐的eventbus 解决方案的缺陷在于, 在数据传递过程中,两个组件必须都已经被渲染过。
在复杂的情况下,可以考虑使用Vue 官方提供的状态管理模式——Vuex来进行管理。
store.js

//位于store.js 中
import Vue from 'vue'
import Vuex from 'vuex'
 
Vue.use(Vuex);
 
export default new Vuex.Store({
    /*
    * state指的就是储存的数据,
    * 下面的数据是我在项目中需要用的数据字段
    * */
  state: {
    has_login: false,
    id: 1,
    mobile_num: '',
    name: ''
  },
  /*
    * mutations里面规定的就是想要改变state(数据)的动作函数,
    * 下面的user_message 就是我将传入的message赋值给仓库中的
    * state数据字段,达到更新数据的目的
    * */
  mutations: {
    user_message (state, message) {
      state.has_login = true;
      state.id = message.data.id;
      state.mobile_num = message.data.mobile_num;
      state.name = message.data.name;
    }
  }
})

然后在login.vue组件中,提交收到的用户信息
//位于login.vue

import userMessage from '../store';
export default new Vuex.Store({
   methods: {
      loginSubmit () {
        this.$axios({
          method: 'post',
          url: '/student/login/',
          data: {
            username: this.username,
            password: this.password
          }
        })
          .then(function (response) {
              //这里调用 store.js中 mutations里面的user_message函数,从而改变仓库中的state数据
            userMessage.commit('user_message', response);
            this.$router.replace({path: 'user'});
          }.bind(this))
          .catch(function (error) {
            console.log(error);
            alert('用户名或密码错误');
          });
      }
})

最后在user.vue组件中接收vuex仓库中存储的信息,即先引入仓库

//位于user.vue 中
import userMessage from '../store';

然后可以直接将 userMessage.state 赋值给user.vue作用域中的数据字段,同时,vuex 的state有热更新的属性,对于数据的同步很有帮助,优点良多。
所以,中大型的项目还是在一开始就直接使用vuex是明智的决定,对于开发有很大的便利。

6、动态组件

通过使用保留的 元素,动态地绑定到它的 is 特性,我们让多个组件可以使用同一个挂载点,并可以动态地切换。

<component v-bind:is="currentTabComponent"></component>

除此之外,Vue还提供了 。当在这些组件之间切换的时候,你有时会想保持这些组件的状态,以避免反复重渲染导致的性能问题。为了解决这个问题,我们可以用一个 元素将其动态组件包裹起来。
注意这个 要求被切换到的组件都有自己的名字,不论是通过组件的 name 选项还是局部/全局注册。
keep-alive:https://cn.vuejs.org/v2/api/#keep-alive

<!-- 失活的组件将会被缓存!-->
<keep-alive>
  <component v-bind:is="currentTabComponent"></component>
</keep-alive>

7、为什么组件中的data属性的值必须是一个函数

组件是可复用的vue实例,如果data是对象的话,object是引用类型,当同一个组件被多次复用时,data拷贝的就会是引用的地址即指针,当在其中某个组件修改data的值,其他组件中的值也会变化。用function return 其实就相当于申明了新的变量,相互独立,自然就不会有这样的问题。

data() {
  return {
    count: 0
  }
}

8、vue有哪些指令

v-html、v-show、v-if、v-else、v-else-if、v-for、v-on、v-bind等等

9、vue的响应式(双向数据绑定)原理

当一个Vue实例创建时,vue会遍历data选项的所有属性,并用 Object.defineProperty 将它们转为 getter/setter,并且在内部追踪相关依赖,在属性被访问和修改时通知变化。
每个组件实例都有相应的 watcher 实例,它会在组件渲染的过程中把“接触”过的数据属性记录为依赖。之后当依赖项的 setter 触发时,会通知 watcher,从而使它关联的组件重新渲染。
在这里插入图片描述
js实现简单的双向绑定:

<body>
	<div id="app">
		<input type="text" id="txt"/>
		<p id="show"></p>
	</div>
</body>
<script type="text/javascript">
	var obj={};
	Object.defineProperty(obj,'txt',{
		get:function(){
			return obj;
		},
		set:function(newVal){
			document.getElementById("txt").value = newVal;
			document.getElementById("show").innerHTML = newVal;
		}
	});
	document.getElementById('txt').addEventListener('keyup',function(e){
		obj.txt = e.target.value;
	});
</script>

10、vue如何监控某个属性值的变化

比如现在需要监控data中,obj.a 的变化。Vue中监控对象属性的变化你可以使用:
侦听属性watch

计算属性computed

watch:{
	obj:{
		handler:function(newVal,oldVal){
			console.log("obj is changed");
		},
		deep:true
	}
}

deep属性表示深层遍历,但是这么写会监控obj的所有属性变化,并不是我们想要的效果,所以做点修改:

watch:{
	'obj.a':{
		handler:function(newVal,oldVal){
			console.log("obj.a is changed");
		}
	}
}

还有一种方法,可以通过computed 来实现,只需要:

computed:{
	a1:function(){
		return this.obj.a;
	}
}

利用计算属性的特性来实现,当依赖改变时,便会重新计算一个新值。

## 官方例子:

<div id="demo">{{ fullName }}</div>
  var vm = new Vue({
  el: '#demo',
  data: {
    firstName: 'Foo',
    lastName: 'Bar',
    fullName: 'Foo Bar'
  },
  watch: {
    firstName: function (val) {
      this.fullName = val + ' ' + this.lastName
    },
    lastName: function (val) {
      this.fullName = this.firstName + ' ' + val
    }
  }
})

上面代码是命令式且重复的。将它与计算属性的版本进行比较:

var vm = new Vue({
  el: '#demo',
  data: {
    firstName: 'Foo',
    lastName: 'Bar'
  },
  computed: {
    fullName: function () {
      return this.firstName + ' ' + this.lastName
    }
  }
})

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

示例:

<template>
  <div>
    <ul>
      <li v-for="value in obj" :key="value">
        {{value}}
      </li>
    </ul>
    <button @click="addObjB">添加obj.b</button>
  </div>
</template>
<script>
export default {
  data () {
    return {
      obj: {
        a: 'obj.a'
      }
    }
  },
  methods: {
    addObjB () {
      this.obj.b = 'obj.b'
      console.log(this.obj)
    }
  }
}
</script>

当点击button按钮后,obj.b已经添加成功,但是视图并未更新,因为vue实例创建时,obj.b未声明,因此未被vue转化为响应式的属性,自然就不会触发视图的更新。也就是以上方法新增属性并不是响应式的。为了解决这个问题可以使用:

Vue.set( target, propertyName/index, value )

参数:

{Object | Array} target
{string | number} propertyName/index
{any} value

返回值:设置的值。

用法:
向响应式对象中添加一个属性,并确保这个新属性同样是响应式的,且触发视图更新。它必须用于向响应式对象上添加新属性,因为 Vue 无法探测普通的新增属性 (比如 this.myObject.newProperty = 'hi')

注意对象不能是 Vue 实例,或者 Vue 实例的根数据对象。

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

12、delete、splice、Vue.delete删除数组元素的区别

delete:将被删除元素值变成了empty/undefined,数组的长度不变,其他元素的键值也不改变。
splice、Vue.delete:删除了数组元素,使得其他元素的键值发生变化,数组长度也变化。

 <script type="text/javascript">
    	let arr1=[1,2,3,4];
    	let arr2=[1,2,3,4];
    	let arr3=[1,2,3,4];
    	delete arr1[1];
    	console.log(arr1);
    	arr2.splice(1,1);
    	console.log(arr2);
        this.$delete(arr3,1);
        console.log(arr3);
  </script>

结果:
在这里插入图片描述
在这里插入图片描述

13、优化SPA应用的首屏加载速度慢的问题

1、路由懒加载:
使用require.ensure,router懒加载就是按需加载组件,只有当路由被访问时才会加载对应的组件,而不是在加载首页的时候就加载,项目越大,对首屏加载的速度提升得越明显。
2、使用CDN资源
在Vue项目中,引入到工程中的所有js、css文件,编译时都会被打包进vendor.js,浏览器在加载该文件之后才能开始显示首屏。若是引入的库众多,那么vendor.js文件体积将会相当的大,影响首开的体验。
解决方法是,将引用的外部js、css文件剥离开来,不编译到vendor.js中,而是用资源的形式引用,这样浏览器可以使用多个线程异步将vendor.js、外部的js等加载下来,达到加速首开的目的。
外部的库文件,可以使用CDN资源,或者别的服务器资源等。
3、gzip压缩
4、异步加载组件
5、服务器端渲染

14、前端如何优化网站性能

1、减少HTTP请求数量:
在浏览器与服务器进行通信时,主要是通过 HTTP 进行通信。浏览器与服务器需要经过三次握手,每次握手需要花费大量时间。而且不同浏览器对资源文件并发请求数量有限(不同浏览器允许并发数),一旦 HTTP 请求数量达到一定数量,资源请求就存在等待状态,这是很致命的,因此减少 HTTP 的请求数量可以很大程度上对网站性能进行优化。

合并CSS文件
合并JS文件
使用精灵图CSS Sprites

采用懒加载lazyload

2、控制资源文件加载优先级:
浏览器在加载 HTML 内容时,是将 HTML 内容从上至下依次解析,解析到 link 或者 script 标签就会加载 href 或者 src 对应链接内容,为了第一时间展示页面给用户,就需要将 CSS 提前加载,不要受 JS 加载影响。
一般情况下都是 CSS 在头部,JS 在底部。

3、利用浏览器缓存
浏览器缓存是将网络资源存储在本地,等待下次请求该资源时,如果资源已经存在就不需要到服务器重新请求该资源,直接在本地读取该资源。

4、减少重排(Reflow)
基本原理:重排是DOM的变化影响到了元素的几何属性(宽和高),浏览器会重新计算元素的几何属性,会使渲染树中受到影响的部分失效,浏览器会验证 DOM 树上的所有其它结点的visibility属性,这也是Reflow低效的原因。如果Reflow的过于频繁,CPU使用率就会急剧上升。
减少Reflow,如果需要在DOM操作时添加样式,尽量使用 增加class属性,而不是通过style操作样式。

5、减少 DOM 操作
6、图标使用 IconFont 替换

15、网页到输入网址到渲染完成经历了哪些过程

1、输入网址
2、发送到DNS服务器,并获取域名对应的web服务器的对应的IP地址
3、与web服务器建议TCP连接
4、浏览器向web服务器发生http请求
5、web服务器响应请求并返回指定URL的数据、或错误信息、或重定向的新的URL地址
6、浏览器下载web服务器返回的数据及解析HTML源文件
7、生成DOM树,解析css、js,渲染页面,直至显示完成

### Vue 面试题及答案 #### 1. Vue.js 的响应式原理是什么? Vue.js 利用 **Object.defineProperty**(Vue 2.x)或 **Proxy**(Vue 3.x)来劫持数据对象的读写操作。当数据发生变化Vue 能够检测到这些变化,并通知相关的视图进行更新。这种机制使得数据视图保持同步,而无需手动操作 DOM。 具体来说,Vue 会递归地将数据对象的所有属性转换为 getter setter,从而实现对数据的监听。在 Vue 3.x 中,使用 Proxy 替代了 Object.defineProperty,提供了更强大的功能更好的性能[^1]。 #### 2. Vue 组件之间的通信方式有哪些? - **props / $emit**:父组件通过 props 向子组件传递数据,子组件通过 $emit 向父组件发送事件。 - **v-model**:本质上是 props $emit 的语法糖,用于双向绑定数据。 - **provide / inject**:祖先组件向后代组件提供数据,不需要逐级传递。 - **Event Bus**:通过一个全局的 Vue 实例作为事件总线,实现任意组件间的通信。 - **Vuex**:适用于复杂应用的状态管理工具,集中管理应用的状态。 #### 3. Vue 生命周期钩子函数有哪些?分别在什么候触发? Vue 组件的生命周期可以分为以下几个阶段: - **beforeCreate**:实例初始化之后,数据观测 (data observer) event/watcher 事件配置之前被调用。 - **created**:实例已经创建完成,属性已绑定,但 DOM 还未生成。 - **beforeMount**:挂载开始之前被调用。 - **mounted**:DOM 已经渲染完毕,可以访问真实的 DOM 元素。 - **beforeUpdate**:数据更新调用,发生在虚拟 DOM 重新渲染打补丁之前。 - **updated**:数据更新后调用,虚拟 DOM 重新渲染并应用补丁。 - **beforeUnmount**:实例销毁之前调用。 - **unmounted**:实例销毁后调用。 #### 4. Vue 3 相比 Vue 2 有哪些改进? - **更快的运行速度**:Vue 3 使用 Proxy 来实现响应式系统,相比 Vue 2 的 Object.defineProperty 更加高效。 - **更小的体积**:Vue 3 通过模块化设计 Tree-shaking 技术,显著减少了框架的体积。 - **更好的 TypeScript 支持**:Vue 3 原生支持 TypeScript,提供了更好的类型推导开发体验。 - **Composition API**:引入了类似于 React Hook 的 Composition API,使代码组织更加灵活可复用。 - **更好的可维护性扩展性**:Vue 3 的架构更加模块化,便于长期维护扩展。 #### 5. Vue 中的 computed watch 有什么区别? - **computed**:计算属性基于它们的依赖进行缓存,只有在其依赖的数据发生变化才会重新计算。适合处理复杂的逻辑模板中的表达式。 - **watch**:观察某个数据的变化,并执行相应的回调函数。适用于异步操作或需要执行开销较大的任务。 #### 6. Vue 中的 key 属性有什么作用? `key` 属性主要用于标识列表中每个元素的唯一性。当 Vue 渲染列表,它会尽可能高效地复用现有的元素,而不是重新创建新的元素。通过设置唯一的 `key`,可以帮助 Vue 更准确地判断哪些元素发生了变化,从而提高渲染效率。 #### 7. Vue 中的 v-if v-show 有什么区别? - **v-if**:据条件决定是否渲染元素。如果条件为假,则元素不会出现在 DOM 中。 - **v-show**:通过 CSS 的 `display` 属性控制元素的显示与隐藏。无论条件如何,元素始终存在于 DOM 中。 #### 8. Vue 中的 nextTick 是什么?有什么用途? `nextTick` 是 Vue 提供的一个方法,用于在下次 DOM 更新循环结束后执行回调函数。由于 Vue 的响应式系统是异步更新的,因此在某些情况下,直接访问或操作 DOM 可能无法获取最新的状态。通过 `nextTick`,可以确保在 DOM 更新完成后执行相关操作。 #### 9. Vue 中的 mixin 是什么?有什么优缺点? - **mixin**:是一种分发 Vue 组件中可复用功能的方式。可以通过定义 mixin 对象,包含组件的选项(如 data、methods、生命周期钩子等),然后将其混入到多个组件中。 - **优点**:提高代码的复用性可维护性。 - **缺点**:可能导致命名冲突逻辑混乱,特别是在大型项目中使用过多的 mixin 。 #### 10. Vue 中的插槽(slot)是什么?如何使用? 插槽是 Vue 提供的一种内容分发机制,允许父组件向子组件传递 HTML 内容。通过 `<slot>` 标签,可以在子组件中预留一个位置,供父组件填充内容。 - **默认插槽**:父组件直接传递内容给子组件。 - **具名插槽**:通过 `name` 属性指定不同的插槽位置。 - **作用域插槽**:子组件可以向父组件传递数据,父组件可以据这些数据自定义内容。 ```html <!-- 子组件 --> <template> <div> <slot name="header"></slot> <p>主要内容</p> <slot name="footer"></slot> </div> </template> <!-- 父组件 --> <template> <child-component> <template #header> <h1>头部内容</h1> </template> <template #footer> <p>底部内容</p> </template> </child-component> </template> ``` #### 11. Vue 中的 keep-alive 是什么?有什么用途? `keep-alive` 是 Vue 提供的一个内置组件,用于缓存动态组件的状态。当组件被切换,`keep-alive` 可以保留组件的状态,避免重复渲染初始化。这对于提升用户体验性能非常有帮助。 ```html <keep-alive> <component :is="currentComponent"></component> </keep-alive> ``` #### 12. Vue 中的 directive 是什么?如何自定义指令? 指令是 Vue 提供的一种特殊的属性,用于直接操作 DOM。常见的内置指令包括 `v-model`、`v-show`、`v-if` 等。 要自定义指令,可以通过 `directives` 选项定义一个对象,包含 `bind`、`inserted`、`update`、`componentUpdated` `unbind` 等钩子函数。 ```javascript // 自定义指令 directives: { focus: { inserted(el) { el.focus(); } } } ``` #### 13. Vue 中的 Vuex 是什么?有什么作用? VuexVue 官方提供的状态管理模式库,用于管理应用中的共享状态。它采用集中式存储管理所有组件的状态,并提供了一套规则来保证状态的变化是可以预测的。 - **State**:存储应用的状态。 - **Getters**:从 state 中派生出一些状态。 - **Mutations**:修改 state 的唯一方式,必须是同步函数。 - **Actions**:提交 mutations,可以包含异步操作。 - **Modules**:将 store 分割成模块,每个模块拥有自己的 state、getters、mutations、actions。 #### 14. Vue 中的 router 是什么?如何实现路由导航? Vue Router 是 Vue 官方的路由管理器,用于构建单页应用(SPA)。它提供了声明式的路由配置、嵌套路由、动态路由等功能。 要实现路由导航,可以通过 `<router-link>` 组件或编程式导航(`$router.push`、`$router.replace` 等)。 ```html <router-link to="/home">首页</router-link> ``` ```javascript this.$router.push('/about'); ``` #### 15. Vue 中的 Composition API 是什么?有什么优势? Composition API 是 Vue 3 引入的新特性,类似于 React Hook,允许开发者在不使用类组件的情况下,更好地组织复用逻辑代码。它提供了一系列函数(如 `ref`、`reactive`、`watch`、`computed` 等),帮助开发者更灵活地管理组件的状态逻辑。 - **优势**: - 提高代码的可读性可维护性。 - 更好的类型推导支持 TypeScript。 - 更容易复用逻辑代码。 ```javascript import { ref, onMounted } from 'vue'; export default { setup() { const count = ref(0); function increment() { count.value++; } onMounted(() => { console.log('组件已挂载'); }); return { count, increment }; } }; ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值