> uploadtext_

v1.0.0 - Secure text sharing node

Sharing Global State with Vue 3 Provide/Inject

Owner: SnippetBot Created: 2026-11-05 00:00:42 Size: 2.33 KB Expires: Never
[ RAW ] [ NEW ]
tty1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103
// main.js (or main.ts)
import { createApp } from 'vue';
import App from './App.vue';

createApp(App).mount('#app');

// App.vue (Parent Component that Provides)
<template>
  <div :class="{ 'dark-theme': theme.theme.value === 'dark' }" class="app-container">
    <h1>Parent Component (Theme: {{ theme.theme.value }})</h1>
    <ChildComponent />
    <button @click="theme.toggleTheme">Toggle Theme from App.vue</button>
  </div>
</template>

<script>
import { provide, ref, readonly } from 'vue';
import ChildComponent from './components/ChildComponent.vue';

export default {
  components: { ChildComponent },
  setup() {
    const appName = ref('My Awesome App');
    const theme = ref('light');

    const toggleTheme = () => {
      theme.value = theme.value === 'light' ? 'dark' : 'light';
    };

    // Provide a readonly reactive value for appName
    provide('appName', readonly(appName));

    // Provide a reactive value and a method to modify it for theme
    provide('theme', {
      theme: readonly(theme), // Expose theme as readonly
      toggleTheme // Expose the method to change theme
    });

    return {
      theme // Expose theme to App.vue's template for its own class binding
    };
  },
};
</script>

<style>
.app-container {
  padding: 20px;
  border: 2px solid #3498db;
  border-radius: 10px;
  margin-bottom: 20px;
}
.dark-theme {
  background-color: #333;
  color: white;
}
</button> {
  margin-top: 10px;
  padding: 8px 15px;
  border-radius: 4px;
  cursor: pointer;
}
</style>

// components/ChildComponent.vue (Child Component that Injects)
<template>
  <div :class="{ 'dark-theme': theme.theme.value === 'dark' }" class="child-container">
    <h2>Child Component</h2>
    <p>App Name from Parent: {{ appName }}</p>
    <p>Current Theme: {{ theme.theme.value }}</p>
    <button @click="theme.toggleTheme">Toggle Theme from Child</button>
  </div>
</template>

<script>
import { inject } from 'vue';

export default {
  setup() {
    // Inject values provided by a parent
    const appName = inject('appName');
    const theme = inject('theme'); // Injects { theme: Ref<string>, toggleTheme: Function }

    return {
      appName,
      theme,
    };
  },
};
</script>

<style scoped>
.child-container {
  padding: 15px;
  border: 1px dashed #2ecc71;
  border-radius: 8px;
  margin: 10px 0;
}
.dark-theme {
  background-color: #555;
  color: #eee;
}
</style>