我现在感觉有点不好意思。根据我在您的问题中看到的一些语法,我走下了一个小兔子洞,并且让一堆不必要的旋转。语法是这样的:
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