我們可解到頁面由 Islands 組成代表的每個區塊都分開處理 , 不過有些時候 , 我們還是希望 Islands 中的資料能互通有無
Astro 提供了一個工具 Nanostore 讓我們可以把 React 中的 data 與 Vue 中的 data 做同步
今天我們就來用一個小範例來使用 Nanostore 吧!
npm create astro@latest nanostore-test -- --template basics --no-install --no-git --typescript relaxed
# add vue framework
npx astro add vue -y
# add react framework
npx astro add react -y
Counter.jsx
import { useState } from 'react';
const counterStyle = {
display: 'grid',
fontSize: '2em',
gridTemplateColumns: 'repeat(3, minmax(0, 1fr))',
placeItems: 'center',
marginTop:'2em',
backgroundColor:'blue'
};
export default function Counter({
children,
count: initialCount,
}) {
const [count, setCount] = useState(initialCount);
const add = () => setCount((i) => i + 1);
const subtract = () => setCount((i) => i - 1);
return (
<>
<div style={counterStyle}>
<button onClick={subtract}>-</button>
<pre>{count}</pre>
<button onClick={add}>+</button>
</div>
</>
);
}
Counter.vue
<template>
<div class="counter">
<button @click="subtract()">-</button>
<pre>{{ count }}</pre>
<button @click="add()">+</button>
</div>
</template>
<script>
import { ref } from 'vue';
export default {
setup() {
const count = ref(0);
const add = () => (count.value = count.value + 1);
const subtract = () => (count.value = count.value - 1);
return {
count,
add,
subtract,
};
},
};
</script>
<style>
.counter {
display: grid;
font-size: 2em;
grid-template-columns: repeat(3, minmax(0, 1fr));
margin-top: 2em;
place-items: center;
background-color: greenyellow ;
}
</style>
# add nanostores
npm install nanostores @nanostores/react @nanostores/vue
store/counter.js
import { atom } from 'nanostores';
export const storeCounter = atom(0);
import { useStore } from '@nanostores/react';
import { storeCounter } from 'store/counter.js';
// read the store value with the `useStore` hook
const $counter = useStore(storeCounter);
// write to the new value to store using `.set`
storeCounter.set($counter+1)
<script setup>
import { useStore } from '@nanostores/vue';
import { storeCounter } from 'store/counter.js';
// read the store value with the `useStore` hook
const $counter = useStore(storeCounter);
const add = () => storeCounter.set($counter+1)
const subtract = () => storeCounter.set($counter-1)
</script>
nanostore.astro
---
import ReactCounter from '../components/NanoCounter.jsx';
import VueCounter from '../components/NanoCounter.vue';
---
<main>
<ReactCounter client:only="react" />
<VueCounter client:only="vue"/>
</main>