目录
编辑
# HTML&CSS
【1】简述Chrome盒模型与IE盒模型的区别(掌握)
【2】什么是弹性布局?(掌握)
【3】html5有哪些新特性?(掌握)
【4】CSS3有哪些新特性(掌握)
【5】如何让一个盒子在页面垂直水平居中(掌握)
【6】如何实现响应式布局
1. 使用Viewport单位
2. 弹性布局(Flexbox)
3. 栅格系统
4. 媒体查询
5. CSS Grid
【7】css画三角形,n种方法
解释:
# JavaScript
【1】事件冒泡和事件捕获到底有何区别?(掌握)
【2】什么是闭包?为什么要用它?(掌握)
解释:
Cookies
sessionStorage
localStorage
【4】什么是防抖和节流?有什么区别?如何实现?(掌握)
防抖(Debounce)
节流(Throttle)
# 小程序
【1】小程序登录流程
1. 获取用户登录凭证 code
2. 后端服务器获取 openid 和 session_key
3. 后端服务器处理并返回用户信息
4. 小程序端保存登录态
5. 用户授权和信息获取(可选)
【2】静默登录和非静默登录
静默登录
非静默登录
【3】小程序生命周期
【4】小程序常用API
1. 获取用户信息
【7】小程序包超过2M怎么处理
1. 图片优化
2. 代码优化
3. 功能优化
4. 资源管理
5. 性能分析与测试
# Vue
【1】能说下 vue-router 中常用的路由模式实现原理吗
【2】vue常用的修饰符?
【3】vue中v-if与v-show的区别以及使用场景
【4】v-if和v-for为什么避免一起用
【5】Vue.set 方法使用
【6】多层父子组件通讯
1. 使用 Props 和事件
2. 使用 Vuex 进行状态管理
【7】Vuex刷新页面数据丢失怎么解决?
1. 使用持久化方案
2. 利用浏览器的 sessionStorage 或 localStorage
3. 使用后端存储和恢复方案
【8】简单讲述vuex
【9】`$route` 和 `$router` 的区别
【10】Computed和Watch
Computed 属性
Watch 监听器
# HTML&CSS
【1】简述Chrome盒模型与IE盒模型的区别(掌握)
Chrome盒模型与IE盒模型是指网页浏览器中两种不同的CSS盒模型实现方式。它们的主要区别在于如何计算盒模型的总宽度和高度。
-
Chrome盒模型(也称为W3C标准盒模型):
- 盒模型的总宽度和高度包括了内容区域的宽度和高度(content width/height)、内边距(padding)、边框(border)以及外边距(margin)。
- 这意味着,当你设置一个元素的宽度(width)和高度(height)时,设置的是内容区域的宽度和高度。
-
IE盒模型(也称为传统盒模型):
- 盒模型的总宽度和高度包括了内容区域的宽度和高度,加上内边距(padding)和边框(border)的宽度。
- 在IE盒模型中,设置元素的宽度(width)和高度(height)时,设置的是内容区域、内边距和边框的总宽度和高度。换言之,IE盒模型中的宽度和高度包括了内边距和边框。
现代浏览器(包括Chrome、Firefox等)普遍采用Chrome盒模型(W3C标准盒模型),而IE浏览器在标准模式下也支持Chrome盒模型。在实际开发中,通常不再需要特别关注IE盒模型,除非需要兼容旧版本IE浏览器。
【2】什么是弹性布局?(掌握)
弹性布局(Flexbox)是一种用来进行页面布局的现代CSS布局模型,它能够更方便地实现复杂的布局需求。以下是一个简单的示例代码,带有注释解释每个部分的作用:
/* 设置容器的样式 */
.container {
display: flex; /* 声明容器使用弹性布局 */
justify-content: space-between; /* 水平方向上子项目的对齐方式:两端对齐 */
align-items: center; /* 垂直方向上子项目的对齐方式:居中对齐 */
height: 200px; /* 设置容器的高度 */
background-color: #f0f0f0; /* 设置容器的背景色 */
padding: 20px; /* 设置容器的内边距 */
}
/* 设置子项目的样式 */
.item {
flex: 1; /* 子项目的扩展比例,使其自动填充剩余空间 */
height: 100px; /* 设置子项目的高度 */
margin: 0 10px; /* 设置子项目之间的外边距 */
background-color: #3498db; /* 设置子项目的背景色 */
color: white; /* 设置子项目的文字颜色 */
text-align: center; /* 设置子项目中文字的对齐方式 */
line-height: 100px; /* 设置子项目中文字的行高,使其垂直居中 */
}
HTML结构:
<div class="container">
<div class="item">Item 1</div>
<div class="item">Item 2</div>
<div class="item">Item 3</div>
</div>
CSS说明:
-
.container
样式:display: flex;
:声明容器使用弹性布局。justify-content: space-between;
:子项目在主轴(水平方向)上的对齐方式,这里是两端对齐,即使每个子项目之间的间距相等,并且与容器的两端对齐。align-items: center;
:子项目在交叉轴(垂直方向)上的对齐方式,这里是居中对齐,使子项目在垂直方向上居中显示。height: 200px;
:设置容器的高度为200像素。background-color: #f0f0f0;
:设置容器的背景色为浅灰色。padding: 20px;
:设置容器的内边距为20像素。
-
.item
样式:flex: 1;
:子项目的扩展比例,这里设置为1,表示每个子项目在剩余空间中平均分配。height: 100px;
:设置子项目的高度为100像素。margin: 0 10px;
:设置子项目之间的外边距为0上下,10像素左右。background-color: #3498db;
:设置子项目的背景色为蓝色。color: white;
:设置子项目的文字颜色为白色。text-align: center;
:设置子项目中文字的对齐方式为居中。line-height: 100px;
:设置子项目中文字的行高为100像素,使其垂直居中显示。
这段示例代码实现了一个简单的弹性布局,容器中包含三个子项目,每个子项目在水平方向上均匀分布,垂直方向上居中显示。
【3】html5有哪些新特性?(掌握)
HTML5引入了许多新特性和改进,以下是一些主要的特性及其简单示例代码,带有注释解释每个部分的作用:
<!DOCTYPE html> <!-- HTML5的文档类型声明 -->
<html lang="en">
<head>
<meta charset="UTF-8"> <!-- 指定文档使用的字符编码 -->
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <!-- 设置移动设备的视口 -->
<title>HTML5新特性示例</title>
</head>
<body>
<!-- 语义化标签 -->
<header>
<h1>Welcome to My Website</h1>
<nav>
<ul>
<li><a href="#">Home</a></li>
<li><a href="#">About</a></li>
<li><a href="#">Services</a></li>
<li><a href="#">Contact</a></li>
</ul>
</nav>
</header>
<!-- 表单增强 -->
<form>
<label for="name">Name:</label>
<input type="text" id="name" name="name" required> <!-- required属性表示必填字段 -->
<label for="email">Email:</label>
<input type="email" id="email" name="email" required> <!-- type="email"会验证邮箱格式 -->
<button type="submit">Submit</button> <!-- type="submit"按钮,用于提交表单 -->
</form>
<!-- 多媒体增强 -->
<video controls>
<source src="movie.mp4" type="video/mp4"> <!-- HTML5 video标签支持多种媒体格式 -->
Your browser does not support the video tag.
</video>
<!-- Canvas绘图 -->
<canvas id="myCanvas" width="200" height="100"></canvas>
<script>
var canvas = document.getElementById('myCanvas');
var ctx = canvas.getContext('2d');
ctx.fillStyle = 'blue';
ctx.fillRect(10, 10, 150, 80);
</script>
<!-- 本地存储 -->
<p>Click the button to store data locally:</p>
<button onclick="localStorage.setItem('name', 'John')">Store Data</button>
<button onclick="alert('Stored Name: ' + localStorage.getItem('name'))">Get Data</button>
<!-- 新的语义化元素 -->
<article>
<h2>Article Title</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam consectetur lectus vel justo bibendum, sit amet venenatis nunc fermentum.</p>
</article>
<!-- Web Workers -->
<script>
var worker = new Worker('worker.js');
worker.postMessage('Hello, Worker!');
worker.onmessage = function(event) {
console.log('Received message from worker:', event.data);
};
</script>
</body>
</html>
-
语义化标签:
<header>
:定义页面或区段的头部。<nav>
:定义导航链接的容器。<section>
、<article>
、<aside>
、<footer>
等:更明确地定义文档结构,提高可读性和SEO。
-
表单增强:
required
属性:指定字段为必填项。type="email"
:验证输入是否为邮箱格式。
-
多媒体增强:
<video>
和<audio>
:原生支持多种格式的视频和音频播放。
-
Canvas绘图:
<canvas>
:通过JavaScript绘制图形和动画。
-
本地存储:
localStorage
:在客户端存储数据,使得数据可以持久化存储并在本地访问。
-
新的语义化元素:
<article>
:定义一个独立的内容块,比如一篇文章。<section>
:定义文档的区段。
-
Web Workers:
Worker
对象:允许在后台运行脚本,提高页面性能和响应性。
HTML5的这些新特性使得开发者可以更加便捷地创建交互性强、语义化好、功能丰富的Web应用程序和网页。
【4】CSS3有哪些新特性(掌握)
CSS3引入了许多新特性,让开发者能够更加灵活和高效地样式化网页。以下是一些主要的CSS3新特性及其示例代码,带有注释解释每个部分的作用:
/* 圆角边框 */
div {
border-radius: 10px; /* 设置圆角半径为10像素 */
}
/* 阴影效果 */
div {
box-shadow: 5px 5px 10px rgba(0, 0, 0, 0.1); /* 设置盒子阴影:水平偏移5px,垂直偏移5px,模糊半径10px,透明度0.1 */
}
/* 渐变背景 */
div {
background: linear-gradient(to right, #ffcc00, #ff6666); /* 从左到右线性渐变背景色 */
}
/* 过渡效果 */
a {
transition: color 0.3s ease-in-out; /* 颜色变化过渡效果,持续时间0.3秒,缓动函数为ease-in-out */
}
a:hover {
color: #ff0000; /* 悬停时改变颜色 */
}
/* 动画 */
@keyframes myAnimation {
0% {
transform: scale(1);
}
50% {
transform: scale(1.1);
}
100% {
transform: scale(1);
}
}
div {
animation: myAnimation 3s infinite; /* 应用动画:持续时间3秒,无限循环 */
}
/* 字体特性 */
p {
font-family: "Arial", sans-serif; /* 设置字体 */
font-size: 16px; /* 设置字体大小 */
font-weight: bold; /* 设置字体粗细 */
}
/* 2D和3D转换 */
div {
transform: rotate(45deg); /* 旋转45度 */
}
-
圆角边框 (
border-radius
):- 使用
border-radius
属性可以为元素的边框添加圆角。
- 使用
-
阴影效果 (
box-shadow
):box-shadow
属性允许为元素添加阴影效果,可以控制阴影的偏移、模糊程度和颜色透明度。
-
渐变背景 (
linear-gradient
):linear-gradient
函数可以创建线性渐变背景色,允许在元素的背景上从一种颜色平滑过渡到另一种颜色。
-
过渡效果 (
transition
):transition
属性允许在元素状态改变时,平滑地过渡样式的变化,如颜色、大小等。
-
动画 (
@keyframes
和animation
):@keyframes
允许定义动画序列的关键帧。animation
属性应用动画效果,定义动画名称、持续时间、延迟时间等。
-
字体特性:
- 可以使用
font-family
、font-size
、font-weight
等属性控制文本的字体、大小和粗细。
- 可以使用
-
2D和3D转换 (
transform
):transform
属性允许元素进行旋转、缩放、平移、倾斜等变换,包括3D变换。
这些CSS3新特性使得开发者能够更加精确地控制和设计网页的外观和交互效果,提升了用户体验和开发效率。
【5】如何让一个盒子在页面垂直水平居中(掌握)
.container {
position: absolute; /* 使用绝对定位 */
top: 50%; /* 顶部偏移50% */
left: 50%; /* 左侧偏移50% */
transform: translate(-50%, -50%); /* 使用负的50%的translate来修正位置 */
}
【6】如何实现响应式布局
实现响应式布局通常涉及使用CSS媒体查询和灵活的布局技术。以下是实现响应式布局的一般步骤和一些常见的方法:
1. 使用Viewport单位
Viewport单位(如vw
,vh
,vmin
,vmax
)可以根据视口的尺寸进行调整,有助于创建相对于屏幕大小的布局。
.container {
width: 100vw; /* 相对于视口宽度100% */
height: 100vh; /* 相对于视口高度100% */
}
2. 弹性布局(Flexbox)
Flexbox 是一种强大的布局模型,特别适合响应式设计,可以轻松地实现灵活的布局排列。
.container {
display: flex;
justify-content: center; /* 水平居中 */
align-items: center; /* 垂直居中 */
}
3. 栅格系统
使用栅格系统(如Bootstrap的栅格系统)可以在不同屏幕尺寸上定义不同的布局。
<div class="row">
<div class="col-sm-6 col-md-4">内容</div>
<div class="col-sm-6 col-md-4">内容</div>
<div class="col-sm-6 col-md-4">内容</div>
</div>
4. 媒体查询
媒体查询允许根据设备的特定特征(如宽度、高度、设备类型等)应用不同的CSS样式。
/* 当屏幕宽度小于768px时应用的样式 */
@media (max-width: 768px) {
.container {
width: 100%; /* 宽度100% */
padding: 10px; /* 边距增加 */
}
}
5. CSS Grid
CSS Grid 是一种强大的布局系统,可以创建复杂的网格布局,非常适合于大规模的响应式设计。
.container {
display: grid;
grid-template-columns: 1fr 1fr; /* 两列布局 */
gap: 10px; /* 间隙 */
}
@media (max-width: 768px) {
.container {
grid-template-columns: 1fr; /* 单列布局 */
}
}
【7】css画三角形,n种方法
/* 创建一个带有 id="triangle" 的 div 元素 */
#triangle {
width: 0; /* 设置宽度为0 */
height: 0; /* 设置高度为0 */
border-left: 50px solid transparent; /* 左边框为透明,宽度50px */
border-right: 50px solid transparent; /* 右边框为透明,宽度50px */
border-bottom: 100px solid blue; /* 底部边框为实体,高度100px,颜色为蓝色 */
}
解释:
-
width: 0;
和height: 0;
:将元素的宽度和高度都设置为0,这是为了让元素不占据空间,实际上我们将依赖边框来绘制三角形。 -
border-left: 50px solid transparent;
:设置左边框为宽度为50px的透明边框。这个边框将会成为三角形的左侧斜边。 -
border-right: 50px solid transparent;
:设置右边框为宽度为50px的透明边框。这个边框将会成为三角形的右侧斜边。 -
border-bottom: 100px solid blue;
:设置底部边框为宽度为100px的实体边框,颜色为蓝色。这个边框将会成为三角形的底边。
# JavaScript
【1】事件冒泡和事件捕获到底有何区别?(掌握)
1.事件冒泡:从下至上。当给父子元素的同一事件绑定方法的时候,触发子元素身上的事件,执行完毕之后,也会触发父级元素相同的事件。
**注意: addEventListener中有三个属性,第三个属性是布尔值。false为事件冒泡,true为事件捕获**
2.事件捕获:从上至下到指定元素。当触发子元素身上的事件时,先触发父元素,然后在传递给子元素
【2】什么是闭包?为什么要用它?(掌握)
闭包(Closure)是指函数和声明该函数的词法环境的组合。闭包可以让函数访问在其声明外部的变量,即使在函数返回后,这些变量依然可以被访问和操作。闭包在许多编程语言中都是一个重要的概念,特别是在函数式编程和 JavaScript 中尤为常见。
function outerFunction() {
let outerVariable = "I'm outside!";
function innerFunction() {
console.log(outerVariable); // innerFunction可以访问outerFunction中定义的outerVariable
}
return innerFunction; // 返回内部函数
}
const closureExample = outerFunction(); // 调用外部函数,将其返回的内部函数赋值给closureExample
closureExample(); // 执行内部函数,输出 "I'm outside!"
解释:
-
outerFunction:外部函数定义了一个局部变量
outerVariable
和一个内部函数innerFunction
。 -
innerFunction:内部函数
innerFunction
定义在outerFunction
中,并且可以访问outerFunction
中的所有变量,包括outerVariable
。 -
return innerFunction:
outerFunction
返回了innerFunction
,这个返回的innerFunction
形成了一个闭包,它包含了outerFunction
的作用域链(词法环境)。 -
const closureExample = outerFunction();:调用
outerFunction
,并将返回的innerFunction
赋值给closureExample
。此时closureExample
成为了一个闭包,它保持了对outerVariable
的引用。 -
closureExample():通过调用
closureExample()
,实际上执行了innerFunction
。由于闭包的存在,innerFunction
可以继续访问和操作outerVariable
,即使outerFunction
已经执行完毕。
闭包使得 JavaScript 可以实现许多高级的编程模式,例如函数工厂、模块模式和私有变量等。理解闭包对于掌握 JavaScript 的高级特性和编程技巧是非常重要的。
【3】请描述一下 cookies,sessionStorage 和 localStorage 的区别?
Cookies、sessionStorage 和 localStorage 都是用于在浏览器端存储数据的机制,但它们在使用场景、存储大小、生命周期和安全性等方面有所不同。以下是它们的区别以及示例代码:
Cookies
- 存储大小: 最多可以存储4KB的数据。
- 生命周期: 可以设置过期时间,如果不设置,默认是会话级别的(浏览器关闭时失效)。
- 安全性: 可以设置为HttpOnly,防止被JavaScript访问,从而提高安全性。
-
// 设置一个cookie document.cookie = "username=John Doe; expires=Thu, 18 Dec 2023 12:00:00 UTC; path=/";
sessionStorage
- 存储大小: 最多可以存储5MB的数据。
- 生命周期: 存储在浏览器的会话期间,页面重新加载或恢复时仍然有效,但关闭标签页或浏览器时会被清除。
- 安全性: 数据仅在同一浏览器窗口(或标签页)中可用,不同标签页或窗口之间的数据不共享。
// 存储数据到sessionStorage sessionStorage.setItem("username", "John Doe"); // 从sessionStorage中获取数据 let username = sessionStorage.getItem("username");
localStorage
- 存储大小: 最多可以存储5MB的数据。
- 生命周期: 数据会永久存储在浏览器中,除非通过JavaScript或用户手动删除。
- 安全性: 数据在同一浏览器的所有窗口中都是共享的,不同标签页或窗口之间可以共享数据。
// 存储数据到localStorage
localStorage.setItem("username", "John Doe");
// 从localStorage中获取数据
let username = localStorage.getItem("username");
【4】什么是防抖和节流?有什么区别?如何实现?(掌握)
防抖(Debounce)和节流(Throttle)都是用来限制某个函数的执行频率,特别是在处理用户输入或者频繁触发事件时非常有用。
防抖(Debounce)
防抖的基本思想是,在事件被触发后等待一段时间,如果在这段时间内没有再次触发该事件,则执行函数;如果在这段时间内再次触发了该事件,则重新计时。
function debounce(func, delay) {
let timeoutId;
return function(...args) {
const context = this;
clearTimeout(timeoutId);
timeoutId = setTimeout(() => {
func.apply(context, args);
}, delay);
};
}
// 使用防抖处理一个输入框输入事件的例子
const inputHandler = debounce(function(event) {
console.log("Input value:", event.target.value);
}, 300); // 300毫秒的延迟
document.getElementById('myInput').addEventListener('input', inputHandler);
在上面的例子中,debounce
函数接收一个函数 func
和一个延迟时间 delay
,返回一个新函数,该函数会在最后一次调用后等待 delay
毫秒后执行原始函数 func
。
节流(Throttle)
节流的基本思想是在一定时间间隔内只触发一次函数执行。无论事件触发频率多高,都会按照固定频率执行。
function throttle(func, delay) {
let lastExecTime = 0;
return function(...args) {
const context = this;
const currentTime = Date.now();
if (currentTime - lastExecTime >= delay) {
func.apply(context, args);
lastExecTime = currentTime;
}
};
}
// 使用节流处理一个滚动事件的例子
const scrollHandler = throttle(function(event) {
console.log("Scroll top:", window.scrollY);
}, 100); // 100毫秒的间隔
window.addEventListener('scroll', scrollHandler);
在这个例子中,throttle
函数接收一个函数 func
和一个间隔时间 delay
,返回一个新函数,该函数会在每个 delay
毫秒内最多执行一次原始函数 func
。
# 小程序
【1】小程序登录流程
小程序的登录流程通常涉及以下几个步骤,并且在实现上可能会涉及到使用微信提供的 API(如 wx.login
)来获取用户的登录凭证 code
,然后使用这个 code
向自己的服务器发送请求,完成登录验证和用户信息获取。
1. 获取用户登录凭证 code
在小程序中,使用 wx.login
方法获取用户登录凭证 code
,该 code
用于后续向服务器换取用户的唯一标识 openid
和会话密钥 session_key
。
wx.login({
success: function(res) {
if (res.code) {
// 将 res.code 发送给后端服务器
} else {
console.log('登录失败!' + res.errMsg)
}
}
});
2. 后端服务器获取 openid 和 session_key
将前一步获取到的 code
发送到自己的后端服务器。后端服务器收到 code
后,调用微信的接口(例如 https://api.weixin.qq.com/sns/jscode2session
)换取用户的 openid
和 session_key
。
示例请求:
GET https://api.weixin.qq.com/sns/jscode2session?appid=YOUR_APPID&secret=YOUR_SECRET&js_code=JSCODE&grant_type=authorization_code
其中:
appid
:小程序的 AppIDsecret
:小程序的 AppSecretjs_code
:前一步获取的code
grant_type
:固定为authorization_code
3. 后端服务器处理并返回用户信息
后端服务器收到微信返回的 openid
和 session_key
后,可以根据业务逻辑进行处理,如生成用户的登录态标识(如 token
),将用户信息存储在数据库中,然后返回给小程序端。
4. 小程序端保存登录态
小程序端接收到后端返回的用户信息后,可以将用户的登录态信息保存在本地(如 Storage
),以便在用户下次打开小程序时,可以根据这些信息判断用户是否登录,并实现相应的功能。
5. 用户授权和信息获取(可选)
如果需要获取用户的头像、昵称等信息,可以引导用户进行授权,使用 button
组件来触发 getUserInfo
方法获取用户信息,并将信息发送给后端服务器进行存储或其他操作。
【2】静默登录和非静默登录
静默登录和非静默登录是两种不同的用户登录方式,主要区别在于用户交互和权限获取的方式。
静默登录
静默登录指的是在不需要用户交互的情况下,通过已有的登录凭证(如微信小程序的 code
)直接获取用户信息的方式。
// 小程序端静默登录示例代码
// 使用 wx.login 获取用户登录凭证 code
wx.login({
success: function(res) {
if (res.code) {
// 将 code 发送给后端服务器进行处理
wx.request({
url: 'https://your-server.com/login',
method: 'POST',
data: {
code: res.code
},
success: function(response) {
// 后端返回用户信息,保存到本地存储
const userInfo = response.data.userInfo;
wx.setStorageSync('userInfo', userInfo);
console.log('静默登录成功', userInfo);
},
fail: function(error) {
console.error('静默登录失败', error);
}
});
} else {
console.error('登录失败!' + res.errMsg);
}
}
});
注释说明:
wx.login
:调用微信登录接口,获取用户的登录凭证code
。- 后端请求:将获取到的
code
发送到后端服务器,后端根据code
调用微信接口获取用户的openid
和session_key
,然后进行业务逻辑处理,返回用户信息。 wx.setStorageSync
:将后端返回的用户信息保存在小程序的本地存储中,以便下次使用。
非静默登录
非静默登录通常需要用户的主动操作,例如用户点击按钮授权获取更多的个人信息。
// 小程序端非静默登录示例代码
// 用户点击按钮触发获取用户信息的操作
wx.getUserInfo({
success: function(res) {
const userInfo = res.userInfo;
// 将 userInfo 发送给后端服务器进行处理
wx.request({
url: 'https://your-server.com/login',
method: 'POST',
data: {
userInfo: userInfo
},
success: function(response) {
// 后端返回用户信息,保存到本地存储
wx.setStorageSync('userInfo', userInfo);
console.log('非静默登录成功', userInfo);
},
fail: function(error) {
console.error('非静默登录失败', error);
}
});
},
fail: function(error) {
console.error('获取用户信息失败', error);
}
});
注释说明:
wx.getUserInfo
:调用微信获取用户信息接口,用户需要确认授权才能获取。- 后端请求:将获取到的用户信息发送到后端服务器进行处理,后端根据业务逻辑进行处理和返回。
wx.setStorageSync
:将后端返回的用户信息保存在小程序的本地存储中。
【3】小程序生命周期
App({
// 小程序初始化时触发,全局只触发一次
onLaunch: function(options) {
// options 可以获取小程序打开时的参数,如路径、query、场景值等
console.log('App Launch', options);
},
// 小程序启动或从后台进入前台时触发
onShow: function(options) {
// options 可以获取小程序启动场景,如路径、query、场景值等
console.log('App Show', options);
},
// 小程序从前台进入后台时触发
onHide: function() {
console.log('App Hide');
},
// 小程序发生错误时触发
onError: function(error) {
console.error('App Error', error);
}
})
Page({
// 页面被加载时触发
onLoad: function(options) {
// options 可以获取页面跳转所带来的参数
console.log('Page Load', options);
},
// 页面显示时触发
onShow: function() {
console.log('Page Show');
},
// 页面初次渲染完成时触发
onReady: function() {
console.log('Page Ready');
},
// 页面隐藏时触发
onHide: function() {
console.log('Page Hide');
},
// 页面卸载时触发
onUnload: function() {
console.log('Page Unload');
},
// 页面触发下拉刷新时触发
onPullDownRefresh: function() {
console.log('Page Pull Down Refresh');
},
// 页面触底时触发
onReachBottom: function() {
console.log('Page Reach Bottom');
},
// 页面分享时触发
onShareAppMessage: function() {
console.log('Page Share');
return {
title: '分享标题',
path: '/page/path?id=123'
};
},
// 页面滚动时触发
onPageScroll: function(scroll) {
console.log('Page Scroll', scroll);
},
// 页面尺寸改变时触发,如横竖屏切换
onResize: function(size) {
console.log('Page Resize', size);
}
})
【4】小程序常用API
1. 获取用户信息
// 调用登录接口
wx.login({
success: function(loginRes) {
// 获取用户信息
wx.getUserInfo({
success: function(userRes) {
var userInfo = userRes.userInfo;
var nickName = userInfo.nickName;
var avatarUrl = userInfo.avatarUrl;
var gender = userInfo.gender; // 性别 0:未知、1:男、2:女
var province = userInfo.province;
var city = userInfo.city;
var country = userInfo.country;
}
});
}
});
2. 发起网络请求
wx.request({
url: 'https://api.example.com/data',
method: 'GET',
data: {
id: '123',
name: 'example'
},
header: {
'content-type': 'application/json'
},
success: function(res) {
console.log(res.data);
},
fail: function(err) {
console.error('请求失败:', err);
}
});
3. 调用本地存储 API
// 保存数据到本地缓存
wx.setStorageSync('key', 'value');
// 从本地缓存中同步获取指定 key 对应的内容
var data = wx.getStorageSync('key');
console.log(data);
4. 弹窗交互
// 显示模态弹窗
wx.showModal({
title: '提示',
content: '这是一个模态弹窗',
success: function(res) {
if (res.confirm) {
console.log('用户点击确定');
} else if (res.cancel) {
console.log('用户点击取消');
}
}
});
5. 图片相关操作
// 预览图片
wx.previewImage({
urls: ['https://example.com/image1.jpg', 'https://example.com/image2.jpg'],
current: 'https://example.com/image1.jpg' // 当前显示图片的链接
});
// 选择图片并上传
wx.chooseImage({
count: 1,
sizeType: ['original', 'compressed'],
sourceType: ['album', 'camera'],
success: function(res) {
var tempFilePaths = res.tempFilePaths;
// 上传逻辑
}
});
【7】小程序包超过2M怎么处理
当小程序包超过了2MB大小限制时,可以考虑以下几种处理方法来优化和减少包的大小:
1. 图片优化
- 压缩图片:使用工具如 TinyPNG 等在线工具或插件,压缩图片以减少图片文件大小。
- 使用适当的图片格式:选择合适的图片格式,如 JPEG 对于照片,PNG 对于透明图像,以在不影响质量的情况下减少文件大小。
- 减少不必要的图片:移除不必要的图片或者通过 CDN 动态加载图片,减少初始加载时的图片体积。
2. 代码优化
- 精简代码:去除不必要的注释、空格和代码行,减少代码体积。
- 使用 ES6+ 特性:利用 ES6+ 的语法特性,它们通常比传统的 JavaScript 语法更紧凑。
- 分包加载:考虑将不同页面的代码进行分包,使得初始加载的主包大小减小。
3. 功能优化
- 按需加载:延迟加载不是初始必需的功能或页面,通过动态引入或分包加载来优化初始加载时的包大小。
- 移除不必要的功能:评估并移除不常用或不必要的功能,以减少小程序包的体积。
4. 资源管理
- 使用小程序云开发:将一些数据或资源存储在小程序的云端,减少本地资源的包含。
- CDN 加速:将一些静态资源如图片、视频等存储在 CDN 上,提高资源加载速度,同时减少小程序包的体积。
5. 性能分析与测试
- 使用开发者工具分析:利用微信开发者工具的性能分析功能,查看哪些资源或代码占用了较多空间。
- 设备适配优化:考虑不同设备的适配性,以免因为资源过多导致性能下降或加载时间延长。
通过这些优化措施,可以有效地减少小程序包的大小,提升用户的使用体验和加载速度。
# Vue
【1】能说下 vue-router 中常用的路由模式实现原理吗
hash模式: 运用了html的瞄点功能 改变了#后的路径 也就是改变了当前页面的瞄点 不会刷新页面 通过监听浏览器的onhashchange()事件变化 来查找对应的路由规则
(访问路径上包含# 不美观 改变#后面的路径不会自动刷新页面 减少了http请求)
history模式: 利用H5中history里新增的两个API:pushState和replaceState() 和onpopstate事件来监听URL变化
(访问路径上没有# 使用起来比较美观,后端可以获取到完整的路由信息)
【2】vue常用的修饰符?
.stop: 阻止单击事件冒泡;
.once: 点击事件将只触发一次
.keyup: 键盘抬起
.keydowm: 键盘按下
.prevent: 提交事件不会重新加载页面 可以用来阻止表单提交的默认行为
【3】vue中v-if与v-show的区别以及使用场景
v-if是通过控制dom节点的显示与隐藏的;v-show是通过设置DOM元素的displa为block还是为none来控制显示隐藏的,v-if有更高的切换消耗 v-show有着更高的初始渲染消耗 所以频繁的切换还是用v-show比较好
【4】v-if和v-for为什么避免一起用
因为v-for的优先级要高于v-if,会造成选循环再显示隐藏的效果,对于性能方面有些浪费
【5】Vue.set 方法使用
Vue.set(操作的对象,操作的属性,属性值)
在 Vue.js 中,通常使用 Vue.set
方法来在响应式对象上添加响应式属性。这在你需要动态添加属性时非常有用,因为直接通过赋值添加新属性时,Vue 不能自动追踪这些变化。以下是一个示例代码,并附带详细的注释说明:
<template>
<div>
<p>{{ user.name }}</p>
<button @click="addAge">增加年龄</button>
</div>
</template>
<script>
export default {
data() {
return {
user: {
name: 'Alice',
age: 30
}
};
},
methods: {
addAge() {
// 使用 Vue.set 添加响应式属性
Vue.set(this.user, 'age', this.user.age + 1);
}
}
};
</script>
<style>
/* 样式 */
</style>
【6】多层父子组件通讯
在 Vue.js 2.x 中,父子组件之间的通信可以通过 props 属性、事件以及使用 Vuex 进行状态管理来实现。下面我会给出几种常见的多层父子组件通信的代码示例。
1. 使用 Props 和事件
父组件向子组件传递数据并监听子组件的事件:
<!-- ParentComponent.vue -->
<template>
<div>
<ChildComponent :message="parentMessage" @childEvent="handleChildEvent" />
</div>
</template>
<script>
import ChildComponent from './ChildComponent.vue';
export default {
components: {
ChildComponent
},
data() {
return {
parentMessage: 'Hello from Parent'
};
},
methods: {
handleChildEvent(payload) {
console.log('Received from child:', payload);
}
}
};
</script>
<!-- ChildComponent.vue -->
<template>
<div>
<p>{{ message }}</p>
<button @click="sendToParent">Send to Parent</button>
</div>
</template>
<script>
export default {
props: ['message'],
methods: {
sendToParent() {
this.$emit('childEvent', 'Message from Child');
}
}
};
</script>
2. 使用 Vuex 进行状态管理
设置 Vuex 状态,实现多层组件通信:
// store/index.js
import Vue from 'vue';
import Vuex from 'vuex';
Vue.use(Vuex);
export default new Vuex.Store({
state: {
message: 'Hello from Vuex'
},
mutations: {
updateMessage(state, payload) {
state.message = payload;
}
},
actions: {
setMessage({ commit }, payload) {
commit('updateMessage', payload);
}
}
});
<!-- ParentComponent.vue -->
<template>
<div>
<ChildComponent />
</div>
</template>
<script>
import ChildComponent from './ChildComponent.vue';
export default {
components: {
ChildComponent
}
};
</script>
<!-- ChildComponent.vue -->
<template>
<div>
<p>{{ message }}</p>
<button @click="sendToVuex">Update Vuex State</button>
</div>
</template>
<script>
import { mapState, mapActions } from 'vuex';
export default {
computed: {
...mapState(['message'])
},
methods: {
...mapActions(['setMessage']),
sendToVuex() {
this.setMessage('New Message from Child');
}
}
};
</script>
【7】Vuex刷新页面数据丢失怎么解决?
当页面刷新后,Vuex 状态数据丢失的问题通常可以通过以下几种方法来解决:
1. 使用持久化方案
Vuex 持久化插件: 你可以使用 Vuex 的持久化插件,如 vuex-persistedstate
,它可以将 Vuex 的状态持久化到本地存储(如 localStorage 或 sessionStorage),从而在页面刷新后能够重新加载这些状态数据。
安装 vuex-persistedstate
:
npm install vuex-persistedstate
在 Vuex 的 store/index.js 中配置持久化插件:
import Vue from 'vue';
import Vuex from 'vuex';
import createPersistedState from 'vuex-persistedstate';
Vue.use(Vuex);
export default new Vuex.Store({
// state, mutations, actions...
plugins: [createPersistedState()]
});
2. 利用浏览器的 sessionStorage 或 localStorage
直接利用浏览器提供的 sessionStorage 或 localStorage 进行状态存储,这种方法比较简单,但需要注意安全性和存储容量。
在 Vuex 的 mutations 中进行本地存储:
// store/index.js
import Vue from 'vue';
import Vuex from 'vuex';
Vue.use(Vuex);
export default new Vuex.Store({
state: {
// initial state...
},
mutations: {
updateSomeData(state, newData) {
state.someData = newData;
localStorage.setItem('vuexState', JSON.stringify(state));
}
},
actions: {
// actions...
},
getters: {
// getters...
}
});
在页面加载时恢复状态:
// main.js or App.vue
import store from './store';
const savedState = localStorage.getItem('vuexState');
if (savedState) {
store.replaceState(Object.assign({}, store.state, JSON.parse(savedState)));
}
3. 使用后端存储和恢复方案
如果你的应用需要跨会话或设备保留状态,则可以考虑在后端存储用户的状态数据,并在需要时恢复。
【8】简单讲述vuex
Vuex 是一个专为 [Vue](https://so.csdn.net/so/search?q=Vue&spm=1001.2101.3001.7020).js 应用程序开发的状态管理模式。
1.state:vuex的基本数据,用来存储变量
2.getters:从基本数据(state)派生的数据,相当于state的计算属性
3.mutation:提交更新数据的方法,必须是同步的(如果需要异步使用action)。每个mutation 都有一个字符串的 事件类型 (type) 和 一个 回调函数 (handler)。回调函数就是我们实际进行状态更改的地方,并且它会接受 state 作为第一个参数,提交载荷作为第二个参数
4.action:和mutation的功能大致相同,不同之处在于 Action 提交的是 mutation,而不是直接变更状态,可以包含任意异步操作
5.modules:模块化vuex,可以让每一个模块拥有自己的state、mutation、action、getters,使得结构非常清晰,方便管理
vuex就是多个组件 共享一个数据的状态管理工具 他是响应式的
【9】`$route` 和 `$router` 的区别
$router 携带的时路径信息 是用来跳转页面的
$route 路由信息 主要是用来获取参数
【10】Computed和Watch
在Vue.js中,computed
和watch
是两种不同的响应式数据处理方式,它们可以用来监听数据变化并执行相应的逻辑。以下是它们的区别和如何在代码中使用它们:
Computed 属性
1. 特点:
computed
属性是基于它们的依赖进行缓存的。- 只有当依赖项发生改变时,它们才会重新计算。
computed
属性应该被视为只读属性,因为它们的值是根据依赖项计算得出的。
2. 适用场景:
- 当某个数据需要根据其他数据计算得出,并且这个数据不依赖于用户的直接操作时,可以使用
computed
属性。 - 典型的应用包括对数据进行过滤、格式化或者计算统计值等。
3. 示例代码:
<template>
<div>
<p>原始消息: {{ message }}</p>
<p>反转消息: {{ reversedMessage }}</p>
</div>
</template>
<script>
export default {
data() {
return {
message: 'Hello',
};
},
computed: {
reversedMessage() {
// 通过计算得到反转的消息
return this.message.split('').reverse().join('');
},
},
};
</script>
在上面的示例中,reversedMessage
是一个computed
属性,它依赖于message
,但只有在message
改变时才会重新计算。
Watch 监听器
1. 特点:
watch
是一个侦听器,用于响应数据的变化。- 当数据变化时,执行自定义的回调函数。
2. 适用场景:
- 当需要在数据变化时执行异步或复杂逻辑时,可以使用
watch
。 - 典型的应用包括对数据的深度监听、使用
API
异步获取数据等。
3. 示例代码:
<template>
<div>
<p>当前计数: {{ count }}</p>
<button @click="increment">增加</button>
</div>
</template>
<script>
export default {
data() {
return {
count: 0,
};
},
watch: {
count(newValue, oldValue) {
console.log(`计数从 ${oldValue} 变为 ${newValue}`);
// 在这里可以执行更复杂的逻辑,如异步操作或其他数据处理
},
},
methods: {
increment() {
this.count++;
},
},
};
</script>