我現在感覺有點不好意思。根據我在您的問題中看到的一些語法,我走下了一個小兔子洞,並且讓一堆不必要的旋轉。語法是這樣的:
data() {
return {
enabled: settings.showOverlay
};
}
其中,出於某種原因,我解釋爲「好肯定的是,每當enabled
變化,settings.showOverlay
會有所改變,因爲Vue公司是反應」。
是的,沒有。
在該代碼中,settings.showOverlay
只是初始值對於enabled
屬性。 enabled
屬性將爲反應,但它絕不會將值傳遞給設置對象。基本上數據函數返回一個啓用了屬性的對象,該對象的初始值爲settings.showOverlay
,然後是,即對象變爲反應對象。
如果您希望將Vue中所做的更改傳遞給您的設置對象,那麼您只需在Vue的數據對象上公開設置對象。
data() {
return {
settings,
};
}
現在如果你有一個像
<div v-show="settings.showOverlay"> Some stuff </div>
<button @click="settings.showOverlay= !settings.showOverlay"></button>
settings.showOverlay
代碼不僅將反應在Vue公司,但在settings
對象。不需要我在下面跳過的任何箍(/ facepalm)。
FWIW我相信我在評論中提到的一些鏈接是指數據對象本身。數據對象需要是一個普通的javascript對象,不一定是它的所有屬性。
換句話說,在
data() {
return something
}
something
必須是一個普通的javascript對象。
原來的答案
我已經在我的Vue公司的應用程序一對夫婦的方式做到了這一點。在我的第一個應用程序中,我想做同樣的事情,將設置存儲在一個外部模塊中,該模塊可以管理持久設置並在Vue上顯示這些設置。我最終寫了一個看起來像這樣的類。
class Settings {
constructor(){
// read settings from persisted solution
}
get(key){
// return "key" from settings
}
set(key){
// set "key" in settings
}
save(){
// save settings to persisted solution
}
}
export default Settings
然後在我的Vue中這樣使用它。
import Settings from "./settings"
new Vue({
data:{
someSetting: Settings.get("someSetting")
}
})
然後稍後再觸發set()和save()。對我來說,這一點是每當路由更改被觸發時,我只需將所有設置都設置回設置對象,然後保存。
聽起來像是你正在輸出一個具有getter/setter屬性的對象,可能是這樣的。
export const settings = {
overlay: stored.showOverlay,
get showOverlay(){
return this.overlay
},
set showOverlay(v){
this.overlay = v
}
}
當您觸發set
時,您可能會觸發保存。我比上述解決方案更喜歡這個想法。但讓它工作是一個更多的工作。首先,我嘗試使用計算機。
new Vue({
computed:{
showOverlay: {
get(){ return settings.showOverlay }
set(v) { settings.showOverlay = v }
}
}
})
但是這並不起作用,因爲它不反映Vue的變化。這是有道理的,因爲Vue並不知道改變的價值。添加$forceUpdate
到setter也不起作用,我期望因爲計算值的緩存性質。然而,使用一個計算結合數據屬性,確實工作。
new Vue({
data(){
return {
showOverlay_internal: settings.showOverlay
}
},
computed:{
showOverlay: {
get(){ return this.showOverlay_internal }
set(v) {
settings.showOverlay = v
this.showOverlayInternal = v
}
}
}
})
這改變了Vue的狀態並觸發了設置對象的改變(這反過來可以觸發持久化)。
但是,該死的,這是很多工作。
儘管有時記住我們用於實例化Vue的對象只是普通的舊javascript對象,我們可以操縱它們,這一點很重要。我想知道是否可以編寫一些爲我們創建數據屬性和計算值的代碼。從Vuex那裏得到一個提示,是的,我們可以。
我最終得到的是這個。
import {settings, mapSetting} from "./settings"
const definition = {
name:"app"
}
mapSetting(definition, "showOverlay"
export default definition
mapSetting
做了我們上面爲我們做過的所有工作。 showOverlay
現在是一個計算屬性,對Vue中的更改起反應並更新我們的設置對象。目前唯一的缺點是它暴露了showOverlay_internal
數據屬性。我不知道有多重要。可以改進它來一次映射多個屬性。
這是我寫的使用localStorage
作爲持久性介質的完整代碼。
function saveData(s){
localStorage.setItem("settings", JSON.stringify(s))
}
let stored = JSON.parse(localStorage.getItem("settings"))
if (null == stored) {
stored = {}
}
export const settings = {
overlay: stored.showOverlay,
get showOverlay(){
return this.overlay
},
set showOverlay(v){
this.overlay = v
saveData(this)
}
}
function generateDataFn(definition, setting, internalName){
let originalDataFn = definition.data
return function(){
let data = originalDataFn ? originalDataFn() : {}
data[internalName] = settings[setting]
return data
}
}
function generateComputed(internalName, setting){
return {
get(){
return this[internalName]
},
set(v){
settings[setting] = v
this[internalName] = v
}
}
}
export function mapSetting(definition, setting){
let internalName = `${setting}_internal`
definition.data = generateDataFn(definition, setting, internalName)
if (!definition.computed)
definition.computed = {}
definition.computed[setting] = generateComputed(internalName, setting)
}
我認爲你正在尋找一些有狀態,我想看看[vuex(http://vuex.vuejs.org/en/intro.html) – dops
的原因之一,我開始使用Vue是因爲它應該是「輕量級」的,你應該能夠一次採用它。我不想將我的整個應用程序狀態切換到Vue特定的存儲區(我想我會花更多時間切換到全局消息總線模型,而不是使用Vue首先保存的內容)。有沒有什麼方法可以使用「只是一點點Vue」? – Coderer
我認爲更廣泛的問題可能是我正在觀察具有已經使用getter/setter的屬性的對象 - 我相信在引擎蓋下,導出的模塊通過隱藏實際屬性並提供了只讀視圖只有一個生成的getter。所以,如果我有一個對象並想要觀察吸氣劑,那麼有沒有一個好的方法來做到這一點? – Coderer