Так что я весь день борюсь с этой проблемой. В основном у меня есть корневой компонент с свойством data dbEnabled, который должен решить, отображать ли еще один дочерний компонент с именем Database.
Это должно быть достигнуто нажатием кнопки на еще одном дочернем компоненте с именем Навигация. Мне удалось отправить это свойство от root к компоненту, указав его как опору на принимающем компоненте и передав v-show или v-if из базы данных. К сожалению, он реагирует только на создание экземпляра (не реагирует на изменение).
До сих пор мне удалось достичь этого другим путем, используя document.getElementByID(#db) и добавив класс, который устанавливает отображение: none! Important ; для этого элемента, но можно ли это сделать с Vue изначально?
Это файл main.js:
import Vue from 'vue'
import App from './App'
import Title from './Components/Title.vue'
import Navigation from './Components/Navigation.vue'
import AddProduct from './Components/AddProduct.vue'
import Database from './Components/Database.vue'
Vue.config.productionTip = false
Vue.component('app-title', Title)
Vue.component('nav-buttons', Navigation)
Vue.component('add-product', AddProduct)
Vue.component('db', Database)
/* eslint-disable no-new */
window.App = new Vue({
el: '#app',
components: { App, Title, Navigation, AddProduct, Database },
template: '<App/>',
data: {
dbEnabled: false // <-- this should decide whether to show/hide #db element
}
})
Это компонент навигации, который содержит кнопку переключения:
<template>
<div id="nav-div">
<button> {{ planBtn }}</button>
<button> {{ addBtn }}</button>
<button> {{ editBtn }}</button>
<button @click="hideDb()"> {{ dbBtn }}</button> //<--here I tried openDb() function
</div>
</template>
<script>
export default {
name: 'Navigation',
props: ['dbEnabled'],
data() {
return {
dbBtn: 'Open database',
addBtn: 'Add product',
planBtn: 'Plan meal',
editBtn: 'Edit product'
}
},
methods: {
openDb() {
App.dbEnabled = !App.dbEnabled //<--This function changes the root instance
//value but the v-show/v-if doesn't react to the
//change. Nor does changing this value in Chrome
//console make it react
},
hideDb() {
let d = document.getElementById("db")
d.className = (d.className === '') ? db.className='db-hidden' : db.className=''
}
}
}
</script>
Это компонент базы данных:
<template>
<div id="db"> //<--Tried v-show/v-if here, but works only initially
<table>
<thead>
<tr>
<th
v-for="prAttr in gridColumns"
>{{ prAttr }}</th>
</tr>
</thead>
<tbody>
<tr
:weight="weight"
v-for="product in products">
<td> {{ product.name }} </td>
<td> {{ carbs(product, weight) }} </td>
<td> {{ sugar(product, weight) }} </td>
<td> {{ fiber(product, weight) }} </td>
<td> {{ fat(product, weight) }} </td>
<td> {{ protein(product, weight) }} </td>
<td> {{ unknwn(product, weight) }}</td>
</tr>
</tbody>
</table>
</div>
</template>
<script>
export default {
name: 'Database',
data() {
return {
weight: 100,
gridColumns: ['Product name', 'Carbs (%)', 'Sugar (%)', 'Fiber (%)',
'Fat (%)', 'Protein (%)', 'Unknwn(%)'],
products: [
{name: 'Rimi piens pasterizets 2,5%', carbs: 4.8, sugar: 4.8,
fiber: 0, fat: 2.5, protein: 3.2, unknwn: 'unknwn_ingredients'},
{name: 'Santini Ksylitol', carbs: 99.8, sugar: 0.2,
fiber: 0, fat: 0, protein: 0}
]
}
},
props: ['dbEnabled'],
methods: {
unknwn(cp, weight) {
let unknwn_ingredients = (100 - cp.carbs
- cp.fiber - cp.fat - cp.protein) / weight * 100
return unknwn_ingredients.toFixed(2)
},
carbs(cp, weight) {
let carbs = cp.carbs / weight * 100
return carbs
},
sugar(cp, weight) {
let sugar = cp.carbs / weight * 100
return sugar
},
fiber(cp, weight) {
let fiber = cp.carbs / weight * 100
return fiber
},
fat(cp, weight) {
let fat = cp.carbs / weight * 100
return fat
},
protein(cp, weight) {
let protein = cp.carbs / weight * 100
return protein
}
}
}
</script>
Вы ориентируетесь не на то место. Вы хотите настроить целевой компонент, а не фактический экземпляр vue (приложение)
Самый простой способ исправить это - изменить App.dbEnabled = !App.dbEnabled
this.$root.dbEnabled = !this.$root.dbEnabled
У вас установлен vue-devtools? Это помогает узнать, что вы на самом деле нацеливаете.
Я также советую вам посмотреть на vm. $ Emit(). Лично я использовал бы emit, чтобы подтолкнуть детские изменения вверх по цепочке. Однако в вашем примере это может быть немного избыточным.
Uncaught ReferenceError: $vm0 is not defined.
this. $ root` выводит какundefined
. Я попытался заменитьApp.dbEnabled
this.$root.dbEnabled
и он действительно меняет значение свойства, однакоv-shot
иv-if
прежнему не реагируют на изменение логического значения. Чего мне не хватает?