나는 돌연변이와 행동의 동기에 대한 이해가 어느 때와 어떻게 사용할 것인지 더 잘 판단 할 수 있다고 믿습니다. 또한 "규칙"이 희미 해지는 상황에서 프로그래머가 불확실성의 부담을 덜어줍니다. 각각의 목적에 대해 약간의 추론을 한 후에, 행동과 돌연변이를 사용하는 잘못된 방법이있을 수는 있지만 정식 접근법이 있다고 생각하지 않습니다.
먼저 왜 우리가 돌연변이 또는 행동을 겪는 지 이해하려고 노력합시다.
왜 처음부터 상용구를 통과해야합니까? 구성 요소에서 직접 상태를 변경하지 않는 이유는 무엇입니까?
엄밀히 말하면 state
구성 요소 에서 직접 변경할 수 있습니다 . 은 state
단지 자바 스크립트 객체이며, 당신이 그것을 만드는 것이 변화를 되돌아갑니다 아무것도 마법이있다.
// Yes, you can!
this.$store.state['products'].push(product)
그러나이 작업을 수행하면 모든 곳에서 상태 돌연변이가 분산됩니다. 상태를 수용하는 단일 모듈을 열 수있는 능력을 잃어 버리고 어떤 종류의 작업을 적용 할 수 있는지 한 눈에 알 수 있습니다. 중앙 집중식 돌연변이가 있으면 일부 상용구 비용이 들지만이를 해결합니다.
// so we go from this
this.$store.state['products'].push(product)
// to this
this.$store.commit('addProduct', {product})
...
// and in store
addProduct(state, {product}){
state.products.push(product)
}
...
보일러 플레이트로 짧은 것을 교체하면 보일러 플레이트도 작게 만들고 싶습니다. 따라서 돌연변이는 비즈니스 로직이 거의없는 상태에서 네이티브 작업을 둘러싼 매우 얇은 래퍼라고 생각합니다. 다시 말해서, 돌연변이는 주로 세터와 같이 사용되는 것을 의미한다.
이제 돌연변이를 중앙 집중화 했으므로 상태 변경에 대한 개요가 개선되었으며 툴링 (vue-devtools)도 해당 위치를 인식하므로 디버깅이 쉬워집니다. 또한 많은 Vuex 플러그인은 상태를 직접 추적하여 변경 사항을 추적하지 않고 돌연변이에 의존한다는 점을 명심해야합니다. 따라서 상태에 대한 "경계를 벗어난"변경 사항은 보이지 않습니다.
그래서 mutations
, actions
차이 어쨌든 무엇입니까?
돌연변이와 같은 조치도 상점의 모듈에 상주하며 state
오브젝트를 수신 할 수 있습니다 . 그들이 할 수 있음을 의미 직접 돌연변이 수도 . 그렇다면 둘 다 갖는 요점은 무엇입니까? 돌연변이를 작고 단순하게 유지해야한다고 생각한다면보다 정교한 비즈니스 로직을 수용 할 수있는 대체 수단이 필요하다는 것을 의미합니다. 행동은이를위한 수단입니다. 이전에 설정 한 것처럼 vue-devtools 및 플러그인은 Mutations를 통한 변경 사항을 알고 있으므로 일관성을 유지하려면 작업에서 Mutations를 계속 사용해야합니다. 더욱이, 액션은 모두 포함되어야하고, 캡슐화하는 로직은 비동기적일 수 있으므로 액션은 처음부터 단순히 비동기식으로 만들어 질 것입니다.
행동은 비동기적일 수 있지만 돌연변이는 일반적으로 그렇지 않다는 것이 종종 강조된다. 돌연변이는 동기적인 모든 것에 (그리고 비동기적인 것에 대한 행동) 사용되어야한다는 표시로 구별을 보도록 결정할 수있다. 그러나 예를 들어 둘 이상의 돌연변이를 (동 기적으로) 커밋해야하거나 돌연변이 함수가 Getters 또는 Mutations를 인수로받지 않기 때문에 돌연변이에서 Getter와 함께 작업 해야하는 경우 몇 가지 어려움에 처하게됩니다 ...
... 흥미로운 질문으로 이어집니다.
돌연변이는 왜 Getter를받지 않습니까?
아직이 질문에 대한 만족스러운 답변을 찾지 못했습니다. 나는 핵심 팀이 내가 mo을 발견했다고 설명했다. 사용법을 요약하면 Getter는 상태에 대한 확장을 계산 (및 종종 캐시)해야합니다. 다시 말해서, 기본적으로 여전히 상태이지만 일부 선행 계산이 필요하지만 일반적으로 읽기 전용입니다. 그것은 적어도 그들이 사용하도록 권장되는 방법입니다.
따라서 돌연변이가 Getter에 직접 액세스하는 것을 방지한다는 것은 우리가 전자에서 제공하는 일부 기능을 전자에서 액세스해야하는 경우 이제 세 가지 중 하나가 필요하다는 것을 의미합니다. (1) Getter가 제공 한 상태 계산이 액세스 가능한 곳에 중복되어 있습니다. (2) 계산 된 값 (또는 관련 Getter 자체)이 Mutation (펑키)에 대한 명시적인 인수로 전달되거나 (3) Getter의 논리 자체가 Mutation 내에서 직접 복제 됨 Getter (stench)에서 제공하는 캐싱의 추가 이점없이
다음은 (2)의 예입니다. 제가 경험 한 대부분의 시나리오에서 "최소 불량"옵션으로 보입니다.
state:{
shoppingCart: {
products: []
}
},
getters:{
hasProduct(state){
return function(product) { ... }
}
}
actions: {
addProduct({state, getters, commit, dispatch}, {product}){
// all kinds of business logic goes here
// then pull out some computed state
const hasProduct = getters.hasProduct(product)
// and pass it to the mutation
commit('addProduct', {product, hasProduct})
}
}
mutations: {
addProduct(state, {product, hasProduct}){
if (hasProduct){
// mutate the state one way
} else {
// mutate the state another way
}
}
}
저에게 위의 내용은 약간 복잡 할뿐만 아니라 다소 "누설"인 것 같습니다. 액션에 존재하는 일부 코드는 분명히 돌연변이의 내부 논리에서 나오기 때문입니다.
내 생각에 이것은 타협의 표시입니다. 돌연변이가 Getter를 자동으로 수신하도록 허용하면 몇 가지 문제가 있다고 생각합니다. Vuex 자체의 설계 또는 툴링 (vue-devtools 등), 또는 이전 버전과의 호환성을 유지하거나 명시된 모든 가능성의 조합 일 수 있습니다.
내가 믿지 않는 것은 Getters를 돌연변이에 전달하는 것이 반드시 무언가 잘못하고 있다는 표시입니다. 프레임 워크의 단점 중 하나를 단순히 "패치"하는 것으로 간주합니다.