面试题答案
一键面试- 安装Pinia 在Qwik项目根目录下,使用npm或yarn安装Pinia:
npm install pinia
# 或者
yarn add pinia
- 在Qwik中集成Pinia
- 创建Pinia实例:在项目合适位置(如
src/stores
目录)创建一个pinia.ts
文件。
- 创建Pinia实例:在项目合适位置(如
import { createPinia } from 'pinia';
export const pinia = createPinia();
- 在Qwik应用中使用Pinia:在
main.ts
文件中导入并使用刚刚创建的Pinia实例。
import { createQwikCity } from '@builder.io/qwik-city';
import { render } from '@builder.io/qwik/server';
import { pinia } from './stores/pinia';
const app = createQwikCity({
render,
setupApp: (ctx) => {
ctx.rootContext.inject(pinia);
},
});
export default app;
- 创建Pinia Store
在
src/stores
目录下创建具体的store文件,例如counterStore.ts
。
import { defineStore } from 'pinia';
export const useCounterStore = defineStore('counter', {
state: () => ({
count: 0
}),
actions: {
increment() {
this.count++;
}
}
});
- 在Qwik组件中使用Pinia Store 在Qwik组件中导入并使用store。
import { component$, useStore } from '@builder.io/qwik';
import { useCounterStore } from '../stores/counterStore';
export default component$(() => {
const counterStore = useStore(useCounterStore);
return (
<div>
<p>Count: {counterStore.count}</p>
<button onClick$={() => counterStore.increment()}>Increment</button>
</div>
);
});
- 数据订阅
- 直接监听state变化:在组件内,可以使用
watch
函数监听store中state的变化。例如,在counterStore
中监听count
的变化。
- 直接监听state变化:在组件内,可以使用
import { watch } from '@builder.io/qwik';
import { useStore } from '@builder.io/qwik';
import { useCounterStore } from '../stores/counterStore';
export default component$(() => {
const counterStore = useStore(useCounterStore);
watch(() => counterStore.count, (newValue) => {
console.log('Count has changed to:', newValue);
});
return (
<div>
<p>Count: {counterStore.count}</p>
<button onClick$={() => counterStore.increment()}>Increment</button>
</div>
);
});
- 使用subscribe:在store中可以使用
subscribe
方法来监听store的变化。在counterStore.ts
中添加如下代码:
import { defineStore } from 'pinia';
export const useCounterStore = defineStore('counter', {
state: () => ({
count: 0
}),
actions: {
increment() {
this.count++;
}
},
subscribe: (mutation, state) => {
console.log('Store mutation:', mutation);
console.log('New state:', state);
}
});
- 更新频率控制
- 防抖(Debounce):如果有频繁触发的操作导致store更新,可以使用防抖函数。例如,在一个搜索框输入事件中更新store,防止频繁更新。
import { useStore } from '@builder.io/qwik';
import { useCounterStore } from '../stores/counterStore';
import { debounce } from 'lodash';
export default component$(() => {
const counterStore = useStore(useCounterStore);
const debouncedIncrement = debounce(() => {
counterStore.increment();
}, 300);
return (
<div>
<input type="text" onInput$={() => debouncedIncrement()} />
</div>
);
});
- 节流(Throttle):类似地,可以使用节流函数来限制更新频率。例如,每1秒允许更新一次store。
import { useStore } from '@builder.io/qwik';
import { useCounterStore } from '../stores/counterStore';
import { throttle } from 'lodash';
export default component$(() => {
const counterStore = useStore(useCounterStore);
const throttledIncrement = throttle(() => {
counterStore.increment();
}, 1000);
return (
<div>
<input type="text" onInput$={() => throttledIncrement()} />
</div>
);
});
- 性能优化
- 按需加载Store:如果应用中有多个store,并且某些store不是在应用启动时就需要的,可以使用动态导入。例如,在路由组件中,当路由匹配时才导入相应的store。
import { component$, useStore } from '@builder.io/qwik';
import { useRouter } from '@builder.io/qwik-city';
export default component$(() => {
const router = useRouter();
let counterStore;
if (router.currentRoute.path === '/specific-route') {
const { useCounterStore } = await import('../stores/counterStore');
counterStore = useStore(useCounterStore);
}
return (
<div>
{counterStore && (
<>
<p>Count: {counterStore.count}</p>
<button onClick$={() => counterStore.increment()}>Increment</button>
</>
)}
</div>
);
});
- Memoization(记忆化):在store的getters中使用记忆化,避免重复计算。例如,在
counterStore.ts
中添加一个记忆化的getter。
import { defineStore } from 'pinia';
export const useCounterStore = defineStore('counter', {
state: () => ({
count: 0
}),
actions: {
increment() {
this.count++;
}
},
getters: {
doubleCount: (state) => {
return state.count * 2;
}
}
});
这里doubleCount
的计算结果会被缓存,只有当count
变化时才会重新计算。