Vuex는 Vue.js 애플리케이션용으로 특별히 개발된 상태 관리 패턴입니다. 많은 구성 요소와 복잡한 상호 작용이 포함된 단일 페이지 애플리케이션의 경우 Vuex는 구성 요소 간의 데이터 공유 및 수정을 용이하게 하는 편리하고 정확하며 예측 가능한 상태 관리 방법을 제공합니다.
파일 구조는 다음과 같습니다
/module
/module
/plugins
helpers.js
index.esm.js
index.js
store.js
util.js
util.js
先从最简单的工具函数开始。
find函数
/** * Get the first item that pass the test * by second argument function * * @param {Array} list * @param {Function} f * @return {*} */ export function find (list, f) { return list.filter(f)[0] }
find函数的测试用例
it('find', () => { const list = [33, 22, 112, 222, 43] expect(find(list, function (a) { return a % 2 === 0 })).toEqual(22) })
解析:
先用
断言函数f
过滤列表list
,最后取过滤后列表的第一个元素。
deepCopy函数
/** * Deep copy the given object considering circular structure. * This function caches all nested objects and its copies. * If it detects circular structure, use cached copy to avoid infinite loop. * * @param {*} obj * @param {Array<Object>} cache * @return {*} */ export function deepCopy (obj, cache = []) { // just return if obj is immutable value if (obj === null || typeof obj !== 'object') { return obj } // if obj is hit, it is in circular structure const hit = find(cache, c => c.original === obj) if (hit) { return hit.copy } const copy = Array.isArray(obj) ? [] : {} // put the copy into cache at first // because we want to refer it in recursive deepCopy cache.push({ original: obj, copy }) Object.keys(obj).forEach(key => { copy[key] = deepCopy(obj[key], cache) }) return copy }
deepCopy的测试用例
// 普通结构 it('deepCopy: nornal structure', () => { const original = { a: 1, b: 'string', c: true, d: null, e: undefined } const copy = deepCopy(original) expect(copy).toEqual(original) }) // 嵌套结构 it('deepCopy: nested structure', () => { const original = { a: { b: 1, c: [2, 3, { d: 4 }] } } const copy = deepCopy(original) expect(copy).toEqual(original) }) // 循环引用结构 it('deepCopy: circular structure', () => { const original = { a: 1 } original.circular = original const copy = deepCopy(original) expect(copy).toEqual(original) })
解析:
功能:支持循环引用的深克隆函数
第一个if判断
obj === null || typeof obj !== 'object'
判断如果不是引用类型直接返回(基本类型是值拷贝),也是递归的一个出口。第二个判断
hit
是判断是不是循环引用,由于是循环引用,在cache中应该有缓存到一份拷贝,直接取cache的,避免再次重复拷贝一份。什么是循环引用看测试用例第三个
original.circular = original
,循环引用和被引用的内容是一样的,用缓存就是避免重复的克隆(内容一样)original.circular
是循环引用,original
是被循环引用先把
cope
放到cache
中,是在递归的时候,如果遇到循环引用,要确保cache中有一份被循环引用的copy
,但是copy
必须是引用类型。为什么
cope
必须是引用类型?循环引用
保存的是引用不是内容(这时候还没拷贝完),在递归的时候并未完成拷贝,只有递归跑完了才完成拷贝,这样未来被循环引用
的内容改变时(拷贝完),循环引用
的内容同步改变所以
const copy = Array.isArray(obj) ? [] : {}
必须是引用类型。最后
Object.keys
可以遍历对象和数组的所有键名(只返回实例的属性,不包含原型链和Symbol),实现递归克隆。一共两个出口,一个是基本类型,另一个是循环引用。
forEachValue
/** * forEach for object */ export function forEachValue (obj, fn) { Object.keys(obj).forEach(key => fn(obj[key], key)) }
测试用例
it('forEachValue', () => { let number = 1 function plus (value, key) { number += value } const origin = { a: 1, b: 3 } forEachValue(origin, plus) expect(number).toEqual(5) })
解析:
一个遍历对象的函数(支持对象和数组)
fn(value, key)
但是回调函数第一个参数是值,第二个参数是键值
isObject
export function isObject (obj) { return obj !== null && typeof obj === 'object' }
测试用例
it('isObject', () => { expect(isObject(1)).toBe(false) expect(isObject('String')).toBe(false) expect(isObject(undefined)).toBe(false) expect(isObject({})).toBe(true) expect(isObject(null)).toBe(false) expect(isObject([])).toBe(true) expect(isObject(new Function())).toBe(false) })
解析:
判断是不是对象,这里没有判断是不是原生对象,数组也是通过的。
由于typeof null === 'object'要先判断是不是null
isPromise
export function isPromise (val) { return val && typeof val.then === 'function' }
测试用例
it('isPromise', () => { const promise = new Promise(() => {}, () => {}) expect(isPromise(1)).toBe(false) expect(isPromise(promise)).toBe(true) expect(isPromise(new Function())).toBe(false) })
解析:
判断是不是Promise
首先判断val不是undefined,然后才可以判断val.then,避免报错
判断依据是val.then是不是函数
assert
export function assert (condition, msg) { if (!condition) throw new Error(`[vuex] ${msg}`) }
测试用例:
it('assert', () => { expect(assert.bind(null, false, 'Hello')).toThrowError('[vuex] Hello') })
解析:
断言函数,断言不通过抛出一个自定义错误信息的Error
index.js
和index.esm.js
index.js
import { Store, install } from './store' import { mapState, mapMutations, mapGetters, mapActions, createNamespacedHelpers } from './helpers' export default { Store, install, version: '__VERSION__', mapState, mapMutations, mapGetters, mapActions, createNamespacedHelpers }
index.esm.js
import { Store, install } from './store' import { mapState, mapMutations, mapGetters, mapActions, createNamespacedHelpers } from './helpers' export default { Store, install, version: '__VERSION__', mapState, mapMutations, mapGetters, mapActions, createNamespacedHelpers } export { Store, install, mapState, mapMutations, mapGetters, mapActions, createNamespacedHelpers }
解析:
区别就是
index.esm.js
比index.js
多了个一个导入模式import Vuex, { mapState } from 'index.esm.js'
:有两种方式导入import Vuex from 'index.js'
:只有一种方式导入
mixin.js
export default function (Vue) { const version = Number(Vue.version.split('.')[0]) if (version >= 2) { Vue.mixin({ beforeCreate: vuexInit }) } else { // override init and inject vuex init procedure // for 1.x backwards compatibility. const _init = Vue.prototype._init Vue.prototype._init = function (options = {}) { options.init = options.init ? [vuexInit].concat(options.init) : vuexInit _init.call(this, options) } } /** * Vuex init hook, injected into each instances init hooks list. */ function vuexInit () { const options = this.$options // store injection if (options.store) { this.$store = typeof options.store === 'function' ? options.store() : options.store } else if (options.parent && options.parent.$store) { this.$store = options.parent.$store } } }
解析:
为什么每个组件都拥有(store属性,也即每个组件都能拿到)store
Vue2直接用mixin和钩子函数beforeCreate,Vue1用外观(装饰者)模式重写Vue._init函数。
vuexInit
-
/plugins
helpers.js
🎜🎜🎜 🎜index.esm.js
🎜🎜🎜🎜index.js
🎜🎜🎜🎜store.js
🎜🎜🎜🎜util.js
🎜🎜
util.js
🎜가장 간단한 유틸리티 기능으로 시작하세요. 🎜🎜🎜find function🎜🎜rrreee🎜find function의 테스트 사례🎜rrreee🎜분석: 🎜🎜🎜🎜먼저assert function f
를 사용하여 list list
를 필터링하고 마지막으로 필터링된 목록의 첫 번째 요소입니다. 🎜🎜🎜🎜deepCopy 기능🎜🎜rrreee🎜deepCopy 테스트 사례🎜rrreee🎜분석: 🎜🎜🎜🎜기능: 순환 참조를 지원하는 딥 클로닝 기능🎜🎜🎜🎜첫 번째 if 판단 obj = == null || typeof obj !== 'object'
참조 유형이 아닌 경우 직접 반환되며(기본 유형은 값 복사) 재귀의 출구이기도 합니다. 🎜🎜🎜🎜두 번째 판단
hit
은 순환 참조이므로 캐시에 캐시된 복사본이 있어야 합니다. 다시는 반복하지 않으려면 복사본을 만드세요. 🎜🎜🎜🎜순환 참조란 무엇인가요? 세 번째 테스트 사례 original.circular = 원본
을 참조하세요. 순환 참조와 참조된 콘텐츠는 반복 복제를 피하기 위해 사용됩니다. 동일)🎜 🎜🎜🎜original.circular
는 순환 참조, original
은 순환 참조 🎜🎜🎜🎜먼저 cope
를 에 넣어주세요 >캐시, 반복 시 순환 참조가 발생하는 경우 캐시에서 순환 참조되는 <code>사본
이 있는지 확인하세요. 그러나 사본
은 다음과 같아야 합니다. 참조 유형. 🎜🎜🎜🎜왜 cope
가 참조 유형이어야 합니까? 순환 참조
는 내용이 아닌 참조를 저장합니다(현재 복사가 완료되지 않았습니다). 이 경우 재귀가 완료된 후에만 복사가 완료됩니다. 앞으로 는 순환참조됩니다의 내용이 변경되면(복사가 완료되면) <code>순환참조
의 내용도 동시에 변경됩니다🎜🎜🎜🎜so const copy = Array.isArray(obj) ? [] : {} code>는 참조 유형이어야 합니다. 🎜🎜🎜🎜마지막으로 <code>Object.keys
는 객체 및 배열의 모든 키 이름을 순회하여(프로토타입 체인 및 기호를 제외한 인스턴스의 속성만 반환) 재귀 복제를 구현할 수 있습니다. 🎜🎜🎜🎜출구는 총 2개 있는데, 하나는 기본형이고 다른 하나는 순환참조형입니다. 🎜🎜🎜🎜forEachValue🎜🎜rrreee🎜테스트 사례🎜rrreee🎜분석: 🎜🎜🎜🎜객체를 순회하는 함수(객체 및 배열 지원)🎜🎜🎜🎜fn(value, key) code>그러나 콜백 함수의 첫 번째 매개변수는 값이고 두 번째 매개변수는 키 값입니다🎜🎜🎜🎜isObject🎜🎜rrreee🎜Test case🎜rrreee🎜분석: 🎜🎜🎜🎜인지 확인 객체, 여기에는 아무것도 없습니다. 그것이 네이티브 객체인지 확인하기 위해 배열도 전달됩니다. 🎜🎜🎜🎜typeof null === 'object'는 먼저 null인지 여부를 확인해야 하기 때문입니다🎜🎜🎜🎜isPromise🎜🎜rrreee🎜테스트 사례🎜rrreee🎜분석: 🎜🎜🎜🎜 Promise🎜🎜🎜 🎜먼저 val이 정의되지 않은 것이 아니라고 판단한 다음 val.then을 판단하여 오류 보고를 방지할 수 있습니다🎜🎜🎜🎜판단의 기준은 val.then이 함수인지 여부입니다🎜🎜🎜🎜assert 🎜🎜rrreee🎜테스트 사례: 🎜rrreee🎜Analytic: 🎜🎜🎜🎜Assert 함수, 사용자 정의 오류 메시지를 발생시켜 주장하지 않음 Error🎜🎜<h4>
<code>index.js
및 index.esm.js code>
🎜index.js
🎜rrreee🎜index.esm.js
🎜rrreee🎜분석: 🎜🎜🎜🎜The 차이점은 index.esm.js
에 index.js
🎜🎜🎜🎜import Vuex, 'index.esm.js의 { mapState }보다 가져오기 모드가 하나 더 있다는 것입니다. '
: 두 가지가 있습니다 가져오는 방법은 한 가지뿐입니다 🎜🎜🎜🎜'index.js'에서 Vuex를 가져옵니다
: 가져오는 방법은 한 가지뿐입니다 🎜🎜mixin.jsrrreee🎜분석: 🎜🎜 🎜🎜모든 컴포넌트에 🎜(store 속성, 즉 모든 컴포넌트가 이를 얻을 수 있음)🎜store🎜🎜🎜🎜Vue2는 beforeCreate에 mixin 및 Hook 기능을 직접 사용합니다. , Vue1은 모양(데코레이터) 모드를 사용하여 Vue를 다시 작성합니다. 🎜🎜🎜🎜vuexInit
는 컴포넌트🎜🎜🎜🎜🎜(옵션은 `new Vue(options)`의 옵션입니다.)🎜옵션이 있습니다. 가게🎜beforeCreate
는 Vue
의 순환 후크이므로 this
는 현재 구성 요소 인스턴스를 가리킵니다. 따라서 this.$store
스토어를 현재 컴포넌트에 직접 삽입할 수 있습니다beforeCreate
是Vue
的周期钩子,this
指向当前组件实例,所以this.$store
可以把store直接注入当前组件
所有组件都是继承于一个全局Vue的,全局mixin组件周期钩子beforeCreate
,这样每个组件都能自动注入store,也即每个组件都能直接通过$store
拿到全局Vuenew Vue({ el: 'app', store, router })
的store
相关推荐:
모든 컴포넌트는 글로벌 Vue, 글로벌 믹스인 컴포넌트 사이클에서 상속됩니다. HookbeforeCreate
, 그러면 각 구성 요소가 저장소에 자동으로 삽입될 수 있습니다. 즉, 각 구성 요소는 전역 Vuenew Vue({ el: 'app ', store, router } )
의 스토어
관련 추천: #🎜🎜##🎜🎜#<a href="http://www.php.cn/js-tutorial-368383.html" target="_self"><code>Vuex에 대한 나의 이해
코드>#🎜🎜##🎜🎜##🎜🎜##🎜🎜#vuex(상태 관리)의 Vue.js#🎜🎜##🎜🎜#위 내용은 VueX의 소스 코드 내용에 대한 간략한 분석의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

웹 개발에서 JavaScript의 주요 용도에는 클라이언트 상호 작용, 양식 검증 및 비동기 통신이 포함됩니다. 1) DOM 운영을 통한 동적 컨텐츠 업데이트 및 사용자 상호 작용; 2) 사용자가 사용자 경험을 향상시키기 위해 데이터를 제출하기 전에 클라이언트 확인이 수행됩니다. 3) 서버와의 진실한 통신은 Ajax 기술을 통해 달성됩니다.

보다 효율적인 코드를 작성하고 성능 병목 현상 및 최적화 전략을 이해하는 데 도움이되기 때문에 JavaScript 엔진이 내부적으로 작동하는 방식을 이해하는 것은 개발자에게 중요합니다. 1) 엔진의 워크 플로에는 구문 분석, 컴파일 및 실행; 2) 실행 프로세스 중에 엔진은 인라인 캐시 및 숨겨진 클래스와 같은 동적 최적화를 수행합니다. 3) 모범 사례에는 글로벌 변수를 피하고 루프 최적화, Const 및 Lets 사용 및 과도한 폐쇄 사용을 피하는 것이 포함됩니다.

Python은 부드러운 학습 곡선과 간결한 구문으로 초보자에게 더 적합합니다. JavaScript는 가파른 학습 곡선과 유연한 구문으로 프론트 엔드 개발에 적합합니다. 1. Python Syntax는 직관적이며 데이터 과학 및 백엔드 개발에 적합합니다. 2. JavaScript는 유연하며 프론트 엔드 및 서버 측 프로그래밍에서 널리 사용됩니다.

Python과 JavaScript는 커뮤니티, 라이브러리 및 리소스 측면에서 고유 한 장점과 단점이 있습니다. 1) Python 커뮤니티는 친절하고 초보자에게 적합하지만 프론트 엔드 개발 리소스는 JavaScript만큼 풍부하지 않습니다. 2) Python은 데이터 과학 및 기계 학습 라이브러리에서 강력하며 JavaScript는 프론트 엔드 개발 라이브러리 및 프레임 워크에서 더 좋습니다. 3) 둘 다 풍부한 학습 리소스를 가지고 있지만 Python은 공식 문서로 시작하는 데 적합하지만 JavaScript는 MDNWebDocs에서 더 좋습니다. 선택은 프로젝트 요구와 개인적인 이익을 기반으로해야합니다.

C/C에서 JavaScript로 전환하려면 동적 타이핑, 쓰레기 수집 및 비동기 프로그래밍으로 적응해야합니다. 1) C/C는 수동 메모리 관리가 필요한 정적으로 입력 한 언어이며 JavaScript는 동적으로 입력하고 쓰레기 수집이 자동으로 처리됩니다. 2) C/C를 기계 코드로 컴파일 해야하는 반면 JavaScript는 해석 된 언어입니다. 3) JavaScript는 폐쇄, 프로토 타입 체인 및 약속과 같은 개념을 소개하여 유연성과 비동기 프로그래밍 기능을 향상시킵니다.

각각의 엔진의 구현 원리 및 최적화 전략이 다르기 때문에 JavaScript 엔진은 JavaScript 코드를 구문 분석하고 실행할 때 다른 영향을 미칩니다. 1. 어휘 분석 : 소스 코드를 어휘 단위로 변환합니다. 2. 문법 분석 : 추상 구문 트리를 생성합니다. 3. 최적화 및 컴파일 : JIT 컴파일러를 통해 기계 코드를 생성합니다. 4. 실행 : 기계 코드를 실행하십시오. V8 엔진은 즉각적인 컴파일 및 숨겨진 클래스를 통해 최적화하여 Spidermonkey는 유형 추론 시스템을 사용하여 동일한 코드에서 성능이 다른 성능을 제공합니다.

실제 세계에서 JavaScript의 응용 프로그램에는 서버 측 프로그래밍, 모바일 애플리케이션 개발 및 사물 인터넷 제어가 포함됩니다. 1. 서버 측 프로그래밍은 Node.js를 통해 실현되며 동시 요청 처리에 적합합니다. 2. 모바일 애플리케이션 개발은 재교육을 통해 수행되며 크로스 플랫폼 배포를 지원합니다. 3. Johnny-Five 라이브러리를 통한 IoT 장치 제어에 사용되며 하드웨어 상호 작용에 적합합니다.

일상적인 기술 도구를 사용하여 기능적 다중 테넌트 SaaS 응용 프로그램 (Edtech 앱)을 구축했으며 동일한 작업을 수행 할 수 있습니다. 먼저, 다중 테넌트 SaaS 응용 프로그램은 무엇입니까? 멀티 테넌트 SAAS 응용 프로그램은 노래에서 여러 고객에게 서비스를 제공 할 수 있습니다.


핫 AI 도구

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

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

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

Clothoff.io
AI 옷 제거제

AI Hentai Generator
AI Hentai를 무료로 생성하십시오.

인기 기사

뜨거운 도구

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

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

SecList
SecLists는 최고의 보안 테스터의 동반자입니다. 보안 평가 시 자주 사용되는 다양한 유형의 목록을 한 곳에 모아 놓은 것입니다. SecLists는 보안 테스터에게 필요할 수 있는 모든 목록을 편리하게 제공하여 보안 테스트를 더욱 효율적이고 생산적으로 만드는 데 도움이 됩니다. 목록 유형에는 사용자 이름, 비밀번호, URL, 퍼징 페이로드, 민감한 데이터 패턴, 웹 셸 등이 포함됩니다. 테스터는 이 저장소를 새로운 테스트 시스템으로 간단히 가져올 수 있으며 필요한 모든 유형의 목록에 액세스할 수 있습니다.

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

ZendStudio 13.5.1 맥
강력한 PHP 통합 개발 환경
