웹 확장의 공유 vuex 상태(데드 개체 문제)
웹 확장에서 공유 vue.js 상태를 사용하려고 합니다.
상태는 백그라운드스크립트의 DOM에 저장되어 팝업페이지에 표시됩니다.
첫 번째 시도
첫 번째 시도는 vuex가 없는 단순한 스토어를 사용하는 것이었습니다.
background.displays(배경).
var store = {
count: 0
};
poppup.displaces
browser.runtime.getBackgroundPage().then(bg => {
var store = bg.store;
var vue = new Vue({
el: '#app',
data: {
state: store
},
})
})
poppup.displaces
<div id="app">
<p>{{ state.count }}</p>
<p>
<button @click="state.count++">+</button>
</p>
</div>
<script src="vue.js"></script>
<script src="popup.js"></script>
이것은 팝업이 처음 열렸을 때 기능하지만(카운터를 늘릴 수 있고 값이 갱신됩니다), 팝업이 두 번째로 열리면 렌더링에 실패합니다.[Vue warn]: Error in render: "TypeError: can't access dead object"
이는 첫 번째 팝업에서 vue.js 인스턴스가 변경된 것이 원인인 것 같습니다.store
자체 getter/setters를 설정함으로써 첫 번째 팝업이 닫힌 후 삭제되어 공유 상태를 사용할 수 없게 됩니다.어쩔 수 없을 것 같아서 Vuex를 시도해 보기로 했어요.
두 번째 시도
background.displays(배경).
var store = new Vuex.Store({
state: {
count: 0
},
mutations: {
increment: state => state.count++,
}
})
poppup.displaces
browser.runtime.getBackgroundPage().then(bg => {
var store = bg.store;
var vue = new Vue({
el: '#app',
computed: {
count () {
return store.state.count
}
},
methods: {
increment () {
store.commit('increment')
},
}
});
})
poppup.displaces
<div id="app">
<p>{{ count }}</p>
<p>
<button @click="increment">+</button>
</p>
</div>
<script src="vue.js"></script>
<script src="popup.js"></script>
아쉽게도 이것도 안 돼요.팝업을 열고 현재 카운터 값을 볼 수 있지만, 이 값을 늘린다고 해서 보기가 업데이트되지는 않습니다(팝업을 다시 열어야 새 값이 표시됩니다).
popup.js에서 스토어를 선언한 경우 코드는 정상적으로 동작하기 때문에 동작합니다만, 어떠한 이유로 동작하지 않습니다.
질문:
- vue.js는 이 사용 사례를 전혀 처리할 수 없습니까?
- 그렇다면 다른 프레임워크(각도, 반응 등)는 여기서 작동합니까?
vue 인스턴스가 백그라운드 및 팝업에서 동일하지 않기 때문에 작동하지 않습니다.따라서 백그라운드에서 상태를 가져오면 해당 상태의 워쳐가 팝업 보기가 아닌 백그라운드 페이지 내에서 Vue를 반응시킵니다.백그라운드 및 팝업에서 동일한 저장소를 사용하고 둘 사이의 상태를 동기화하면 이 작업을 수행할 수 있습니다.상태를 동기화하려면 localStorage를 사용하여 상점의 여러 인스턴스를 통해 돌연변이를 전파하는 우수한 플러그인 vuex-shared-mutations를 사용할 수 있습니다.스토어에서 추가
import createMutationsSharer from 'vuex-shared-mutations'
//...
export default new Vuex.Store({
//...
plugins: [createMutationsSharer({ predicate: ['increment'] })],
});
이제 팝업이 버튼에 반응하고 배경이 증가합니다.팝업을 다시 열면 새 저장소를 만들었기 때문에 카운트가 0이 됩니다.팝업이 초기화되면 초기 상태를 로드해야 합니다.
store.syslog:
export default new Vuex.Store({
state: {
count: 0
},
mutations: {
increment: state => state.count++,
setCount (state, count) {
state.count = count
},
},
plugins: [createMutationsSharer({ predicate: ['increment'] })],
actions: {
getCount ({ commit }) {
browser.runtime.sendMessage({type: "storeinit", key: "count"}).then(count => {
commit('setCount', count)
})
}
}
});
background.displays(배경).
import store from './store';
browser.runtime.onMessage.addListener((message, sender) => {
if (message.type === 'storeinit') {
return Promise.resolve(store.state[message.key]);
}
});
poppup.displaces
import store from '../store';
var vue = new Vue({
//...
created () {
this.$store.dispatch('getCount')
}
});
이러한 문제는 관련이 없습니다.리액트 사용자는 프록시를 사용하여 브라우저 확장으로 상태를 전파합니다.react-chrome-redux
지연되어 죄송합니다. 노드 모듈을 만듭니다.
https://github.com/MitsuhaKitsune/vuex-webextensions
모듈은 webextensions 메시징 API를 사용하여 webextension의 모든 스토어 인스턴스를 동기화합니다.
설치는 다른 vuex 플러그인과 같으므로 Readme에서 확인할 수 있습니다.
질문이나 피드백이 있으시면 여기 또는 github 문제에 대해 말씀해 주십시오.
언급URL : https://stackoverflow.com/questions/49341734/shared-vuex-state-in-a-web-extension-dead-object-issues
'sourcecode' 카테고리의 다른 글
헤더에 필터 기능이 사용되는 경우 Vuetify 데이터 테이블에서 검색이 작동하지 않음 (0) | 2022.08.27 |
---|---|
Vue 앱 빌드를 생성하려면 어떤 명령을 사용해야 합니까? (0) | 2022.08.27 |
TypeScript를 사용하여 Vue.js에서 비반응 인스턴스 속성을 지정하는 방법 (0) | 2022.08.27 |
Java에서 구분된 항목의 문자열을 작성하는 가장 좋은 방법은 무엇입니까? (0) | 2022.08.27 |
로그인 후 NuxtJ 리다이렉트 (0) | 2022.08.27 |