1.Vue中的key
key 是为了给每一个虚拟DOM的唯一标识,为了更好的区别各个组件,依靠 key,主要是为了高效的更新虚拟DOM。
2.虚拟DOM
它作为Vue的核心机制之一,用于提高页面性能和开发效率。以树形结构的方式描述了整个DOM结构及其属性。可以通过JavaScript进行创建、修改,但不直接与浏览器的实际DOM交互。虚拟DOM通过差异计算和最小化实际DOM的操作,减少了浏览器的重绘和重排(样式改变重绘,几何信息改变重拍),提高了页面的性能。使用虚拟DOM可以更方便地进行组件化开发,提高代码的可维护性和可复用性。
3.封装一个原生的按钮需要传什么属性
type\size\backgroundColor\text\event
4.$nextTick
- $nextTick() 是 Vue.js 框架中的一个方法,是一个在 Vue 框架中使用的异步方法,其核心原理是利用浏览器的异步任务队列,特别是微任务优先的方式。当 Vue 应用中的数据发生变化时,Vue 会将相关的 DOM 更新操作放入一个异步任务队列中。这个队列通常会在下一次事件循环中被执行。Vue.nextTick() 的设计目的是将一个回调函数推入到这个异步任务队列中,确保在 DOM 更新完成后执行这个回调函数。
- Vue.nextTick() 的应用场景包括:
-
在数据变化后执行的操作,需要使用随数据变化而变化的 DOM 结构时。
-
在 Vue 生命周期中的 created() 钩子函数中进行 DOM 操作时。
在这些情况下,由于 Vue 的 DOM 操作是异步的,因此需要在异步队列中添加回调函数,以确保在 DOM 更新完成后执行这些操作。这样可以避免在数据变化后立即执行 DOM 操作导致的无用渲染,并确保在正确的时间访问最新的 DOM 状态。
5.v-model实现原理
v-model 双向绑定的原理是通过使用语法糖实现的,它本质上是一个语法糖,等同于通过绑定一个 value 属性和一个 input 事件来实现表单元素与 Vue 实例中数据的双向绑定。当表单元素的值发生变化时,input 事件监听器会将最新的值同步到 Vue
<input type="text" :value="msg" @input="setMsg" />
<h1>{{ msg }}</h1>
methods: {
setMsg (e) { this.msg = e.target.value }
}
6.封装一个输入框作为组件给所有人使用
输入的时候触发事件,内容改变的时候触发事件,默认展示文本,基本样式,用户可以指定宽高,背景颜色等等.placeholder:字段预期值的提示信息. type:文本框类型 -- name:name -- disabled:是否禁用 --- value:值 -- clearable:是否显示清空按钮
7.封装一个三级下拉菜单,展开有省市区,你封装这个组件会写一些什么参数?
数据哪来的;选中某一个地区返回一个数据,是返回最后一项还是三项都返回;返回数据的顺序;
8.如何理解路由
vue中是用vue-router实现的,vue的单页面应用是基于路由和组件的,路由用于设定访问路径,并将路径和组件映射起来
9.路由的使用流程
-
1.下载第三方包 npm i vue-router
-
2.在src文件里面新建一个router文件夹,里面新建一个index.js文件
-
3.文件中导入createRouter、createWebHashHistory
-
// 1. 引入第三方包的一些方法, 帮助我们创建路由
import { createRouter, createWebHashHistory } from "vue-router";
const routes = [
{
// 路由地址
path: "/",
// 对应路由显示组件
component: () => import("../views/home.vue"),
},触发
{
// 路由地址
path: "/cart",
// 对应路由显示组件
component: () => import("@/views/cart.vue"),
},
{
// 路由地址
path: "/login",
// 对应路由显示组件
component: () => import("../views/login.vue"),
},
];
// 2. 创建一个路由实例
const router = createRouter({
// 确定路由模式,当前使用hash模式
history: createWebHashHistory(),
// 定义路由表
routes,
});
// 3. 导出当前路由实例
export default router;
- 5.入口文件
import router from "./router/index.js"
myApp.use(router)
- 6.App.vue里面
<router-view> </router-view>
10.Vuex的使用流程
- 1.安装:
npm i vuex - 2.在 src 下创建 store 目录, 并添加 index.js 文件
// 1. 导入 createStore 一会用于创建 store
import { createStore } from 'vuex'
// 2. 创建一个 store, 一会用于导出, 挂载到入口函数中
const store = createStore({
state () {
return {
num: 10086,
num2: 10010,
num3:9999
}
}
})
// 3. 导出 store
export default store
-
- 在入口文件引入, 并通过 use 挂载
import { createApp } from "vue";
import App from "./App.vue";
// 1. 引入 vuex
import store from "./store/index.js";
const myApp = createApp(App);
// 2. 挂载 vuex
myApp.use(store);
myApp.mount("#app");
- 4.在App.vue中使用
<template>
<h1>我是 APP 组件</h1>
<h1> {{ $store.state.num }} </h1>
</template>
<script>
//1.导入辅助函数
import { mapState } from "vuex"
export default {
data() {
return {};
},
computed: {
...mapState(['num', 'num3'])
},
mounted() {
console.log(this.$store)
}
};
</script>
<style></style>
11.v-router使用流程
-
1.下载第三方包 npm i vue-router
-
2.在src文件里面新建一个router文件夹,里面新建一个index.js文件
-
3.文件中导入createRouter、createWebHashHistory
-
// 1. 引入第三方包的一些方法, 帮助我们创建路由
import { createRouter, createWebHashHistory } from "vue-router";
const routes = [
{
// 路由地址
path: "/",
// 对应路由显示组件
component: () => import("../views/home.vue"),
},触发
{
// 路由地址
path: "/cart",
// 对应路由显示组件
component: () => import("@/views/cart.vue"),
},
{
// 路由地址
path: "/login",
// 对应路由显示组件
component: () => import("../views/login.vue"),
},
];
// 2. 创建一个路由实例
const router = createRouter({
// 确定路由模式,当前使用hash模式
history: createWebHashHistory(),
// 定义路由表
routes,
});
// 3. 导出当前路由实例
export default router;
- 5.入口文件
import router from "./router/index.js"
myApp.use(router)
- 6.App.vue里面
<router-view> </router-view>
12.Vuex的五个模块
state,唯一数据源mutation,类似于事件,在vuex中修改state的唯一方法action,异步的getter,计算属性module,模块
13.使用state中的数据
$store.state.num- 使用辅助函数
import { mapState } from "vuex"
export default {
computed: {
...mapState(['num', 'num3'])
},
}
14.子传父完整流程
- 1.子组件在某一个时机, 通知父组件, 触发一个事件我们当前案例中, 是在子组件的输入框输入了内容的时候通知
- 2.在父组件使用子组件的时候, 给子组件绑定一个自定义事件, 一定记得使用 @当子组件通知我们触发这个自定义事件的时候, 我们在父组件内有一个对应的函数会触发,这个函数的参数就是子组件通知父组件时传递的数据
15.组合式API创建响应式数据
- ref\reactive\toRef\toRefs\shallowRef\shallowReactive
16.组合式API完成子传父
- 父组件中引入子组件,定义一个自定义事件,对应的函数的参数是子组件传递的数据
- 子组件中导入defineEmits,子组件找到一个合适的时机触发自定义事件,const emit ,然后emit(“事件名”,数据)
17.vue里实现一个v-model
<input type="text" :value="msg" @input="setMsg" />
<h1>{{ msg }}</h1>
<script>
export default {
data() {
return {msg: "初识默认值", };
},
methods: {
setMsg (e) {
this.msg = e.target.value
}
}
};
</script>
18.组合式API里面的生命周期
onBeforeMount
onMounted
onBeforeUpdate
onUpdated
onUnmount
onUnmounted
19.对组件化开发的理解
- 完整的功能封装到一个组件里,完全独立的功能,不依赖外界环境执行,比如弹出框
20.vue开发里面数据驱动试图怎么理解?
- 它基于一种响应式的系统,使得数据的变化可以自动地更新视图。简单来说,当你修改Vue实例的数据时,相应的视图会自动更新以反映出数据的变化,而无需手动操作DOM。这种数据驱动的方式带来了许多好处。首先,它使得我们可以更方便地管理和维护视图,因为我们只需要关注数据的变化,而不用手动操作DOM元素。其次,它提供了更高的开发效率,因为我们可以专注于数据的处理和业务逻辑,而不用过多关注视图的更新。
21.组合式API与选项式API有什么区别
- 组合式API是将多个不同的API整合在一起,提供更全面的功能,而选项式API则是将多个API按照顺序连接在一起,完成一系列相关的操作。
- 选项式API:date选项写数据,methods选项写函数...一个功能逻辑的代码分散
- 组合式API: 一个功能逻辑的代码组织在一起(包括数据,函数、、、)
- 组合式API里面使用组件不需要注册,引入后直接可以使用
- 组合式API里面的watch可以监听多个对象,第一个参数写成数组的形式,第二个参数是一个回调函数,第三个是一些配置项
22.组合式API获取标签
1)使用ref方法定义一个响应式数据
2)用ref属性将响应式数据绑定上去
3)直接用数据名.value获取标签
23.组合式和选项式侦听器区别
1)组合式侦听器需要导入watch方法
2)选项式侦听器只能侦听一个对象,如果要监听多个对象,需要在计算属性中return多个对象,然后再去侦听那个计算属性
3)组合式侦听器可以直接接侦听多个对象,第一个参数写成数组的形式,第二个参数是一个回调函数,第三个参数是配置项
24.为什么使用路由懒加载
- 路由懒加载的主要目的是优化页面加载性能。当页面较大时,使用路由懒加载可以分割资源,根据路由动态加载所需的组件,而不是一次性加载所有组件,这样可以加快初始页面加载速度,提高用户体验。
25.如何触发action和mutation
1)普通触发
// 在组件中触发
action this.$store.dispatch('actionName', payload);
// 在组件中触发
mutation this.$store.commit('mutationName', payload);
2)借用辅助函数触发
import { mapActions, mapMutations } from 'vuex';
methods: {
// 映射 actions
...mapActions(['increment', 'decrement']),
// 映射 mutations
...mapMutations(['incrementMutation', 'decrementMutation']),
// 其他自定义方法
}
//使用的时候直接this.increment
26.路由的两种写法
1)直接引入组件
import Home from "./components/Home.vue"
const routes = [
{
path:"/",
component:Home
}
]
2)使用动态import实现路由懒加载
const routes = [
{
path:"/",
component:() => import("./components/Home.vue")
}
]
27.Element-Plus中的scope.row
-
在Vue.js的组件中,我们经常会使用到
scope.row,其实scope.row代表组件中的一行数据。scope.row通常用于循环表格中的表格行,可以在table或el-table等组件中使用。 -
在该组件内部,每一行都会生成一个可绑定的对象,该对象就是每一行的数据。
scope.row会自动为我们绑定该对象,在组件内部可以通过该对象来获取行的具体数据。
<el-table :data="tableData">
<el-table-column prop="name">
<template scope="scope">
{{ scope.row.name }}
//在上述代码实例中,我们使用了scope.row.name获取当前行数据中的name属性,并在模板中进行了展示。
</template>
</el-table-column>
</el-table>
28.Vue3里面组合式新增的API
ref、 reactive、 watchEffect、setup、toRef、toRefs
29.框架和库的区别
- 框架(Framework):框架是一个完整的、强大的程序结构,提供了一种组织和执行代码的方法。开发者在框架的基础上编写自己的代码,而框架则负责管理整个应用程序的生命周期。提供了一整套规则和结构,有助于快速开发。然而,可能在某些情况下限制了灵活性。一个框架是由无数个库组成的,适用于构建大型、复杂的应用程序
- 库(Library):库是一组已经编写好的代码片段,可被开发者引用并重复使用。它通常提供了一些特定的功能、方法或工具,以简化开发者在其应用程序中的任务。提供特定的功能,开发者可以更自由地选择如何集成这些功能,因此更加灵活,但需要开发者自行组织代码结构。适用于需要特定功能的场景
30.路由跳转
- 声明式:类似于超链接a
- 1.在vue中路由跳转是router-link
<router-link to="/path">Go to Path</router-link>
- 2.在小程序中路由跳转
<!-- 在 wxml 文件中 -->
<navigator url="/pages/destination/destination">Go to Destination</navigator>
- 编程式: 类似于location.href
- 1.路由跳转是router.push/router.replace/router.go/router.back
// 使用 router.push 进行路由跳转
this.$router.push('/path');
// 使用 router.replace 替换当前路由
this.$router.replace('/path');
// 使用 router.go 进行前进或后退导航
this.$router.go(1); // 前进一步
this.$router.go(-1); // 后退一步
// 使用 router.back 后退一步(等同于 router.go(-1))
this.$router.back();
- 2.在小程序中
// 在页面中使用 JavaScript
// 使用 wx.navigateTo 进行路由跳转
wx.navigateTo({
url: '/pages/destination/destination'
});
// 使用 wx.redirectTo 进行重定向
wx.redirectTo({
url: '/pages/anotherpage/anotherpage'
});
// 使用 wx.navigateBack 进行返回上一页
wx.navigateBack({
delta: 1
});
// 使用 wx.switchTab 进行 Tab 切换
wx.switchTab({
url: '/pages/tabbarpage/tabbarpage'
});
31.nvue 开发与 vue 开发的常见区别
基于原生引擎的渲染,虽然还是前端技术栈,但和 web 开发肯定是有区别的。
- nvue 页面控制显隐只可以使用
v-if不可以使用v-show - nvue 页面只能使用
flex布局,不支持其他布局方式。页面开发前,首先想清楚这个页面的纵向内容有什么,哪些是要滚动的,然后每个纵向内容的横轴排布有什么,按 flex 布局设计好界面。 - nvue 页面的布局排列方向默认为竖排(
column),如需改变布局方向,可以在manifest.json->app-plus->nvue->flex-direction节点下修改,仅在 uni-app 模式下生效。详情。 - nvue 页面编译为 H5、小程序时,会做一件 css 默认值对齐的工作。因为 weex 渲染引擎只支持 flex,并且默认 flex 方向是垂直。而 H5 和小程序端,使用 web 渲染,默认不是 flex,并且设置
display:flex后,它的 flex 方向默认是水平而不是垂直的。所以 nvue 编译为 H5、小程序时,会自动把页面默认布局设为 flex、方向为垂直。当然开发者手动设置后会覆盖默认设置。 - 文字内容,必须、只能在
<text>组件下。不能在<div>、<view>的text区域里直接写文字。否则即使渲染了,也无法绑定 js 里的变量。 - 只有
text标签可以设置字体大小,字体颜色。 - 布局不能使用百分比、没有媒体查询。
- nvue 切换横竖屏时可能导致样式出现问题,建议有 nvue 的页面锁定手机方向。
- 支持的 css 有限,不过并不影响布局出你需要的界面,
flex还是非常强大的。详见 - 不支持背景图。但可以使用
image组件和层级来实现类似 web 中的背景效果。因为原生开发本身也没有 web 这种背景图概念 - css 选择器支持的比较少,只能使用 class 选择器。详见
- nvue 的各组件在安卓端默认是透明的,如果不设置
background-color,可能会导致出现重影的问题。 class进行绑定时只支持数组语法。- Android 端在一个页面内使用大量圆角边框会造成性能问题,尤其是多个角的样式还不一样的话更耗费性能。应避免这类使用。
- nvue 页面没有
bounce回弹效果,只有几个列表组件有bounce效果,包括list、recycle-list、waterfall。 - 原生开发没有页面滚动的概念,页面内容高过屏幕高度并不会自动滚动,只有部分组件可滚动(
list、waterfall、scroll-view/scroller),要滚得内容需要套在可滚动组件下。这不符合前端开发的习惯,所以在 nvue 编译为 uni-app 模式时,给页面外层自动套了一个scroller,页面内容过高会自动滚动。(组件不会套,页面有recycle-list时也不会套)。后续会提供配置,可以设置不自动套。 - 在 App.vue 中定义的全局 js 变量不会在 nvue 页面生效。
globalData和vuex是生效的。 - App.vue 中定义的全局 css,对 nvue 和 vue 页面同时生效。如果全局 css 中有些 css 在 nvue 下不支持,编译时控制台会报警,建议把这些不支持的 css 包裹在条件编译里,
APP-PLUS-NVUE - 不能在
style中引入字体文件,nvue 中字体图标的使用参考:加载自定义字体。如果是本地字体,可以用plus.io的 API 转换路径。 - 目前不支持在 nvue 页面使用
typescript/ts。 - nvue 页面关闭原生导航栏时,想要模拟状态栏,可以参考文章。但是,仍然强烈建议在 nvue 页面使用原生导航栏。nvue 的渲染速度再快,也没有原生导航栏快。原生排版引擎解析
json绘制原生导航栏耗时很少,而解析 nvue 的 js 绘制整个页面的耗时要大的多,尤其在新页面进入动画期间,对于复杂页面,没有原生导航栏会在动画期间产生整个屏幕的白屏或闪屏。
32.Vue修饰符
Vue.js是一个流行的JavaScript框架,提供了一些修饰符,用于在指令中添加特殊功能。以下是一些常见的Vue指令修饰符:
-
v-model修饰符:
.lazy: 默认情况下,v-model 在 input 事件中同步输入框的值,使用.lazy修饰符可以转变为在 change 事件中同步。.number: 将用户的输入值转为数字类型。.trim: 自动过滤用户输入的首尾空白字符。
<input v-model.lazy="message"> <input v-model.number="age"> <input v-model.trim="username"> -
v-on修饰符:
.stop: 阻止事件冒泡。.prevent: 阻止默认事件。.capture: 添加事件侦听器时使用 capture 模式。.self: 只当事件是从侦听器绑定的元素本身触发时才触发回调。
<a v-on:click.stop="doThis"></a> <form v-on:submit.prevent="onSubmit"></form> <div v-on:click.capture="doThat"></div> <div v-on:click.self="doSomething"></div> -
v-bind修饰符:
.prop: 用于绑定 DOM 属性。.camel: 将 kebab-case 属性名转为 camelCase。
<div v-bind:my-prop.prop="someValue"></div> <div v-bind:camel-case.prop="someValue"></div> -
v-show和v-if修饰符:
.sync: 用于在父子组件之间双向绑定 Boolean 值。
<child :visible.sync="isVisible"></child>
这只是一些常见的修饰符,Vue.js 还提供其他一些用于不同指令的修饰符。在使用时,请参考官方文档,因为新的修饰符可能会在新的版本中被引入。