我有一个Guestbook
组件,我将其分为Sign
和View
组件。
我想通过或什至更好地与我的主要访客留言簿组件和子级View组件共享条目数据,但是我不知道如何实现此目的。
我有以下代码:
/src/components/Guestbook.vue
<template>
<div>
<h1>Guestbook</h1>
<SignGuestbook />
<ViewGuestbook :entries="v_entries" />
<ViewGuestbook :p_entries="v_entries" />
<!-- Error: '[Vue warn]: Property or method "store" is not defined on the instance but referenced during render.' -->
<!-- <ViewGuestbook :entries="store" /> -->
<!-- <ViewGuestbook :p_entries="store" /> -->
<!-- Error: '[Vue warn]: Property or method "$store" is not defined on the instance but referenced during render.' -->
<!-- <ViewGuestbook :entries="$store" /> -->
<!-- <ViewGuestbook :p_entries="$store" /> -->
</div>
</template>
<script>
import SignGuestbook from './SignGuestbook.vue'
import ViewGuestbook from './ViewGuestbook.vue'
import Vue from 'vue'
import Vuex from 'vuex'
import guestbook from './guestbook.js'
Vue.use(Vuex)
const store = new Vuex.Store({
state: {
entries: [
{ id: 1, name: 'stored 1', comment: 'comment' },
{ id: 2, name: 'stored 2', comment: 'comment' }
]
},
getters: {
entries: entries => {
return entries
}
},
mutations: {
refreshList (state) {
state.s_entries = guestbook.getItems()
}
}
})
export default {
name: 'Guestbook',
components: {
SignGuestbook,
ViewGuestbook
},
props: ['v_entries'],
data () {
return { comment: '', name: '', entries: ['test'] }
},
methods: {
refreshList: async function () {
this.entries = await guestbook.getItems()
store.commit('refreshList')
// this.$store = await guestbook.getItems()
console.log('regular entries:', this.entries)
console.log('stored entries:', this.store.getters.entries)
}
},
async created () {
await guestbook.authoriseAndConnect()
await guestbook.createMutableData()
await this.refreshList()
}
}
</script>
/src/components/ViewGuestbook.vue
<template>
<div>
get entries attempt #1<br>
<div v-for="entry in entries">
an entry<br>
</div>
<br>
get entries attempt #2<br>
{{ entries }}
<br>
<!-- Error: '[Vue warn]: Property or method "$store" is not defined on the instance but referenced during render.' -->
<!-- stored entries<br>
{{ this.$store }}
<br>-->
<br>
</div>
</div>
</template>
<script>
export default {
name: 'ViewGuestbook',
props: ['p_entries'],
data () {
return { entries: [
{ id: 1, name: 'child 1', comment: 'comment' },
{ id: 2, name: 'child 2', comment: 'comment' }
]}
},
async created () {
this.entries = this.p_entries
}
}
</script>
/src/components/guestbook.js
let app
let md
async function authoriseAndConnect () {
const opts = {
forceUseMock: true
}
let appInfo = {
name: 'SAFE Guestbook Application',
id: 'net.maidsafe.tutorials.web-app',
version: '0.1.0',
vendor: 'MaidSafe.net Ltd.'
}
app = await window.safe.initialiseApp(appInfo, null, opts)
console.log('Authorising SAFE application...')
try {
const authReqUri = await app.auth.genAuthUri()
console.log('Generated authentication URI...', authReqUri)
const authUri = await window.safe.authorise(authReqUri)
console.log('SAFE application authorised...')
await app.auth.loginFromUri(authUri)
} catch (err) {
console.warn('Application authorisation was rejected', err)
}
console.log('Application connected to the network')
}
async function createMutableData () {
console.log('Creating MutableData with initial dataset...')
const typeTag = 15000
md = await app.mutableData.newRandomPublic(typeTag)
const initialData = {
'random_key_1': JSON.stringify({
name: 'parent 1',
comment: 'comment'
}),
'random_key_2': JSON.stringify({
name: 'parent 2',
comment: 'comment'
})
}
await md.quickSetup(initialData)
}
async function getItems () {
const entries = await md.getEntries()
let entriesList = await entries.listEntries()
let items = []
entriesList.forEach((entry) => {
const value = entry.value
if (value.buf.length === 0) return
const parsedValue = JSON.parse(value.buf)
items.push({ key: entry.key, value: parsedValue, version: value.version })
})
return items
}
module.exports = {
authoriseAndConnect,
createMutableData,
getItems
}
index.js
import Vue from 'vue'
import App from './App'
import router from './router'
export default new Vue({
el: '#root',
router,
render: (h) => h(App)
})
// Error: unused variable
// let globalData = new Vue({
// data: {
// $store: {}
// }
// })
// Error: '[Vue warn]: Property or method "$store" is not defined on the instance but referenced during render.'
// Vue.mixin({
// computed: {
// $store: {
// get: function () { return globalData.$data.$store },
// set: function (newData) { globalData.$data.$store = newData }
// }
// }
// })
预期(至少其中之一):
get entries attempt #1
an entry
an entry
get entries attempt #2
[{ id: 1, name: 'stored 1', comment: 'comment' },{ id: 2, name: 'stored 2', comment: 'comment' }]
结果:
get entries attempt #1
get entries attempt #2
get entries attempt #1
get entries attempt #2
答案 0 :(得分:0)
TL; DR: https://codesandbox.io/s/62wvro7083
我用自己的小数据存储解决了这个问题,这是一种非常简单的方法,但是对我来说足够好,而无需深入研究Vuex。
首先,我在初始化其他任何内容之前在某个地方创建数据存储。
window.globalData = new Vue({
data: {
$store: {
shared: {}
}
},
});
此后,我添加了一个全局Mixin,它允许获取数据并将其设置到全局存储中。
Vue.mixin({
computed: {
$store: {
get: function () { return window.globalData.$data.$store },
set: function (newData) { window.globalData.$data.$store = newData; }
}
}
});
然后,每个组件都可以通过this.$store
访问数据存储。在一个示例codeandbox中,我有一个“ shared”变量来保存内容,可以随意进行以下操作:
答案 1 :(得分:0)
在ViewGuestbook.vue中,您必须将属性复制到主数据中。
在created()
或mounted()
钩中执行以下操作:
this.entries = this.p_entries; //Just assign
this.entries = JSON.parse(JSON.stringify(this.p_entries)); //Or clone it.
答案 2 :(得分:0)
要共享数据,请使用v-bind将数据对象从父组件绑定到子组件的props对象。
像这样:
/src/components/Guestbook.vue
...
<ViewGuestbook v-bind:entries="d_entries" />
...
export default {
name: 'Guestbook',
components: {
SignGuestbook,
ViewGuestbook
},
data () {
return { d_entries: [] }
},
methods: {
refreshList: async function () {
this.d_entries = [
{ id: 1, name: 'placeholder 1', comment: 'comment' },
{ id: 2, name: 'placeholder 2', comment: 'comment' }
]
},
},
async created () {
this.refreshList()
}
...
/src/components/ViewGuestbook.vue
<template>
<div>
entries<br>
<div v-for="entry in entries">
{{ entry.name }}<br>
{{ entry.comment }}<br>
</div>
</div>
</template>
<script>
export default {
name: 'ViewGuestbook',
props: {
'entries': Array
}
}
</script>