Vue의 내장 구성 요소인 연결 유지에 대한 이해에 대해 이야기해 보겠습니다.
연결 유지란 무엇인가요? 다음 기사에서는 vue 내장 구성 요소 연결 유지에 대한 이해에 대해 설명하겠습니다. 도움이 되기를 바랍니다.
1. Keep-alive란 무엇입니까
keep-alive
는 vue
에 내장된 구성 요소로 구성 요소 전환 중에 상태를 유지할 수 있습니다. . 메모리에서 DOM
의 반복 렌더링을 방지합니다. [관련 권장사항: vuejs 비디오 튜토리얼keep-alive
是vue
中的内置组件,能在组件切换过程中将状态保留在内存中,防止重复渲染DOM
。【相关推荐:vuejs视频教程、web前端开发】
keep-alive
包裹动态组件时,会缓存不活动的组件实例,而不是销毁它们。
keep-alive
可以设置以下props
属性:
-
include
- 字符串或正则表达式。只有名称匹配的组件会被缓存 -
exclude
- 字符串或正则表达式。任何名称匹配的组件都不会被缓存 -
max
- 数字。最多可以缓存多少组件实例
关于keep-alive
的基本用法:
<keep-alive> <component :is="view"></component> </keep-alive>
使用includes
和exclude
:
<keep-alive include="a,b"> <component :is="view"></component> </keep-alive> <!-- 正则表达式 (使用 `v-bind`) --> <keep-alive :include="/a|b/"> <component :is="view"></component> </keep-alive> <!-- 数组 (使用 `v-bind`) --> <keep-alive :include="['a', 'b']"> <component :is="view"></component> </keep-alive>
匹配首先检查组件自身的 name
选项,如果 name
选项不可用,则匹配它的局部注册名称 (父组件 components
选项的键值),匿名组件不能被匹配
设置了 keep-alive 缓存的组件,会多出两个生命周期钩子(activated
与deactivated
):
- 首次进入组件时:
beforeRouteEnter
>beforeCreate
>created
>mounted
>activated
> ... ... >beforeRouteLeave
>deactivated
- 再次进入组件时:
beforeRouteEnter
>activated
> ... ... >beforeRouteLeave
>deactivated
二、使用场景
使用原则:当我们在某些场景下不需要让页面重新加载时我们可以使用keepalive
举个栗子:
当我们从首页
–>列表页
–>商详页
–>再返回
,这时候列表页应该是需要keep-alive
从首页
–>列表页
–>商详页
–>返回到列表页(需要缓存)
–>返回到首页(需要缓存)
–>再次进入列表页(不需要缓存)
,这时候可以按需来控制页面的keep-alive
在路由中设置keepAlive
属性判断是否需要缓存
{ path: 'list', name: 'itemList', // 列表页 component (resolve) { require(['@/pages/item/list'], resolve) }, meta: { keepAlive: true, title: '列表页' } }
使用<keep-alive>
<div id="app" class='wrapper'> <keep-alive> <!-- 需要缓存的视图组件 --> <router-view v-if="$route.meta.keepAlive"></router-view> </keep-alive> <!-- 不需要缓存的视图组件 --> <router-view v-if="!$route.meta.keepAlive"></router-view> </div>
三、原理分析
keep-alive
是vue
中内置的一个组件
源码位置:src/core/components/keep-alive.js
export default { name: 'keep-alive', abstract: true, props: { include: [String, RegExp, Array], exclude: [String, RegExp, Array], max: [String, Number] }, created () { this.cache = Object.create(null) this.keys = [] }, destroyed () { for (const key in this.cache) { pruneCacheEntry(this.cache, key, this.keys) } }, mounted () { this.$watch('include', val => { pruneCache(this, name => matches(val, name)) }) this.$watch('exclude', val => { pruneCache(this, name => !matches(val, name)) }) }, render() { /* 获取默认插槽中的第一个组件节点 */ const slot = this.$slots.default const vnode = getFirstComponentChild(slot) /* 获取该组件节点的componentOptions */ const componentOptions = vnode && vnode.componentOptions if (componentOptions) { /* 获取该组件节点的名称,优先获取组件的name字段,如果name不存在则获取组件的tag */ const name = getComponentName(componentOptions) const { include, exclude } = this /* 如果name不在inlcude中或者存在于exlude中则表示不缓存,直接返回vnode */ if ( (include && (!name || !matches(include, name))) || // excluded (exclude && name && matches(exclude, name)) ) { return vnode } const { cache, keys } = this /* 获取组件的key值 */ const key = vnode.key == null // same constructor may get registered as different local components // so cid alone is not enough (#3269) ? componentOptions.Ctor.cid + (componentOptions.tag ? `::${componentOptions.tag}` : '') : vnode.key /* 拿到key值后去this.cache对象中去寻找是否有该值,如果有则表示该组件有缓存,即命中缓存 */ if (cache[key]) { vnode.componentInstance = cache[key].componentInstance // make current key freshest remove(keys, key) keys.push(key) } /* 如果没有命中缓存,则将其设置进缓存 */ else { cache[key] = vnode keys.push(key) // prune oldest entry /* 如果配置了max并且缓存的长度超过了this.max,则从缓存中删除第一个 */ if (this.max && keys.length > parseInt(this.max)) { pruneCacheEntry(cache, keys[0], keys, this._vnode) } } vnode.data.keepAlive = true } return vnode || (slot && slot[0]) } }
可以看到该组件没有template
,而是用了render
,在组件渲染的时候会自动执行render
函数
this.cache
是一个对象,用来存储需要缓存的组件,它将以如下形式存储:
this.cache = { 'key1':'组件1', 'key2':'组件2', // ... }
在组件销毁的时候执行pruneCacheEntry
函数
function pruneCacheEntry ( cache: VNodeCache, key: string, keys: Array<string>, current?: VNode ) { const cached = cache[key] /* 判断当前没有处于被渲染状态的组件,将其销毁*/ if (cached && (!current || cached.tag !== current.tag)) { cached.componentInstance.$destroy() } cache[key] = null remove(keys, key) }
在mounted
钩子函数中观测 include
和 exclude
的变化,如下:
mounted () { this.$watch('include', val => { pruneCache(this, name => matches(val, name)) }) this.$watch('exclude', val => { pruneCache(this, name => !matches(val, name)) }) }
如果include
或exclude
发生了变化,即表示定义需要缓存的组件的规则或者不需要缓存的组件的规则发生了变化,那么就执行pruneCache
函数,函数如下:
function pruneCache (keepAliveInstance, filter) { const { cache, keys, _vnode } = keepAliveInstance for (const key in cache) { const cachedNode = cache[key] if (cachedNode) { const name = getComponentName(cachedNode.componentOptions) if (name && !filter(name)) { pruneCacheEntry(cache, key, keys, _vnode) } } } }
在该函数内对this.cache
对象进行遍历,取出每一项的name
值,用其与新的缓存规则进行匹配,如果匹配不上,则表示在新的缓存规则下该组件已经不需要被缓存,则调用pruneCacheEntry
函数将其从this.cache
对象剔除即可
关于keep-alive
的最强大缓存功能是在render
函数中实现
首先获取组件的key
值:
const key = vnode.key == null? componentOptions.Ctor.cid + (componentOptions.tag ? `::${componentOptions.tag}` : '') : vnode.key
拿到key
值后去this.cache
, 웹 프론트엔드 개발
keep-alive
동적 구성 요소를 래핑할 때 캐시 구성 요소 인스턴스를 파괴하는 대신 비활성 구성 요소 인스턴스가 됩니다. 🎜🎜keep-alive
는 다음 props
속성을 설정할 수 있습니다: 🎜include
- 문자열 또는 정규 표현식. 이름이 일치하는 구성 요소만 캐시됩니다.제외
- 문자열 또는 정규 표현식입니다. 이름이 일치하는 구성요소는 캐시되지 않습니다.max
- 숫자. 캐시할 수 있는 최대 구성 요소 인스턴스 수
keep-alive
의 기본 사용법: 🎜/* 如果命中缓存,则直接从缓存中拿 vnode 的组件实例 */ if (cache[key]) { vnode.componentInstance = cache[key].componentInstance /* 调整该组件key的顺序,将其从原来的地方删掉并重新放在最后一个 */ remove(keys, key) keys.push(key) }
includes
및 exclude 사용
: 🎜/* 如果没有命中缓存,则将其设置进缓存 */ else { cache[key] = vnode keys.push(key) /* 如果配置了max并且缓存的长度超过了this.max,则从缓存中删除第一个 */ if (this.max && keys.length > parseInt(this.max)) { pruneCacheEntry(cache, keys[0], keys, this._vnode) } }
name
옵션을 확인합니다. name
옵션을 사용할 수 없는 경우 로컬 등록 이름(부모)과 일치합니다. 구성 요소 구성 요소</ 코드> 옵션 키 값), 익명 구성 요소는 일치할 수 없습니다. 🎜🎜연결 유지 캐시가 설정된 구성 요소에는 수명 주기 후크가 두 개 더 있습니다(<code>활성화
및 비활성화됨).
): 🎜- 컴포넌트를 처음 입력할 때:
beforeRouteEnter
>beforeCreate
> >탑재됨
> ... ... >비활성화됨
li> - 구성요소를 다시 입력하세요.
beforeRouteEnter
>activated
> ... ... > code>비활성화 li>
🎜2. 사용 시나리오🎜🎜🎜사용 원칙: 페이지를 다시 로드할 필요가 없는 경우 일부 시나리오에서는 keepalive
🎜🎜를 사용할 수 있습니다. 예:🎜🎜홈페이지
–>목록 페이지
–>비즈니스 세부정보 페이지
–>반환
이때 목록 페이지는 홈페이지</code에서 <code>연결 유지
🎜🎜해야 합니다. >–>목록 페이지</code >–><code>비즈니스 세부정보 페이지
–>목록 페이지로 돌아가기(캐싱 필요)
–> 홈페이지로 돌아가기(캐싱 필요)
– >목록 페이지 다시 입력(캐싱 필요 없음)
이때 연결 유지
를 제어할 수 있습니다. > 필요에 따라 페이지의 🎜🎜라우팅 코드에 keepAlive를 설정> 속성은 캐싱이 필요한지 여부를 결정합니다🎜beforeRouteEnter(to, from, next){
next(vm=>{
console.log(vm)
// 每次进入路由执行
vm.getData() // 获取数据
})
},
로그인 후 복사로그인 후 복사🎜<keep-alive>
를 사용하세요🎜activated(){
this.getData() // 获取数据
},
로그인 후 복사로그인 후 복사🎜3. 원리 분석🎜🎜🎜keep -alive
는 vue
🎜🎜에 내장된 구성 요소입니다. 소스 코드 위치: src/core/comComponents/ keep-alive.js🎜rrreee🎜이 구성 요소에는 템플릿
이 없고 대신 렌더링
을 사용하여 자동으로 렌더링</code을 실행하는 것을 볼 수 있습니다. > 컴포넌트가 렌더링될 때의 함수🎜🎜<code>this.cache
는 캐시해야 하는 컴포넌트를 저장하는 데 사용되며 다음 형식으로 저장됩니다. 🎜rrreee🎜 를 실행합니다. 컴포넌트가 소멸될 때 pruneCacheEntry
함수 🎜rrreee🎜 mounted
후크 함수에서 관찰 < code>include
및 exclude
의 변경 사항은 다음과 같습니다. : 🎜rrreee🎜 include
또는 exclude
가 변경되면 정의가 필요하다는 뜻입니다. 캐시된 구성 요소의 규칙이나 캐시할 필요가 없는 구성 요소의 규칙이 변경된 경우 , 그런 다음 pruneCache
함수를 실행합니다. 함수는 다음과 같습니다. 🎜rrreee🎜이 함수에서 this.cache
를 업데이트하고 개체를 트래버스하고 name<을 제거합니다. /code> 값을 사용하여 새 캐싱 규칙을 일치시킵니다. 일치하지 않으면 구성요소가 더 이상 새 캐싱 규칙에 따라 캐시될 필요가 없음을 의미합니다. 그런 다음 <code>pruneCacheEntry<를 호출합니다. /code> 함수를 사용하여 <code>this.cache
개체에서 제거합니다🎜🎜 keep-alive
의 가장 강력한 캐싱 기능은 렌더링</code에 구현되어 있습니다. > function 🎜🎜먼저 구성 요소의 <code>key
값을 가져옵니다. 🎜rrreee🎜 key
값을 가져온 후 this.cache< /code> 개체로 이동하여 이 값이 있는지 확인합니다. 존재하는 경우 구성 요소에 캐시가 있음을 의미합니다. 즉, 다음과 같이 캐시에 도달한다는 의미입니다.<div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class='brush:php;toolbar:false;'>/* 如果命中缓存,则直接从缓存中拿 vnode 的组件实例 */
if (cache[key]) {
vnode.componentInstance = cache[key].componentInstance
/* 调整该组件key的顺序,将其从原来的地方删掉并重新放在最后一个 */
remove(keys, key)
keys.push(key)
}</pre><div class="contentsignin">로그인 후 복사</div></div><div class="contentsignin">로그인 후 복사</div></div><p>直接从缓存中拿 <code>vnode
的组件实例,此时重新调整该组件key
的顺序,将其从原来的地方删掉并重新放在this.keys
中最后一个
beforeRouteEnter(to, from, next){ next(vm=>{ console.log(vm) // 每次进入路由执行 vm.getData() // 获取数据 }) },
<keep-alive>
를 사용하세요🎜activated(){ this.getData() // 获取数据 },
🎜3. 원리 분석🎜🎜🎜keep -alive
는 vue
🎜🎜에 내장된 구성 요소입니다. 소스 코드 위치: src/core/comComponents/ keep-alive.js🎜rrreee🎜이 구성 요소에는 템플릿
이 없고 대신 렌더링
을 사용하여 자동으로 렌더링</code을 실행하는 것을 볼 수 있습니다. > 컴포넌트가 렌더링될 때의 함수🎜🎜<code>this.cache
는 캐시해야 하는 컴포넌트를 저장하는 데 사용되며 다음 형식으로 저장됩니다. 🎜rrreee🎜 를 실행합니다. 컴포넌트가 소멸될 때 pruneCacheEntry
함수 🎜rrreee🎜 mounted
후크 함수에서 관찰 < code>include
this.cache
对象中没有该key
值的情况,如下:
/* 如果没有命中缓存,则将其设置进缓存 */ else { cache[key] = vnode keys.push(key) /* 如果配置了max并且缓存的长度超过了this.max,则从缓存中删除第一个 */ if (this.max && keys.length > parseInt(this.max)) { pruneCacheEntry(cache, keys[0], keys, this._vnode) } }
表明该组件还没有被缓存过,则以该组件的key
为键,组件vnode
为值,将其存入this.cache
中,并且把key
存入this.keys
中
此时再判断this.keys
中缓存组件的数量是否超过了设置的最大缓存数量值this.max
,如果超过了,则把第一个缓存组件删掉
四、思考题:缓存后如何获取数据
解决方案可以有以下两种:
- beforeRouteEnter
- actived
beforeRouteEnter
每次组件渲染的时候,都会执行beforeRouteEnter
beforeRouteEnter(to, from, next){ next(vm=>{ console.log(vm) // 每次进入路由执行 vm.getData() // 获取数据 }) },
actived
在keep-alive
缓存的组件被激活的时候,都会执行actived
钩子
activated(){ this.getData() // 获取数据 },
注意:服务器端渲染期间avtived
不被调用
위 내용은 Vue의 내장 구성 요소인 연결 유지에 대한 이해에 대해 이야기해 보겠습니다.의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

핫 AI 도구

Undresser.AI Undress
사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover
사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool
무료로 이미지를 벗다

Clothoff.io
AI 옷 제거제

Video Face Swap
완전히 무료인 AI 얼굴 교환 도구를 사용하여 모든 비디오의 얼굴을 쉽게 바꾸세요!

인기 기사

뜨거운 도구

메모장++7.3.1
사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전
중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기
강력한 PHP 통합 개발 환경

드림위버 CS6
시각적 웹 개발 도구

SublimeText3 Mac 버전
신 수준의 코드 편집 소프트웨어(SublimeText3)

뜨거운 주제











PHP와 Vue: 프론트엔드 개발 도구의 완벽한 조합 오늘날 인터넷이 빠르게 발전하는 시대에 프론트엔드 개발은 점점 더 중요해지고 있습니다. 사용자가 웹 사이트 및 애플리케이션 경험에 대한 요구 사항이 점점 더 높아짐에 따라 프런트 엔드 개발자는 보다 효율적이고 유연한 도구를 사용하여 반응형 및 대화형 인터페이스를 만들어야 합니다. 프론트엔드 개발 분야의 두 가지 중요한 기술인 PHP와 Vue.js는 함께 사용하면 완벽한 도구라고 볼 수 있습니다. 이 기사에서는 독자가 이 두 가지를 더 잘 이해하고 적용할 수 있도록 PHP와 Vue의 조합과 자세한 코드 예제를 살펴보겠습니다.

JavaScript 튜토리얼: HTTP 상태 코드를 얻는 방법, 특정 코드 예제가 필요합니다. 서문: 웹 개발에서는 서버와의 데이터 상호 작용이 종종 포함됩니다. 서버와 통신할 때 반환된 HTTP 상태 코드를 가져와서 작업의 성공 여부를 확인하고 다양한 상태 코드에 따라 해당 처리를 수행해야 하는 경우가 많습니다. 이 기사에서는 JavaScript를 사용하여 HTTP 상태 코드를 얻는 방법과 몇 가지 실용적인 코드 예제를 제공합니다. XMLHttpRequest 사용

프론트엔드 개발 인터뷰에서 일반적인 질문은 HTML/CSS 기초, JavaScript 기초, 프레임워크 및 라이브러리, 프로젝트 경험, 알고리즘 및 데이터 구조, 성능 최적화, 크로스 도메인 요청, 프론트엔드 엔지니어링, 디자인 패턴, 새로운 기술 및 트렌드. 면접관 질문은 후보자의 기술적 능력, 프로젝트 경험, 업계 동향에 대한 이해를 평가하기 위해 고안되었습니다. 따라서 지원자는 자신의 능력과 전문성을 입증할 수 있도록 해당 분야에 대한 충분한 준비를 갖추어야 합니다.

Django는 빠른 개발과 깔끔한 방법을 강조하는 Python으로 작성된 웹 애플리케이션 프레임워크입니다. Django는 웹 프레임워크이지만 Django가 프런트엔드인지 백엔드인지에 대한 질문에 답하려면 프런트엔드와 백엔드의 개념에 대한 깊은 이해가 필요합니다. 프론트엔드는 사용자가 직접 상호작용하는 인터페이스를 의미하고, 백엔드는 HTTP 프로토콜을 통해 데이터와 상호작용하는 서버측 프로그램을 의미합니다. 프론트엔드와 백엔드가 분리되면 프론트엔드와 백엔드 프로그램을 독립적으로 개발하여 각각 비즈니스 로직과 인터랙티브 효과, 데이터 교환을 구현할 수 있습니다.

빠르고 효율적인 프로그래밍 언어인 Go 언어는 백엔드 개발 분야에서 널리 사용됩니다. 그러나 Go 언어를 프런트엔드 개발과 연관시키는 사람은 거의 없습니다. 실제로 프런트엔드 개발에 Go 언어를 사용하면 효율성이 향상될 뿐만 아니라 개발자에게 새로운 지평을 열어줄 수도 있습니다. 이 기사에서는 프런트엔드 개발에 Go 언어를 사용할 수 있는 가능성을 살펴보고 독자가 이 영역을 더 잘 이해할 수 있도록 구체적인 코드 예제를 제공합니다. 전통적인 프런트엔드 개발에서는 사용자 인터페이스를 구축하기 위해 JavaScript, HTML, CSS를 사용하는 경우가 많습니다.

Django: 프론트엔드와 백엔드 개발을 모두 처리할 수 있는 마법의 프레임워크! Django는 효율적이고 확장 가능한 웹 애플리케이션 프레임워크입니다. MVC, MTV를 포함한 다양한 웹 개발 모델을 지원할 수 있으며 고품질 웹 애플리케이션을 쉽게 개발할 수 있습니다. Django는 백엔드 개발을 지원할 뿐만 아니라 프런트엔드 인터페이스를 빠르게 구축하고 템플릿 언어를 통해 유연한 뷰 표시를 구현할 수 있습니다. Django는 프론트엔드 개발과 백엔드 개발을 완벽한 통합으로 결합하므로 개발자가 전문적으로 학습할 필요가 없습니다.

Golang과 프런트엔드 기술의 결합: Golang이 프런트엔드 분야에서 어떤 역할을 하는지 살펴보려면 구체적인 코드 예제가 필요합니다. 인터넷과 모바일 애플리케이션의 급속한 발전으로 인해 프런트엔드 기술이 점점 더 중요해지고 있습니다. 이 분야에서는 강력한 백엔드 프로그래밍 언어인 Golang도 중요한 역할을 할 수 있습니다. 이 기사에서는 Golang이 프런트엔드 기술과 어떻게 결합되는지 살펴보고 특정 코드 예제를 통해 프런트엔드 분야에서의 잠재력을 보여줍니다. 프론트엔드 분야에서 Golang의 역할은 효율적이고 간결하며 배우기 쉬운 것입니다.

JavaScript에서 HTTP 상태 코드를 얻는 방법 소개: 프런트 엔드 개발에서 우리는 종종 백엔드 인터페이스와의 상호 작용을 처리해야 하며 HTTP 상태 코드는 매우 중요한 부분입니다. HTTP 상태 코드를 이해하고 얻는 것은 인터페이스에서 반환된 데이터를 더 잘 처리하는 데 도움이 됩니다. 이 기사에서는 JavaScript를 사용하여 HTTP 상태 코드를 얻는 방법을 소개하고 구체적인 코드 예제를 제공합니다. 1. HTTP 상태 코드란 무엇입니까? HTTP 상태 코드는 브라우저가 서버에 요청을 시작할 때 서비스가
