vue基础知识


vue

路由懒加载

当打包构建应用时,JavaScript 包会变得非常大,影响页面加载。如果我们能把不同路由对应的组件分割成不同的代码块,然后当路由被访问的时候才加载对应组件,这样就会更加高效。

Vue Router 支持开箱即用的动态导入,这意味着你可以用动态导入代替静态导入:

1
2
3
4
5
6
7
8
9
10
11
12
13
// 将
// import UserDetails from './views/UserDetails.vue'
// 替换成
const UserDetails = () => import('./views/UserDetails.vue')

const router = createRouter({
// ...
routes: [
{ path: '/users/:id', component: UserDetails }
// 或在路由定义里直接使用它
{ path: '/users/:id', component: () => import('./views/UserDetails.vue') },
],
})

component (和 components) 配置接收一个返回 Promise 组件的函数,Vue Router 只会在第一次进入页面时才会获取这个函数,然后使用缓存数据。这意味着你也可以使用更复杂的函数,只要它们返回一个 Promise :

1
2
3
4
const UserDetails = () =>
Promise.resolve({
/* 组件定义 */
})

HashRouter和 HistoryRouter的区别和原理?

hashRouter原理

  • HashRouter 使用 URL 的哈希(即 # 符号后面的部分)来模拟完整的 URL 路径。
  • 当哈希值改变时(例如从 #home 变为 #about),页面不会重新加载。相反,这种变化可以通过 JavaScript 捕捉到,并且可以用来动态地加载视图而不刷新页面。
  • 哈希变化不会导致浏览器向服务器发送请求,因为哈希永远不会被包括在 HTTP 请求中。

使用场景

不支持HTML5,适合老的浏览器

适用那些不需要SEO的

HistoryRouter原理

  • HistoryRouter 利用 HTML5 的 History API 来维护浏览历史记录和 URL 的变化
  • 使用 pushStatereplaceState 方法和 popstate 事件来实现 URL 的变化而不重新加载页面。
  • 当这些方法被调用时,它们会改变浏览器的 URL 地址栏,但不会发送请求到服务器。

两者区别

url格式:HashRouter包括#符号,HistoryRouter:不带

服务器配置:HashRouter不需要特殊的服务器配置,因为 URL 的哈希部分永远不会发送到服务器。HistoryRouter 需要服务器对所有可能的路由请求返回同一个 HTML 文件,否则用户直接访问http://example.com/about 可能会导致 404 错误,除非服务器特别配置了路由规则。

浏览器兼容:hashRouter:在所有浏览器中都能工作,historyRouter:需要浏览器支持

SEO:前者不利于搜索,后者有利于

Vue2.0 双向绑定的原理与缺陷?

Vue 2.0 使用 Object.defineProperty 来实现响应式系统。这个方法允许对一个对象的属性进行拦截,当属性被访问或修改时,Vue 可以捕捉到这些变化并做出相应的响应,如视图更新。

  1. 响应式对象
    • Vue 在初始化实例时对 data 对象的属性执行递归遍历,使用 Object.defineProperty 将它们转化为 getter/setter,并收集依赖(即数据与视图之间的依赖关系),这是其双向绑定的核心。
  2. 依赖收集
    • 当渲染函数被执行时,会读取到使用的属性,属性的 getter 函数就会执行。在 getter 函数中,会将当前的 watcher(观察者,即依赖)添加到这个属性的依赖列表中。
  3. 派发更新
    • 当属性的值发生变化时,setter 会被调用,它会通知所有依赖于该属性的 watcher 对象,执行它们的 update 方法,引起视图的重新渲染。

缺陷:

新增或删除属性:Vue 2.0 不能检测到对象属性的添加或删除。因此,如果你需要在对象上添加新的属性,需要使用 Vue.set 或者 this.$set 方法。

Vue3.0 实现数据双向绑定的方法?

原理:

Vue 3.0 引入了 Composition API 和使用 Proxy 对象来实现响应式系统,这是一种更为高效和强大的方式。

  1. Proxy
    • Vue 3.0 使用 Proxy 对象包裹 data 对象,可以拦截对象的任意属性的读取和修改操作,包括属性添加和删除等操作。
    • Proxy 可以监听动态添加的属性和删除的属性,也可以监听数组索引和长度的变化。
  2. Reactivity API
    • Vue 3.0 提供了 reactive, ref, 和 computed 等 API 来创建响应式数据。
    • reactive 用于创建响应式对象,ref 用于创建响应式的基本类型值。

react

React生命周期的各个阶段是什么?

初始化阶段

    • constructor(): 构造函数,用于初始化组件的状态。
    • static getDerivedStateFromProps(): 接收新的 props 和旧的 state,返回一个对象来更新 state,或者返回 null 表示不需要更新。
    • render(): 渲染组件,返回一个 React 元素。

更新阶段

  • shouldComponentUpdate(): 接收新的 props 和 state,返回一个布尔值来决定是否需要重新渲染组件。
  • static getSnapshotBeforeUpdate(): 在组件更新之前(DOM 更新之前)调用,可以返回一个值,该值会在 componentDidUpdate 中作为参数传入。

渲染输出阶段

  • render(): 组件的输出,返回一个 React 元素。

卸载阶段

  • componentWillUnmount(): 组件卸载之前调用,用于清理工作,如定时器、事件监听器等。

挂载后阶段

  • componentDidMount(): 组件挂载(即添加到 DOM 后)之后立即调用,常用于执行 DOM 操作、发起网络请求等。

更新后阶段

  • componentDidUpdate(): 组件更新后调用,可以访问最新的 props 和 state,用于执行依赖于 DOM 的操作。

错误处理阶段

  • static getDerivedStateFromError(): 接收一个错误参数,返回一个对象来更新 state,或者返回 null 表示不需要更新。
  • componentDidCatch(): 接收一个错误参数和一个信息对象,信息对象包含组件堆栈等,用于错误边界的异常处理。

函数组件

,生命周期主要由 React Hooks 提供:

  1. 初始化
    • 使用 useState 来定义状态。
  2. 依赖项获取
    • 使用 useEffect 来处理副作用和生命周期。
  3. 更新
    • useEffect 的第二个参数可以指定依赖项列表,当依赖项变化时触发更新。
  4. 卸载
    • useEffect 中返回一个清理函数,用于组件卸载时执行清理操作。

ReactRouter基本用法是什么?

用LInk组件创建

1
2
3
4
5
6
7
8
9
10
11
import { Link } from 'react-router-dom';

function Navigation() {
return (
<nav>
<Link to="/">Home</Link>
<Link to="/about">About</Link>
<Link to="/contact">Contact</Link>
</nav>
);
}

使用Navigate组件

1
2
3
4
5
import { Navigate } from 'react-router-dom';

function RedirectToHome() {
return <Navigate to="/" replace />;
}

动态路由

1
<Route path="/users/:userId" element={<UserProfile />} />

保护路由

你可以使用 Navigate 组件来重定向未授权的用户:

1
2
3
4
<Route
path="/protected"
element={user.isAuthenticated ? <Protected /> : <Navigate to="/login" replace />}
/>

嵌套路由:

一层层路由嵌套

使用Outlet等等

React组件间传值的方法有哪些?

Props 传递:常见

提升状态

  • 将状态提升到共同的父组件中,然后通过props将其传递给需要它的子组件。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// 父组件
class ParentComponent extends React.Component {
state = { sharedValue: 'some value' };

render() {
return (
<>
<ComponentA value={this.state.sharedValue} />
<ComponentB value={this.state.sharedValue} />
</>
);
}
}

// 子组件
function ComponentA(props) {
return <div>{props.value}</div>;
}

function ComponentB(props) {
return <div>{props.value}</div>;
}

Context API

  • 当你想要跨多层组件传递数据时,可以使用Context API,它提供了一种方式,可以跨层级提供和访问数据。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
const MyContext = React.createContext(defaultValue);

function App() {
return (
<MyContext.Provider value="some value">
<ComponentA />
</MyContext.Provider>
);
}

function ComponentA() {
return (
<MyContext.Consumer>
{value => <ComponentB value={value} />}
</MyContext.Consumer>
);
}

function ComponentB(props) {
return <div>{props.value}</div>;
}

状态管理库:

  • 使用如 Redux、MobX、Zustand 等状态管理库来管理跨组件的状态。

Refs

  • 使用Refs在组件间直接访问DOM节点或组件实例。

回调函数之类


文章作者: 悠然寂夏
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 悠然寂夏 !
评论
评论
评论
  目录