Как получить родительский компонент vue и дочерний компонент vue для использования одного и того же объекта данных? - PullRequest
0 голосов
/ 09 октября 2018

У меня есть компонент 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

Ответы [ 3 ]

0 голосов
/ 10 октября 2018

В ViewGuestbook.vue вы должны скопировать свойство в основные данные.

В created() или mounted() ловушке сделайте это:

this.entries = this.p_entries; //Just assign
this.entries = JSON.parse(JSON.stringify(this.p_entries)); //Or clone it.
0 голосов
/ 11 октября 2018

Для совместного использования данных свяжите объект данных из родительского компонента с объектом props дочернего компонента, используя v-bind.

Примерно так:

/ 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>
0 голосов
/ 09 октября 2018

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.В примере codesandbox у меня есть одна переменная «shared», которая содержит контент, не стесняйтесь делать это по-другому:

https://codesandbox.io/s/62wvro7083

Edit Vue Template

...