2023高频前端面试题-vue

1. 什么是 M V VM

Model-View-ViewModel 模式
在这里插入图片描述

Model 层: 数据模型层

通过 Ajaxfetch 等 API 完成客户端和服务端业务模型的同步。

View 层: 视图层

作为视图模板存在,其实 View 就是⼀个动态模板。

ViewModel 层: 视图模型层

负责暴露数据给 View 层,并对 View 层中的数据绑定声明、 指令声明、 事件绑定声明, 进行实际的业务逻辑实现。

数据变化了, 视图自动更新 => ViewModel 底层会做好监听 Object.defineProperty,当数据变化时,View 层会自动更新

视图变化了, 绑定的数据自动更新 => 会监听双向绑定的表单元素的变化,⼀旦变化,绑定的数据也会得到⾃动更新。

2. MVVM 的优缺点有哪些?

优点

  1. 实现了视图(View)和模型(Model)的分离,降低代码耦合、提⾼视图或逻辑的复⽤性

  2. 提⾼了可测试性:ViewModel 的存在可以帮助开发者更好地编写测试代码

  3. 能⾃动更新 DOM:利⽤双向绑定,数据更新后视图⾃动更新,让开发者从繁琐的⼿动操作 DOM 中解放出来

缺点

  1. Bug 难被调试:因为使⽤了双向绑定的模式,当我们看到界⾯发生异常了,有可能是 View 的代码产生的 Bug,

    也有可能是 Model 代码的问题。数据绑定使得⼀个位置的 Bug 被快速传递到别的位置,

    要定位原始出问题的地⽅就变得不那么容易了

    可采用的调试方案:

    (1) 注释掉一段代码, 确定代码的位置

    (2) debugger 打断点 或者 console 进行调试

  2. 在⼀个⼤的模块中 Model 也会很⼤,虽然使⽤上来说⽅便了,但如果⻓期持有不释放内存,就会造成更多的内存消耗

    占用的是 浏览器的 内存

3. 谈谈对 Vue 生命周期的理解?

生命周期的概念

每个 Vue 实例(每个组件也都是一个 vue 实例)都有⼀个完整的⽣命周期:

  1. 开始创建 (空实例)
  2. 初始化数据
  3. 编译模版
  4. 挂载 DOM
  5. 渲染、更新数据 => 重新渲染
  6. 卸载

这⼀系列过程我们称之为 Vue 的⽣命周期。

各个生命周期的作用

生命周期执行时机
beforeCreate在组件实例被创建之初、组件的属性⽣效之前被调用
created在组件实例已创建完毕。此时属性也已绑定,但真实 DOM 还未⽣成,$el 还不可⽤
beforeMount在组件挂载开始之前被调⽤。相关的 render 函数⾸次被调⽤
mounted在 el 被新建的 vm.$el 替换并挂载到实例上之后被调用
beforeUpdate在组件数据修改了, 视图更新之前调⽤。发⽣在虚拟 DOM 打补丁之前
updated在组件数据修改了, 视图更新之后被调用
activited在组件被激活时调⽤(使用了 <keep-alive> 的情况下)
deactivated在组件被停用时调⽤(使用了 <keep-alive> 的情况下)
beforeDestory在组件销毁前调⽤ (销毁: vue 默认会进行释放掉实例所有的监听, 释放掉所有的组件…)
destoryed在组件销毁后调⽤ (像定时器, webscoket 连接, … 跟 vue 没有太大关联的资源, 需要手动释放!)

生命周期示意图
在这里插入图片描述

4. 在 Vue 中网络请求应该放在哪个生命周期中发起?

至少在 created 之后, 因为数据才基本初始化完毕, 当然 mounted 中也可以 (比 created 稍晚一些)

5. Vue 组件之间如何进行通信?

父传子, 子传父, 非父子, Vuex

5.1 props 和 $emit

(1) 通过 props 将数据在组件树中进行⾃上⽽下的传递;

<jack :money="count" :obj="myobj"></jack>
export default {// props: ['money']props: {money: {type: Number,default: 1,},obj: {type: Object,default: () => {return {name: "zs",age: 18,};},},},
};

附件: props 验证

(2) 通过 $emit@ 来作信息的向上传递。

this.$emit('add-action', 参数1, 参数2, ...)
<jack @add-action="fatherFn"></jack>

5.2 eventBus 事件总线

可通过 EventBus 进⾏信息的发布与订阅。 (创建一个都能访问到的事件总线)

Vue.prototype.$eventBus = new Vue(); // this.$eventBus
// A组件中, 监听 bus的事件
this.$eventBus.$on('事件名', function(参数1, 参数2, ...) {...
})// B组件中, 触发 bus的事件
this.$eventBus.$emit('事件名', 参数1, 参数2, ...)

5.3 $children $parent $refs

(1) $children

父组件中, $children 返回的是一个组件集合,如果你能清楚的知道子组件的顺序,你也可以使用下标来操作

// 父组件中
<template><div class="hello_world"><com-a></com-a><com-b></com-b></div>
</template>

this.$children[0] => <com-a></com-a>

this.$children[1] => <com-b></com-b>

(2) $parent

子组件中, this.$parent 指向父组件

this.$parent.xxx = 200

this.$parent.fn()

(3) $refs

通过添加 ref 和 $refs 配合, 也可以很方便的获取子组件, 访问调用子组件的属性或方法

// 父组件中
<template><div class="hello_world"><com-a ref="coma"></com-a> // this.$refs.coma.count = 200<com-b ref="comb"></com-b> // this.$refs.comb.addFn()</div>
</template>

this.$refs.coma => <com-a></com-a>

this.$refs.comb => <com-b></com-b>

5.4 provide inject

**成对出现:**provide 和 inject 是成对出现的

作用:用于父组件向子孙组件传递数据

使用方法:

  • provide 在父组件中, 返回要传给下级的数据
  • inject 在需要使用这个数据的子孙组件中注入数据。(不论组件层次有多深)

父组件

export default {provide() {return {value: this.value, // 共享给子孙组件的数据};},data() {return {value: "父组件的数据",money: 100,};},
};

子孙组件

export default {inject: ['value'],props: {...}
}

5.5 $attrs $listeners

在 Vue 2.4 版本中加⼊的 $attrs$listeners 可以用来作为跨级组件之间的通信机制。 (父传孙)

父组件

<template><div><my-child1 :money="100" desc='你好哇' @test1="fn1" @test2="fn2"></my-child1></div>
</template>

子组件

<template><div class="my-child1"><!-- $attrs => { "money": 100, "desc": "你好哇" } --><div>{{ $attrs }}</div><my-child2 v-bind="$attrs" v-on="$listeners"></my-child2></div>
</template><script>
import MyChild2 from "./my-child2";
export default {created() {console.log(this.$listeners);},components: {MyChild2,},
};
</script>

在这里插入图片描述

孙组件

<template><div>我是child2 - {{ money }} - {{ desc }}<button @click="clickFn">按钮</button></div>
</template><script>
export default {props: ['money', 'desc'],methods: {clickFn () {this.$emit('test1', '嘎嘎')this.$emit('test2', '嘿嘿')}}
}
</script>

在这里插入图片描述

5.6 Vuex

全局状态管理库。可通过它来进行全局数据流的管理。

state: 存放数据

mutations: 存放操作数据的方法

actions: 存放一些异步操作 (也可以进行一些同步处理) 注意: actions 是不能直接修改 state 数据的, 需要提交 mutation

getters: 存放基于 state 计算出来的一些值 (计算属性)

modules: 分模块, 项目大了, 也推荐分模块管理 (同模块的 vuex 操作, 就会在一起)

注意点: 分模块了, 默认 muations, actions, getters 注册到全局的, 一般会开启命名空间

语法: namespaced: true

6. computed 和 watch 的区别是什么?

computed

  1. 它是计算属性。主要用于值的计算并一般会返回一个值。所以它更多⽤于计算值的场景
  2. 它具有缓存性。当访问它来获取值时,它的 getter 函数所计算出来的值会进行缓存
  3. 只有当它依赖的属性值发生了改变,那下⼀次再访问时才会重新调⽤ getter 函数来计算
  4. 它适⽤于计算⽐较消耗性能的计算场景
  5. 必须要有一个返回值

watch

  1. 它更多的是起到 “观察” 的作⽤,类似于对数据进行变化的监听并执行回调。

    主要⽤于观察 props 或 本组件 data 的值,当这些值发生变化时,执⾏处理操作

  2. 不一定要返回某个值

建议

  1. 当目的是进⾏数值计算,且依赖于其他数据,那么推荐使用 computed

  2. 当需要在某个数据发生变化的, 同时做⼀些稍复杂的逻辑操作,那么推荐使⽤ watch

7. Vue 双向绑定原理?

7.1 基本认知

在 Vue 2.x 中,利⽤的是 Object.defineProperty 去劫持对象的访问器(Getter、Setter),

当对象属性值发⽣变化时可获取变化,然后根据变化来作后续响应;(一个一个的劫持)

在 Vue 3.0 中,则是通过 Proxy 代理对象进⾏类似的操作。劫持的是整个对象, 只要对象中的属性变化了, 都能劫持到

7.2 Object.defineProperty 和 Proxy 的优缺点?

Proxy

  • 可以直接监听整个对象,⽽⾮是对象的某个属性

  • 可以直接监听数组的变化

  • 拦截⽅法丰富:多达 13 种,不限于get set deletePropertyhas 等。

    Object.defineProperty 强大很多

Object.defineProperty

  • 兼容性较好(可⽀持到 IE9)

8. 如何理解 Vue 的响应式系统?

(考察 MVVM) M: model 数据模型, V:view 视图模型, VM: viewModel 视图数据模型

双向:

  1. 视图变化了, 数据自动更新 => 监听原生的事件即可, 输入框变了, 监听输入框 input 事件
  2. 数据变化了, 视图要自动更新 => vue2 和 vue3

8.1 基本原理

vue2.0 数据劫持: Object.defineProperty (es5)

vue3.0 数据劫持: Proxy (es6)

分析 :此题考查 Vue 的 MVVM 原理

解答: Vue 的双向绑定原理其实就是 MVVM 的基本原理, Vuejs 官网已经说明, 实际就是通过 Object.defineProperty 方法 完成了对于 Vue 实例中数据的 劫持 , 通过对于 data 中数据 进行 set 的劫持监听, 然后通过 观察者模式 , 通知 对应的绑定节点 进行节点数据更新, 完成数据驱动视图的更新

简单概述 : 通过 Object.defineProperty 完成对于数据的劫持, 通过观察者模式, 完成对于节点的数据更新

8.2 观察者模式

观察者模式: 当对象间存在 一对多 关系时,则使用观察者模式(Observer Pattern)。

比如,当一个对象或者数据被修改时,则会自动通知依赖它的对象。

意图: 定义对象间的一种 一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。

拍卖会的时候,大家相互叫价,拍卖师(Dep) 会观察 最高标价(利用 Object.defineProperty 监听),

一旦最高价变化了, 然后通知给其它竞价者(watcher 观察者 - 订阅者, 订阅了价格的变化),这就是一个观察者模式

下图为 Vue 框架在数据初始化中使用观察者模式的示意图:
在这里插入图片描述
在这里插入图片描述

Dep 要进行 依赖收集,并通过一个 subs 数组, 记录观察者 Watcher,

Watcher 分为 渲染 watcher、计算属性 watcher、侦听器 watcher 三种

收集依赖: 简单点说就是谁借了我的钱,我就把那个人 记下来 ,以后我的钱少了 我就通知他们说我没钱了

<div><p>{{ msg }}</p>   // Watcher1(渲染), 依赖于msg
</div><div><h1>{{ car }}</h1>   // Watcher2(渲染),  依赖于car
</div><div><h1>{{ myMsg }}</h1>   // Watcher3(渲染), 依赖于myMsg
</div>computed: {myMsg () {console.log('计算属性重新计算了')return this.msg + '20'  // Watcher4(计算属性中), 依赖于msg, msg变了重新计算}
}watch: {msg (newValue) {console.log('新的msg', newValue) // Watcher5(侦听器), 将来msg变化, 这边要执行这个函数}
}------------------------------------------------------------------// 收集依赖 (dep结构有点类似于二维数组, (Map结构))   arr.type="msgDep"
dep: [msgDep: [Watcher5(侦听器), Watcher4(计算属性中), Watcher1(渲染)],carDep: [Watcher2(渲染)],myMsgDep: [Watcher3(渲染)]
]// Watcher
{callback: Function, (数据变化后, 需要执行的回调)isRenderWatcher: Boolean, (是否是render的watcher, 是否要触发视图的更新, 往后放, 最后统一虚拟dom对比, 统一更新)...
}

比如: 假定数据 money 变了, 那么没有任何与 money 相关的观察者, 就不需要进行任何更新操作, 也不需要执行任何的监视函数

然而: 假定数据 msg 变了, 就会通知到相关的 Watcher, 且优先通知侦听器 Watcher 和计算属性 Watcher, 后进行统一的渲染更新

  1. 通知侦听器 Watcher, 立刻执行配置的函数, console.log(‘新的 msg’, newValue)
  2. 通知计算属性 Watcher, 计算属性依赖的值变了, 需要重新计算
    且更新后, myMsg 变化了, 需要进行进行视图的渲染 (render) (— 要更新, 等着—)
  3. 通过到 watcher1, 渲染 Watcher (—要更新—)
  4. 最后统一进行, 新旧虚拟 dom 的对比, 完成视图的更新

当数据状态发生改变时,会被 Object.defineProperty 监听劫持到, 会通知到 Dep, 并根据收集的依赖关系,

让订阅者 Watcher 进行数据更新(update)操作 , 派发更新

总结概述: vue 采用的是观察者模式, 是一种一对多的关系, 一上来 vue 在解析渲染时, 会进行依赖收集, 会将渲染 watcher、计算属性 watcher、侦听器 watcher, 都收集到对应的 dep 中, 将来 Object.defineProperty 监听到数据变化, 就根据依赖关系, 派发更新

9. Vue 中的 key 到底有什么用?

key 是为 Vue 中的虚拟 DOM 节点(vNode)标记唯⼀性的 id。

9.1 key 的作用

作用: 给虚拟 dom 添加标识, (优化复用对比策略, 优化渲染性能)

主要考察:

  1. vue 的更新机制 (差异化更新) 对比新旧虚拟 dom, 找出不同的部分, 进行更新视图

    为什么对比虚拟 dom, 而不对比真实的 dom ? 真实的 dom 太复杂, 对比起来性能太差

  2. 虚拟 dom: 使用 js 对象的方式, 模拟真实的 dom 结构 { type: ‘div’, className: ‘box’ , children: [] }

    属性的量大大的减少了, 没有真实 dom 的那么多无效的属性, 对比起来性能高很多

  3. diff 算法: 默认的对比(diff) 机制, 同层兄弟元素, 是按照下标进行对比的, 但是加了 key, 就相当于给虚拟 dom 加了个标识

    对比策略, 就是对相同 key 的元素进行对比了, 在列表 v-for 中, key 的使用尤为常见, 可以用于优化渲染性能

在这里插入图片描述

9.2 key 的常见应用场景

key 的常见应用场景 => v-for, v-for 遍历的列表中的项的顺序, 非常的容易改变

1 往后面加, 默认的对比策略, 按照下标, 没有任何问题

// 旧
<ul><li>张三</li><li>李四</li>
</ul>// 新
<ul><li>张三</li><li>李四</li><li>王五</li>
</ul>

2 往前面加, 由于下标变了, 如果按照之前的下标对比, 元素是混乱的, 策略: 加上 key

一旦加上了 key, 就是按照 key 进行新旧 dom 的对比了

// 旧
<ul><li key="17">张三</li><li key="31">李四</li>
</ul>// 新  [ { id: 17, name: '张三' }, ... ]
<ul><li key="52">王五</li><li key="17">张三</li><li key="31">李四</li>
</ul>

总结: key 就是给 虚拟 dom 添加了一个 标识, 优化了对比策略!!!

10. Vue 跳转路由时的传参方式 (query 和 params 的区别)

  1. 通过 query 传参
this.$router.push("/login?username=pp&age=18&desc=xx");this.$router.push({path: "/login",query: {username: "pp",age: 18,desc: "xxx",},
});this.$router.push({name: "login",query: {username: "pp",age: 18,desc: "xxx",},
});

获取: this.$route.query.username

  1. 通过 params 传参, 必须通过命名路由的方式传递!
this.$router.push({name: "login",params: {username: "pp",age: 18,},
});

获取: this.$route.params.username

区别:

  1. params 传参, 必须要用命名路由的方式传值

  2. params 传参, 不会显示在地址栏中, 刷新会丢失

    可以配合 localStorage 使用

    (1) A 跳转路由到 B, 通过 params 传值

    (2) B 页面中, 立刻通过 this.$route.params 获取参数

    (获取参数的逻辑, 优先从$route 中拿, 如果拿不到(说明刷新了), 从本地取即可)

    (3) 拿到参数后, 立刻存到本地 (保证刷新丢失后, 还能从本地拿)

    (4) 实现功能…

B 页面的逻辑

created () {let username = this.$route.params.usernameif (username) {// 刚跳过来, 有参数, 立刻存起来localStorage.setItem('myParams', JSON.stringify(this.$route.params))} else {// 没有, 说明用户刷新了, 丢失了params, username参数, 本地拿username = JSON.parse(localStorage.getItem('myParams')).username}
}

11. Vue 项目进行 SEO 优化

Vue SPA 单页面应用对 SEO 不太友好,当然也有相应的解决方案,下面列出几种 SEO 方案

  1. SSR 服务器渲染

    服务端渲染, 在服务端 html 页面节点, 已经解析创建完了, 浏览器直接拿到的是解析完成的页面解构

    关于服务器渲染:Vue 官网介绍 ,对 Vue 版本有要求,对服务器也有一定要求,需要支持 nodejs 环境。

    优势: 更好的 SEO,由于搜索引擎爬虫抓取工具可以直接查看完全渲染的页面

    缺点: 服务器 nodejs 环境的要求, 且对原代码的改造成本高! nuxt.js (坑比较多, 做好踩坑的准备)

  2. 静态化 (博客, 介绍性官网)

    Nuxt.js 可以进行 generate 静态化打包, 缺点: 动态路由会被忽略。 /users/:id

    优势:

    • 编译打包时, 就会帮你处理, 纯静态文件,访问速度超快;
    • 对比 SSR,不涉及到服务器负载方面问题;
    • 静态网页不宜遭到黑客攻击,安全性更高。

    不足:

    • 如果动态路由参数多的话不适用。
  3. 预渲染 prerender-spa-plugin (插件)

    如果你只是对少数页面需要做 SEO 处理(例如 / 首页, /about 关于等页面)

    预渲染是一个非常好的方式, 预渲染会在构建时, 简单的针对特定路由, 生成静态 HTML 文件 (打包时可以帮你解析静态化)

    优势: 设置预渲染简单, 对代码的改动小

    缺点: 只适合于做少数页面进行 SEO 的情况, 如果页面几百上千, 就不推荐了 (会打包很慢)

  4. 使用 Phantomjs 针对爬虫 做处理

    Phantomjs 是一个基于 webkit 内核的无头浏览器,没有 UI 界面,就是一个浏览器,

    其内的点击、翻页等人为相关操作需要程序设计实现。

    这种解决方案其实是一种旁路机制,原理就是通过 Nginx 配置, 判断访问的来源 UA 是否是爬虫访问,

    如果是则将搜索引擎的爬虫请求转发到一个 node server,再通过 PhantomJS 来解析完整的 HTML,返回给爬虫

在这里插入图片描述

  1. 优势:

    • 完全不用改动项目代码,按原本的 SPA 开发即可,对比开发 SSR 成本小太多了;
    • 对已用 SPA 开发完成的项目,这是不二之选。

    不足:

    • 部署需要 node 服务器支持;

    • 爬虫访问比网页访问要慢一些,因为定时要定时资源加载完成才返回给爬虫;(不影响用户的访问)

    • 如果被恶意模拟百度爬虫大量循环爬取,会造成服务器负载方面问题,

      解决方法是判断访问的 IP,是否是百度官方爬虫的 IP。

小结:

  • 如果构建大型网站,如商城类 => SSR 服务器渲染

  • 如果只是正常公司官网, 博客网站等 => 预渲染/静态化/Phantomjs 都比较方便

  • 如果是已用 SPA 开发完成的项目进行 SEO 优化,而且部署环境支持 node 服务器,使用 Phantomjs

博客参考: SEO 优化方案

12. Vue 项目权限处理

现在权限相关管理系统用的框架都是 element 提供的vue-element-admin模板框架比较常见。

权限控制常见分为三大块

  • 菜单权限控制
  • 按钮权限控制
  • 请求 url 权限控制。

权限管理在后端中主要体现在对接口访问权限的控制,在前端中主要体现在对菜单访问权限的控制。

  1. 按钮权限控制比较容易,主要采取的方式是从后端返回按钮的权限标识,然后在前端进行显隐操作 v-if / disabled。

  2. url 权限控制,主要是后端代码来控制,前端只需要规范好格式即可。

  3. 剩下的菜单权限控制,是相对复杂一些的

    (1) 需要在路由设计时, 就拆分成静态路由和动态路由

    静态路由: 所有用户都能访问到的路由, 不会动态变化的 (登录页, 首页, 404, …)

    动态路由: 动态控制的路由, 只有用户有这个权限, 才将这个路由添加给你 (审批页, 社保页, 权限管理页…)

    (2) 用户登录进入首页时, 需要立刻发送请求, 获取个人信息 (包含权限的标识)

在这里插入图片描述

  1. (3) 利用权限信息的标识, 筛选出合适的动态路由, 通过路由的 addRoutes 方法, 动态添加路由即可!

    (4) router.options.routes (拿的是默认配置的项, 拿不到动态新增的) 不是响应式的!

    为了能正确的显示菜单, 为了能够将来正确的获取到用户路由, 我们需要用vuex 管理 routes 路由数组

    (5) 利用 vuex 中的 routes, 动态渲染菜单

13. Vue 项目支付功能

支付宝方式:点击支付宝支付, 调用后台接口(携带订单号),后台返回一个 form 表单(HTML 字符串结构),

提交 form 就可以调用支付宝支付

代码:

//  alipayWap: 后台接口返回的form 片段
<div v-html="alipayWap" ref="alipayWap"></div>methods: {toAlipay () {this.$axios.get('xxx').then (res = > {this.alipayWap = res;// 等待dom更新, 等页面中有这个form表单了this.$nextTick(() => {this.$refs.alipayWap.children[0].submit()})})}
}

在这里插入图片描述

微信支付:需要自己根据后台返回的 url 生成二维码页面,如图所示

在这里插入图片描述

博客参考 1: https://blog.csdn.net/qq_36710522/article/details/90480914

博客参考 2: https://blog.csdn.net/zyg1515330502/article/details/94737044

14. 如何处理 打包出来的项目(首屏)加载过慢的问题

SPA 应用: 单页应用程序, 所有的功能, 都在一个页面中, 如果第一次将所有的路由资源, 组件都加载了, 就会很慢!

加载过慢 => 一次性加载了过多的资源, 一次性加载了过大的资源

  • 加载过多 => 路由懒加载, 访问到路由, 再加载该路由相关的组件内容
  • 加载过大 => 图片压缩, 文件压缩合并处理, 开启 gzip 压缩等

比如:

  1. 配置异步组件, 路由懒加载

    const login = () => import("../pages/login.vue");
    
  2. 图片压缩: 使用 webp 格式的图片, 提升首页加载的速度

  3. CDN 加速: 配置 CDN 加速, 加快资源的加载效率 (花钱)

  4. 开启 gzip 压缩 (一般默认服务器开启的, 如果没开, 确实可能会很慢, 可以让后台开一下)

    在这里插入图片描述
    博客: https://www.cnblogs.com/xidian-Jingbin/p/10643391.html

15. 你在项目中遇到过什么技术难题

问题: 考察解决问题的能力!

话术: 前端要学的东西确实很多,但是并不夸张, 肯多花点时间沉淀一般都会有解决方案

一般遇到难题 (这些前端所谓的难题, 一般都是一些没有做过, 没有尝试过得一些业务), 我们要时刻保持独立思考,

知道自己要做什么业务由此决定要学什么知识, 然后实现业务, 举一反三,总结归纳!

比如 1: 如果之前没有做过国际化, 换肤, 没有做过支付, 权限控制, 没有做过即时通信 websocket, excel 导入导出, 就会觉得很难,

但其实真正上手花时间去学着做了, 也都能逐步思考解决相关页面, 这些其实也都还 ok

比如 2: 有时候, 复杂的或者困难的, 并不是技术层面的, 而是业务需求方面的, 需要进行大量树形结构的处理

展示列表式数据时, 展示图表数据时, 筛选条件关联条件多了, 组件与组件的联动关系的控制也比较麻烦,

将联动的条件, 存 vuex, 然后 => 进行分模块管理也是比较合适的选择

16. 请简单介绍一下你的项目

一定要做准备工作:

项目的介绍, 因人而异, 可以找不同的网站, 先从网站的功能业务角度出发, 去介绍

然后思考: 如果是现在让你写这样的功能页面, 你会如何实现! 然后手写记录下来, 推算合理性 (遇到什么问题, 怎么解决的!),

逐步完善对于项目的介绍

以饿了么为例: https://github.com/bailicangdu/vue2-elm

1 基本业务介绍: 给用户提供外卖服务的

2 技术栈: vue2 + vuex + vue-router + webpack + ES6/7 + axios+ sass + flex + svg

3 功能需求介绍:

  • 定位功能
  • 选择城市
  • 搜索地址
  • 展示所选地址附近商家列表
  • 搜索美食,餐馆
  • 根据距离、销量、评分、特色菜、配送方式等进行排序和筛选
  • 餐馆食品列表页
  • 购物车功能
  • 店铺评价页面
  • 单个食品详情页面
  • 商家详情页
  • 登录、注册
  • 修改密码
  • 个人中心
  • 发送短信、语音验证
  • 下单功能
  • 订单列表
  • 订单详情
  • 下载 App
  • 添加、删除、修改收货地址
  • 帐户信息
  • 服务中心
  • 红包
  • 上传头像
  • 付款

4 哪些模块你是会的, 就可以着重介绍, 哪些模块不太会做, 就查资料, 对比方案, 构思思路

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/170190.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

移远通信5G RedCap模组拿下首个中国移动5G物联网开放实验室5G及轻量化产品能力认证

10月21日&#xff0c;在2023世界物联网博览会期间&#xff0c;中国移动举办了以“智融万物 创见未来”为主题的物联网开发者大会暨物联网产业论坛。作为中国移动在物联网领域重要的合作伙伴&#xff0c;移远通信应邀参加论坛。 随着千行百业数智化进程的不断加速&#xff0c;5G…

什么是web3.0?

Web 3.0&#xff0c;也常被称为下一代互联网&#xff0c;代表着互联网的下一个重大演变。尽管关于Web 3.0的确切定义尚无共识&#xff0c;但它通常被认为是一种更分散、更开放且更智能的互联网。 以下是Web 3.0的一些主要特征和概念&#xff1a; 1. 去中心化 Web 3.0旨在减少…

达芬奇MacOS最新中文版 DaVinci Resolve Studio 18中文注册秘钥

DaVinci Resolve Studio 18是一款专业的视频编辑软件&#xff0c;它具有多种强大的功能。首先&#xff0c;它提供了丰富的视频剪辑工具&#xff0c;如剪切、复制、粘贴、剪辑、缩放和移动等&#xff0c;使用户可以轻松地剪辑和组合视频素材。其次&#xff0c;该软件还支持多个轨…

搜维尔科技:伦敦艺术家利用Varjo头显捕捉盲人隐藏的梦想

在伦敦举行的弗里泽艺术博览会上,与专业级虚拟现实/XR硬件和软件领域的全球领先者Varjo合作,展示一个突破性的混合现实艺术装置, 皇家国家盲人学会 (rnib),英国领先的视力丧失慈善机构。 这个名为"公共交通的私人生活"的装置是一个互动的声音和图像雕塑,旨在让有眼光…

AI小百科 - 什么是词向量?

如何表示一个单词的意义&#xff1f;对人来说&#xff0c;一般用解释法&#xff0c;用一段话来解释词的含义。如“太阳”在新华字典中的释义是“太阳系的中心天体。银河系的一颗普通恒星。”然而&#xff0c;这样的解释计算机是听不懂的&#xff0c;必须用更简洁的方式来对词义…

Unity3D 打包发布时生成文件到打包目录

有时候需要自己创建批处理文件或日志文件&#xff0c;在启动程序的同级目录使用&#xff0c;减少手动操作的时间和错误率。主要使用到的是OnPostprocessBuild方法。 1、在工程中的Editor文件夹下创建脚本 2、将文件放入Plugins的相关目录 3.脚本内容 using System.Collection…

智慧垃圾站:AI视频智能识别技术助力智慧环保项目,以“智”替人强监管

一、背景分析 建设“技术先进、架构合理、开放智能、安全可靠”的智慧环保平台&#xff0c;整合环境相关的数据&#xff0c;对接已建业务系统&#xff0c;将环境相关数据进行统一管理&#xff0c;结合GIS技术进行监测、监控信息的展现和挖掘分析&#xff0c;实现业务数据的快速…

3ds Max2023安装教程(最新最详细)

目录 一.简介 二.安装步骤 软件&#xff1a;3ds Max版本&#xff1a;2023语言&#xff1a;简体中文大小&#xff1a;6.85G安装环境&#xff1a;Win11/Win10/Win8/Win7硬件要求&#xff1a;CPU3GHz 内存16G(或更高&#xff09;下载通道①百度网盘丨64位下载链接&#xff1a; …

UMMKD

方法 对于“Y”形模型&#xff0c;绿线之前的层是分开的&#xff0c;绿线之后的层在模态之间共享。对于“X”形模型&#xff0c;第一条蓝线之前和第二条蓝线之后的层是分开的&#xff0c;蓝线之间的层在模态之间共享 作者未提供数据

Android Studio新功能-设备镜像Device mirroring-在电脑侧显示手机实时画面并可控制

下载最新的灰测版本-蜥蜴 成功运行到真机后&#xff0c;点击右侧Running Devices选项卡&#xff0c;再点击号 选中当前设备&#xff1b; 非常丝滑同步&#xff0c;在电脑侧也可以顺畅控制真机 该功能大大方便了我们视线保持在显示器上专注开发&#xff0c;并且便于与UI视觉进行…

Guacamole Web端配置使用

文章目录 项目目的下载需要的docker镜像配置数据库并启动服务访问并配置web页面连接windows系统 项目目的 使用Guacamole搭建&#xff0c;类似腾讯云那样的web远程控制页面 下载需要的docker镜像 guacamole和guacd都下载最新版&#xff0c;mysql则使用5.6的版本 docker pul…

报错:SSL routines:ssl3_get_record:wrong version number

一、问题描述 前后端联调的时候&#xff0c;连接后端本地服务器&#xff0c;接口一直pending调不通&#xff0c;控制台还报以下错误&#xff1a; 立马随手搜索了一下解决方案&#xff0c;但是emmm&#xff0c;不符合前端的实际情况&#xff1a; 二、解决方法&#xff1a; 实际…

RetentionPolicy枚举类

包名package java.lang.annotation 作用 注释保留策略。此枚举类型的常量描述用于保留注释的各种策略。它们被使用与&#xff5b; Retention&#xff5d;元注释类型一起指定注释要保留多长时间。 属性 SOURCE编译器将丢弃注释。CLASS注释将由编译器记录在类文件…

封装一个vue3 Toast组件,支持组件和api调用

先来看一段代码 components/toast/index.vue <template><div v-if"isShow" class"toast">{{msg}}</div> </template><script setup> import { ref, watch } from vue const props defineProps({show: {type: Boolean,def…

1024 特别企划|揭秘 StarRocks 社区背后的神秘力量(内涵福利)

自 2021 年成立以来&#xff0c;StarRocks 社区一路狂奔&#xff0c;短短两年便已跃居开源项目活跃度榜单的前三名&#xff0c;并已融入到互联网、金融、物流等各行各业的数据分析场景&#xff0c;发挥着越来越重要的作用。 在之前的文章《StarRocks 社区&#xff1a;从初生到两…

基于Qt 的CAN Bus实现

# 简介 从 Qt5.8 开始,提供了 CAN Bus 类,假设您的 Qt 版本没有 CAN Bus,可以参考 Linux 应用编程来操控开发板的 CAN,目前我们主要讲解 Qt 相关的 CAN编程。其实 Qt 也提供了相关的 Qt CAN 的例子,我们也可以直接参考来编程。读者手上需要有测试 CAN 的仪器!否则写好程…

【Maven教程】(九):使用 Maven 进行测试 ~

目录 1️⃣ account-captcha 1.1 account-captcha 1.2 account-captcha 的主代码 1.3 account-captcha的测试代码 2️⃣ maven-surefire-plugin 简介 3️⃣ 跳过测试 4️⃣ 动态指定要运行的测试用例 5️⃣ 包含与排除测试用例 6️⃣ 测试报告 6.1基本的测试报告 6.…

面试知识储备--打包工具篇(webpack和vite)

1.vite常用配置 常用配置 1.preprocessorOptions 传递给 CSS 预处理器的配置选项 2.PostCSS 也是用来处理 CSS 的&#xff0c;只不过它更像是一个工具箱&#xff0c;可以添加各种插件来处理 CSS 3.resolve.extensions 导入时想要省略的扩展名列表。默认值为 [‘.mjs’, ‘.js’…

武汉洪山区申请ITSS认证和能力评估CS认证的好处

武汉洪山区企业申请ITSS认证和信息系统建设和服务能力评估CS认证的好处 ITSS认证和信息系统建设和服务能力评估CS认证是一种评估和认证企业信息系统建设及服务能力的标准。这个认证体系基于一套全面的标准&#xff0c;通过评估企业的技术能力、管理能力和服务水平&#xff0c;…

Kafka3.x安装以及使用

一、Kafka下载 下载地址&#xff1a;https://kafka.apache.org/downloads 二、Kafka安装 因为选择下载的是 .zip 文件&#xff0c;直接跳过安装&#xff0c;一步到位。 选择在任一磁盘创建空文件夹&#xff08;不要使用中文路径&#xff09;&#xff0c;解压之后把文件夹内容剪…