feat: add faq items
This commit is contained in:
24
components/BasketButton.vue
Normal file
24
components/BasketButton.vue
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
<script lang="ts" setup>
|
||||||
|
defineProps({
|
||||||
|
isVisible: Boolean,
|
||||||
|
})
|
||||||
|
|
||||||
|
const rStore = useRecipeStore()
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<button
|
||||||
|
v-show="rStore.displayedRecipe.length !== rStore.recipes.length && isVisible"
|
||||||
|
class="fixed z-9 inline-flex cursor-pointer items-center justify-center rounded rounded-full shadow hover:shadow-md"
|
||||||
|
bg="green-50 dark:green-900" w="10" h="10"
|
||||||
|
bottom="18" right="4"
|
||||||
|
text="green-600 dark:green-300"
|
||||||
|
>
|
||||||
|
<span v-if="rStore.displayedRecipe.length">
|
||||||
|
<div i-mdi-bowl-mix-outline />
|
||||||
|
</span>
|
||||||
|
<span v-else>
|
||||||
|
<div i-mdi-bowl-outline />
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
</template>
|
||||||
@@ -3,16 +3,12 @@ import { storeToRefs } from 'pinia'
|
|||||||
import type { StuffItem } from '~/data/food'
|
import type { StuffItem } from '~/data/food'
|
||||||
import { meat, staple, tools, vegetable } from '~/data/food'
|
import { meat, staple, tools, vegetable } from '~/data/food'
|
||||||
|
|
||||||
import { useInvisibleElement } from '~/composables/helper'
|
|
||||||
import { useEmojiAnimation } from '~/composables/animation'
|
import { useEmojiAnimation } from '~/composables/animation'
|
||||||
import { useRecipe } from '~/composables/recipe'
|
|
||||||
|
|
||||||
const rStore = useRecipeStore()
|
const rStore = useRecipeStore()
|
||||||
const { curTool } = storeToRefs(rStore)
|
const { curTool } = storeToRefs(rStore)
|
||||||
const curStuff = computed(() => rStore.selectedStuff)
|
const curStuff = computed(() => rStore.selectedStuff)
|
||||||
|
|
||||||
const { displayedRecipe, clickTool } = useRecipe(rStore.recipes)
|
|
||||||
|
|
||||||
const recipeBtn = ref<HTMLButtonElement>()
|
const recipeBtn = ref<HTMLButtonElement>()
|
||||||
const { playAnimation } = useEmojiAnimation(recipeBtn)
|
const { playAnimation } = useEmojiAnimation(recipeBtn)
|
||||||
|
|
||||||
@@ -35,30 +31,9 @@ function toggleStuff(item: StuffItem, category = '', _e?: Event) {
|
|||||||
action: item.name,
|
action: item.name,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const recipePanel = ref()
|
|
||||||
const { isVisible, show } = useInvisibleElement(recipePanel)
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<Transition>
|
|
||||||
<button
|
|
||||||
v-show="displayedRecipe.length !== rStore.recipes.length && isVisible"
|
|
||||||
ref="recipeBtn"
|
|
||||||
class="fixed z-9 inline-flex cursor-pointer items-center justify-center rounded rounded-full shadow hover:shadow-md"
|
|
||||||
bg="green-50 dark:green-900" w="10" h="10" bottom="4" right="4"
|
|
||||||
text="green-600 dark:green-300"
|
|
||||||
@click="show"
|
|
||||||
>
|
|
||||||
<span v-if="displayedRecipe.length">
|
|
||||||
<div i-mdi-bowl-mix-outline />
|
|
||||||
</span>
|
|
||||||
<span v-else>
|
|
||||||
<div i-mdi-bowl-outline />
|
|
||||||
</span>
|
|
||||||
</button>
|
|
||||||
</Transition>
|
|
||||||
|
|
||||||
<h2 m="t-4" text="xl" font="bold" p="1">
|
<h2 m="t-4" text="xl" font="bold" p="1">
|
||||||
🥘 先选一下食材
|
🥘 先选一下食材
|
||||||
</h2>
|
</h2>
|
||||||
@@ -123,7 +98,7 @@ const { isVisible, show } = useInvisibleElement(recipePanel)
|
|||||||
<ToolTag
|
<ToolTag
|
||||||
v-for="item, i in tools" :key="i"
|
v-for="item, i in tools" :key="i"
|
||||||
:active="curTool === item.name"
|
:active="curTool === item.name"
|
||||||
@click="clickTool(item)"
|
@click="rStore.clickTool(item)"
|
||||||
>
|
>
|
||||||
<span v-if="item.emoji" class="inline-flex">{{ item.emoji }}</span>
|
<span v-if="item.emoji" class="inline-flex">{{ item.emoji }}</span>
|
||||||
<span v-else-if="item.icon" class="inline-flex">
|
<span v-else-if="item.icon" class="inline-flex">
|
||||||
@@ -137,44 +112,5 @@ const { isVisible, show } = useInvisibleElement(recipePanel)
|
|||||||
</ToolTag>
|
</ToolTag>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div ref="recipePanel" m="2 t-4" p="2" class="relative shadow transition hover:shadow-md" bg="gray-400/8">
|
<RecipePanel />
|
||||||
<h2 text="xl" font="bold" p="1">
|
|
||||||
🍲 来看看组合出的菜谱吧!
|
|
||||||
</h2>
|
|
||||||
|
|
||||||
<ToggleMode />
|
|
||||||
|
|
||||||
<!-- <Switch /> -->
|
|
||||||
<div class="cook-recipes" p="2">
|
|
||||||
<SearchFoodInput />
|
|
||||||
|
|
||||||
<Transition mode="out-in">
|
|
||||||
<div class="cook-filter-recipes">
|
|
||||||
<span v-if="!curStuff.length && !curTool" text="sm" p="2">
|
|
||||||
你要先选食材或工具哦~
|
|
||||||
</span>
|
|
||||||
|
|
||||||
<span v-else-if="displayedRecipe.length">
|
|
||||||
<DishTag v-for="item, i in displayedRecipe" :key="i" :dish="item" />
|
|
||||||
</span>
|
|
||||||
|
|
||||||
<span v-else text="sm">
|
|
||||||
还没有完美匹配的菜谱呢……
|
|
||||||
<br>
|
|
||||||
大胆尝试一下,或者<a href="#" @click="rStore.reset()">
|
|
||||||
<strong>换个组合</strong></a>?
|
|
||||||
<br>
|
|
||||||
<span m="t-1">欢迎来
|
|
||||||
<a class="font-bold text-blue-600 dark:text-blue-400" href="https://docs.qq.com/sheet/DQk1vdkhFV0twQVNS?tab=uykkic" target="_blank">这里</a>
|
|
||||||
反馈新的菜谱!
|
|
||||||
</span>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</Transition>
|
|
||||||
|
|
||||||
<hr m="y-2">
|
|
||||||
|
|
||||||
<RandomRecipe />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
25
components/FAQItem.vue
Normal file
25
components/FAQItem.vue
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
<script lang="ts" setup>
|
||||||
|
import { Disclosure, DisclosureButton, DisclosurePanel } from '@headlessui/vue'
|
||||||
|
|
||||||
|
defineProps<{
|
||||||
|
title: string
|
||||||
|
}>()
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<Disclosure v-slot="{ open }" as="div" class="mt-2">
|
||||||
|
<DisclosureButton
|
||||||
|
class="w-full flex justify-between rounded-lg bg-purple-100 px-4 py-2 text-left text-sm font-medium text-purple-900 hover:bg-purple-200 focus:outline-none focus-visible:ring focus-visible:ring-purple-500 focus-visible:ring-opacity-75"
|
||||||
|
>
|
||||||
|
<span>{{ title }}</span>
|
||||||
|
<div
|
||||||
|
i-ri-arrow-drop-up-line
|
||||||
|
:class="open ? 'rotate-180 transform' : ''"
|
||||||
|
class="h-5 w-5 text-purple-500"
|
||||||
|
/>
|
||||||
|
</DisclosureButton>
|
||||||
|
<DisclosurePanel class="px-2 pb-2 pt-4 text-sm text-gray-500">
|
||||||
|
<slot />
|
||||||
|
</DisclosurePanel>
|
||||||
|
</Disclosure>
|
||||||
|
</template>
|
||||||
53
components/RecipePanel.vue
Normal file
53
components/RecipePanel.vue
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
<script lang="ts" setup>
|
||||||
|
const recipePanel = ref()
|
||||||
|
const rStore = useRecipeStore()
|
||||||
|
|
||||||
|
const { isVisible, show } = useInvisibleElement(recipePanel)
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<Transition>
|
||||||
|
<BasketButton :is-visible="isVisible" @click="show" />
|
||||||
|
</Transition>
|
||||||
|
|
||||||
|
<div ref="recipePanel" m="2 t-4" p="2" class="recipe-panel relative shadow transition hover:shadow-md" bg="gray-400/8">
|
||||||
|
<h2 text="xl" font="bold" p="1">
|
||||||
|
🍲 来看看组合出的菜谱吧!
|
||||||
|
</h2>
|
||||||
|
|
||||||
|
<ToggleMode />
|
||||||
|
|
||||||
|
<!-- <Switch /> -->
|
||||||
|
<div class="cook-recipes" p="2">
|
||||||
|
<SearchFoodInput />
|
||||||
|
|
||||||
|
<Transition mode="out-in">
|
||||||
|
<div class="cook-filter-recipes">
|
||||||
|
<span v-if="!rStore.selectedStuff.length && !rStore.curTool" text="sm" p="2">
|
||||||
|
你要先选食材或工具哦~
|
||||||
|
</span>
|
||||||
|
|
||||||
|
<span v-else-if="rStore.displayedRecipe.length">
|
||||||
|
<DishTag v-for="item, i in rStore.displayedRecipe" :key="i" :dish="item" />
|
||||||
|
</span>
|
||||||
|
|
||||||
|
<span v-else text="sm">
|
||||||
|
还没有完美匹配的菜谱呢……
|
||||||
|
<br>
|
||||||
|
大胆尝试一下,或者<a href="#" @click="rStore.reset()">
|
||||||
|
<strong>换个组合</strong></a>?
|
||||||
|
<br>
|
||||||
|
<span m="t-1">欢迎来
|
||||||
|
<a class="font-bold text-blue-600 dark:text-blue-400" href="https://docs.qq.com/sheet/DQk1vdkhFV0twQVNS?tab=uykkic" target="_blank">这里</a>
|
||||||
|
反馈新的菜谱!
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</Transition>
|
||||||
|
|
||||||
|
<hr m="y-2">
|
||||||
|
|
||||||
|
<RandomRecipe />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
51
components/TheBottomMenu.vue
Normal file
51
components/TheBottomMenu.vue
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
<script lang="ts" setup>
|
||||||
|
import type { BottomMenuItem } from '@yunlefun/vue'
|
||||||
|
import { ref } from 'vue'
|
||||||
|
|
||||||
|
const items: BottomMenuItem[] = [
|
||||||
|
{
|
||||||
|
icon: 'i-ri-home-line',
|
||||||
|
activeIcon: 'i-ri-home-fill',
|
||||||
|
title: '首页',
|
||||||
|
to: '/',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'i-ri-compass-2-line',
|
||||||
|
activeIcon: 'i-ri-compass-2-fill',
|
||||||
|
title: '关于',
|
||||||
|
to: '/about',
|
||||||
|
},
|
||||||
|
// {
|
||||||
|
// icon: 'i-ri-user-line',
|
||||||
|
// activeIcon: 'i-ri-user-fill',
|
||||||
|
// title: '我的',
|
||||||
|
// to: '/user',
|
||||||
|
// },
|
||||||
|
{
|
||||||
|
icon: 'i-ri-question-line',
|
||||||
|
activeIcon: 'i-ri-question-fill',
|
||||||
|
title: '帮助',
|
||||||
|
to: '/help',
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
const router = useRouter()
|
||||||
|
|
||||||
|
const active = ref('/')
|
||||||
|
function onClick(item: BottomMenuItem) {
|
||||||
|
active.value = item.to || ''
|
||||||
|
router.push(item.to || '/')
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<YlfBottomMenu shadow-2xl>
|
||||||
|
<YlfBottomMenuItem
|
||||||
|
v-for="item in items"
|
||||||
|
:key="item.to"
|
||||||
|
:item="item"
|
||||||
|
:active="active === item.to"
|
||||||
|
@click="onClick"
|
||||||
|
/>
|
||||||
|
</YlfBottomMenu>
|
||||||
|
</template>
|
||||||
@@ -1,11 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<nav text-xl p="t-6">
|
<div>
|
||||||
<NuxtLink class="mx-2 icon-btn" to="/" title="首页">
|
|
||||||
<div i-ri-home-2-line />
|
|
||||||
</NuxtLink>
|
|
||||||
|
|
||||||
<DarkToggle />
|
|
||||||
|
|
||||||
<NuxtLink class="mx-2 icon-btn hover:text-orange-400" to="/help" title="帮助">
|
<NuxtLink class="mx-2 icon-btn hover:text-orange-400" to="/help" title="帮助">
|
||||||
<div i-ri-question-line />
|
<div i-ri-question-line />
|
||||||
</NuxtLink>
|
</NuxtLink>
|
||||||
@@ -21,5 +15,5 @@
|
|||||||
<a class="hover:text-black-400 mx-2 icon-btn" rel="noreferrer" href="https://github.com/YunYouJun/cook" target="_blank" title="GitHub">
|
<a class="hover:text-black-400 mx-2 icon-btn" rel="noreferrer" href="https://github.com/YunYouJun/cook" target="_blank" title="GitHub">
|
||||||
<div i-ri-github-line />
|
<div i-ri-github-line />
|
||||||
</a>
|
</a>
|
||||||
</nav>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@@ -1,12 +1,12 @@
|
|||||||
|
import type { MaybeComputedElementRef } from '@vueuse/core'
|
||||||
import { isClient, useElementBounding } from '@vueuse/core'
|
import { isClient, useElementBounding } from '@vueuse/core'
|
||||||
import type { Ref } from 'vue'
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* trigger show invisible element
|
* trigger show invisible element
|
||||||
* @param target
|
* @param target
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
export function useInvisibleElement(target: Ref<HTMLElement>) {
|
export function useInvisibleElement(target: MaybeComputedElementRef<HTMLElement>) {
|
||||||
const { top } = useElementBounding(target)
|
const { top } = useElementBounding(target)
|
||||||
|
|
||||||
const isVisible = computed(() => {
|
const isVisible = computed(() => {
|
||||||
|
|||||||
@@ -1,81 +0,0 @@
|
|||||||
import { storeToRefs } from 'pinia'
|
|
||||||
import type { Recipes } from '~/types'
|
|
||||||
|
|
||||||
import type { StuffItem } from '~/data/food'
|
|
||||||
import { useRecipeStore } from '~/composables/store/recipe'
|
|
||||||
|
|
||||||
export function useRecipe(recipe: Recipes) {
|
|
||||||
const gtm = useGtm()
|
|
||||||
|
|
||||||
const rStore = useRecipeStore()
|
|
||||||
const { curMode, curTool } = storeToRefs(rStore)
|
|
||||||
const curStuff = computed(() => rStore.selectedStuff)
|
|
||||||
|
|
||||||
// 默认严格模式
|
|
||||||
const displayedRecipe = computed(() => {
|
|
||||||
// if keyword exist, return result directly
|
|
||||||
const keyword = rStore.keyword
|
|
||||||
if (keyword)
|
|
||||||
return recipe.filter(item => item.name.includes(keyword))
|
|
||||||
|
|
||||||
if (curMode.value === 'strict') {
|
|
||||||
return recipe.filter((item) => {
|
|
||||||
const stuffFlag = curStuff.value.every(stuff => item.stuff.includes(stuff))
|
|
||||||
const toolFlag = item.tools?.includes(curTool.value)
|
|
||||||
return curTool.value ? (stuffFlag && toolFlag) : stuffFlag
|
|
||||||
})
|
|
||||||
}
|
|
||||||
else if (curMode.value === 'loose') {
|
|
||||||
return recipe.filter((item) => {
|
|
||||||
const stuffFlag = curStuff.value.some(stuff => item.stuff.includes(stuff))
|
|
||||||
const toolFlag = item.tools?.includes(curTool.value)
|
|
||||||
|
|
||||||
// 同时存在 厨具和材料,则同时判断
|
|
||||||
if (curTool.value && curStuff.value.length) {
|
|
||||||
return stuffFlag && toolFlag
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (curStuff.value.length)
|
|
||||||
return stuffFlag
|
|
||||||
else if (curTool.value)
|
|
||||||
return toolFlag
|
|
||||||
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
// survival
|
|
||||||
else {
|
|
||||||
return recipe.filter((item) => {
|
|
||||||
const stuffFlag = item.stuff.every(stuff => curStuff.value.includes(stuff))
|
|
||||||
const toolFlag = item.tools?.includes(curTool.value)
|
|
||||||
return curTool.value ? (stuffFlag && toolFlag) : stuffFlag
|
|
||||||
})
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
/**
|
|
||||||
* toggle tool
|
|
||||||
* @param item
|
|
||||||
*/
|
|
||||||
const clickTool = (item: StuffItem) => {
|
|
||||||
const value = item.name
|
|
||||||
rStore.toggleTools(value)
|
|
||||||
|
|
||||||
gtm?.trackEvent({
|
|
||||||
event: 'click',
|
|
||||||
category: `tool_${value}`,
|
|
||||||
action: 'click_tool',
|
|
||||||
label: '工具',
|
|
||||||
})
|
|
||||||
gtm?.trackEvent({
|
|
||||||
event: 'click_tool',
|
|
||||||
action: item.name,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
displayedRecipe,
|
|
||||||
clickTool,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -3,6 +3,7 @@ import { useStorage } from '@vueuse/core'
|
|||||||
import type { RecipeItem, Recipes } from '~/types'
|
import type { RecipeItem, Recipes } from '~/types'
|
||||||
|
|
||||||
import recipeData from '~/data/recipe.json'
|
import recipeData from '~/data/recipe.json'
|
||||||
|
import type { StuffItem } from '~/data/food'
|
||||||
|
|
||||||
const namespace = 'cook'
|
const namespace = 'cook'
|
||||||
|
|
||||||
@@ -80,6 +81,69 @@ export const useRecipeStore = defineStore('recipe', () => {
|
|||||||
|
|
||||||
const randomRecipe = ref<RecipeItem>(generateRandomRecipe(recipes))
|
const randomRecipe = ref<RecipeItem>(generateRandomRecipe(recipes))
|
||||||
|
|
||||||
|
const gtm = useGtm()
|
||||||
|
|
||||||
|
// 默认严格模式
|
||||||
|
const displayedRecipe = computed(() => {
|
||||||
|
if (keyword.value)
|
||||||
|
return recipes.filter(item => item.name.includes(keyword.value))
|
||||||
|
|
||||||
|
if (curMode.value === 'strict') {
|
||||||
|
return recipes.filter((item) => {
|
||||||
|
const stuffFlag = selectedStuff.value.every(stuff => item.stuff.includes(stuff))
|
||||||
|
const toolFlag = item.tools?.includes(curTool.value)
|
||||||
|
return curTool.value ? (stuffFlag && toolFlag) : stuffFlag
|
||||||
|
})
|
||||||
|
}
|
||||||
|
else if (curMode.value === 'loose') {
|
||||||
|
return recipes.filter((item) => {
|
||||||
|
const stuffFlag = selectedStuff.value.some(stuff => item.stuff.includes(stuff))
|
||||||
|
const toolFlag = item.tools?.includes(curTool.value)
|
||||||
|
|
||||||
|
// 同时存在 厨具和材料,则同时判断
|
||||||
|
if (curTool.value && selectedStuff.value.length) {
|
||||||
|
return stuffFlag && toolFlag
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (selectedStuff.value.length)
|
||||||
|
return stuffFlag
|
||||||
|
else if (curTool.value)
|
||||||
|
return toolFlag
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
// survival
|
||||||
|
else {
|
||||||
|
return recipes.filter((item) => {
|
||||||
|
const stuffFlag = item.stuff.every(stuff => selectedStuff.value.includes(stuff))
|
||||||
|
const toolFlag = item.tools?.includes(curTool.value)
|
||||||
|
return curTool.value ? (stuffFlag && toolFlag) : stuffFlag
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
/**
|
||||||
|
* toggle tool
|
||||||
|
* @param item
|
||||||
|
*/
|
||||||
|
const clickTool = (item: StuffItem) => {
|
||||||
|
const value = item.name
|
||||||
|
toggleTools(value)
|
||||||
|
|
||||||
|
gtm?.trackEvent({
|
||||||
|
event: 'click',
|
||||||
|
category: `tool_${value}`,
|
||||||
|
action: 'click_tool',
|
||||||
|
label: '工具',
|
||||||
|
})
|
||||||
|
gtm?.trackEvent({
|
||||||
|
event: 'click_tool',
|
||||||
|
action: item.name,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
recipes,
|
recipes,
|
||||||
|
|
||||||
@@ -98,6 +162,10 @@ export const useRecipeStore = defineStore('recipe', () => {
|
|||||||
setMode,
|
setMode,
|
||||||
|
|
||||||
addStuff,
|
addStuff,
|
||||||
|
|
||||||
|
// useRecipe
|
||||||
|
displayedRecipe,
|
||||||
|
clickTool,
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,8 @@
|
|||||||
title: 关于
|
title: 关于
|
||||||
---
|
---
|
||||||
|
|
||||||
|
:AboutMenu
|
||||||
|
|
||||||
### **🍜 好的,今天我们来做菜!**
|
### **🍜 好的,今天我们来做菜!**
|
||||||
|
|
||||||
> 希望大家吃的开心!
|
> 希望大家吃的开心!
|
||||||
@@ -54,11 +56,11 @@ Hello,我是云游君。
|
|||||||
此外,我也会继续尝试做一些有趣或有用的东西,并分享给大家。
|
此外,我也会继续尝试做一些有趣或有用的东西,并分享给大家。
|
||||||
你也可以在这些地方找到我。
|
你也可以在这些地方找到我。
|
||||||
|
|
||||||
<!-- :AboutMe -->
|
:AboutMe
|
||||||
|
|
||||||
对了,给微信公众号「云游君」发送「做菜」也可以快速找到这个网址。
|
对了,给微信公众号「云游君」发送「做菜」也可以快速找到这个网址。
|
||||||
|
|
||||||
## [**赞助者**](https://sponsors.yunyoujun.cn)
|
## 赞助者
|
||||||
|
|
||||||
也非常感谢至今以来的所有赞助者们!
|
也非常感谢至今以来的所有赞助者们!
|
||||||
|
|
||||||
|
|||||||
@@ -1,38 +0,0 @@
|
|||||||
---
|
|
||||||
title: 帮助
|
|
||||||
---
|
|
||||||
|
|
||||||
- 相关链接
|
|
||||||
- [居家菜谱投稿](https://docs.qq.com/form/page/DWk9GWW9oTmlXZU9V)
|
|
||||||
- [晒晒你的菜](https://docs.qq.com/sheet/DQk1vdkhFV0twQVNS?tab=dmeahc)
|
|
||||||
- [反馈建议](https://docs.qq.com/sheet/DQk1vdkhFV0twQVNS?tab=snaau2)
|
|
||||||
- 网站相关
|
|
||||||
- 故障/新功能反馈:[Issues](https://github.com/YunYouJun/cook/issues)
|
|
||||||
- 交流/建议/分享:[Discussions](https://github.com/YunYouJun/cook/issues)
|
|
||||||
|
|
||||||
## **模式说明**
|
|
||||||
|
|
||||||
- 模糊匹配:展示所有含当前选中任意食材的菜谱
|
|
||||||
- 精准匹配:展示所有含当前选中所有食材的菜谱
|
|
||||||
- 生存模式:展示当前选中食材即可制作的所有菜谱
|
|
||||||
|
|
||||||
## **友情提示**
|
|
||||||
|
|
||||||
- 点击首页最上方的大锅图标,可清空所选食材和工具。
|
|
||||||
<!-- - 本项目支持 PWA,使用浏览器打开时,可将其添加到主屏幕以获得近原生 APP 的体验。 -->
|
|
||||||
|
|
||||||
<!-- <InstallPwa /> -->
|
|
||||||
|
|
||||||
## FAQ
|
|
||||||
|
|
||||||
### 页面无法点击、资源加载失败?
|
|
||||||
|
|
||||||
> 试试「无痕模式」是否正常?
|
|
||||||
|
|
||||||
1. 清除 Cookie(点击浏览器网址前方的 🔒 图标,找到 Cookie 并清除)
|
|
||||||
2. 🔒 图标,网站数据(清除)
|
|
||||||
3. 强制刷新缓存
|
|
||||||
- Windows: `Ctrl + F5`
|
|
||||||
- macOS: `Cmd + Shift + R`
|
|
||||||
|
|
||||||
<br />
|
|
||||||
@@ -1,7 +1,8 @@
|
|||||||
<template>
|
<template>
|
||||||
<main class="px-4 text-center text-gray-700 dark:text-gray-200">
|
<main class="text-center text-gray-700 dark:text-gray-200" p="b-15">
|
||||||
<Menu />
|
|
||||||
<slot />
|
<slot />
|
||||||
<BaseFooter />
|
<BaseFooter />
|
||||||
|
<DarkToggle absolute right-5 top-5 />
|
||||||
|
<TheBottomMenu fixed bottom-0 left-0 right-0 />
|
||||||
</main>
|
</main>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -14,7 +14,10 @@ export default defineNuxtConfig({
|
|||||||
'@nuxtjs/color-mode',
|
'@nuxtjs/color-mode',
|
||||||
'@vite-pwa/nuxt',
|
'@vite-pwa/nuxt',
|
||||||
'@nuxt/content',
|
'@nuxt/content',
|
||||||
|
|
||||||
'@zadigetvoltaire/nuxt-gtm',
|
'@zadigetvoltaire/nuxt-gtm',
|
||||||
|
|
||||||
|
'@yunlefun/vue/nuxt',
|
||||||
],
|
],
|
||||||
|
|
||||||
experimental: {
|
experimental: {
|
||||||
|
|||||||
@@ -23,6 +23,7 @@
|
|||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@antfu/eslint-config": "^0.39.8",
|
"@antfu/eslint-config": "^0.39.8",
|
||||||
|
"@headlessui/vue": "^1.7.15",
|
||||||
"@iconify-json/carbon": "^1.1.18",
|
"@iconify-json/carbon": "^1.1.18",
|
||||||
"@iconify-json/fe": "^1.1.6",
|
"@iconify-json/fe": "^1.1.6",
|
||||||
"@iconify-json/gg": "^1.1.5",
|
"@iconify-json/gg": "^1.1.5",
|
||||||
@@ -40,6 +41,7 @@
|
|||||||
"@vite-pwa/nuxt": "^0.1.0",
|
"@vite-pwa/nuxt": "^0.1.0",
|
||||||
"@vue/test-utils": "^2.4.1",
|
"@vue/test-utils": "^2.4.1",
|
||||||
"@vueuse/nuxt": "^10.2.1",
|
"@vueuse/nuxt": "^10.2.1",
|
||||||
|
"@yunlefun/vue": "^0.0.7",
|
||||||
"@zadigetvoltaire/nuxt-gtm": "^0.0.13",
|
"@zadigetvoltaire/nuxt-gtm": "^0.0.13",
|
||||||
"consola": "^3.2.3",
|
"consola": "^3.2.3",
|
||||||
"cross-env": "^7.0.3",
|
"cross-env": "^7.0.3",
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<main class="markdown-body text-left">
|
<main class="markdown-body px-4 text-left">
|
||||||
<ContentDoc v-slot="{ doc }">
|
<ContentDoc v-slot="{ doc }">
|
||||||
<h1>{{ doc.title }}</h1>
|
<h1>{{ doc.title }}</h1>
|
||||||
<ContentRenderer :value="doc" />
|
<ContentRenderer :value="doc" />
|
||||||
|
|||||||
92
pages/help.vue
Normal file
92
pages/help.vue
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
<script lang="ts" setup>
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="w-full px-2 pt-8">
|
||||||
|
<h1 text-2xl font="bold" my="4">
|
||||||
|
帮助
|
||||||
|
</h1>
|
||||||
|
<div class="mx-auto max-w-md w-full rounded-2xl bg-white p-2" text-left>
|
||||||
|
<FAQItem title="什么是模式?">
|
||||||
|
<ul>
|
||||||
|
<li>模糊匹配:展示所有含当前选中任意食材的菜谱</li>
|
||||||
|
<li>精准匹配:展示所有含当前选中所有食材的菜谱</li>
|
||||||
|
<li>生存模式:展示当前选中食材即可制作的所有菜谱</li>
|
||||||
|
</ul>
|
||||||
|
</FAQItem>
|
||||||
|
|
||||||
|
<FAQItem title="如何快速清空所选食材和工具?">
|
||||||
|
<div inline-flex items-center justify-center>
|
||||||
|
点击顶部 <div i-mdi-pot-steam-outline mx-1 inline-block /> 图标即可。
|
||||||
|
</div>
|
||||||
|
</FAQItem>
|
||||||
|
|
||||||
|
<FAQItem title="是否有 APP?">
|
||||||
|
<b>暂时没有开发 APP 的计划。</b>
|
||||||
|
<br>
|
||||||
|
但我们正在优化 PWA 的体验,以便您可以直接将本站添加到桌面,并享受类似 APP 的体验。
|
||||||
|
<br>
|
||||||
|
敬请期待!
|
||||||
|
</FAQItem>
|
||||||
|
|
||||||
|
<FAQItem title="页面无法点击、资源加载失败?">
|
||||||
|
<blockquote>
|
||||||
|
试试「无痕模式」是否正常?
|
||||||
|
</blockquote>
|
||||||
|
<br>
|
||||||
|
<ol>
|
||||||
|
<li>
|
||||||
|
<b>清除 Cookie</b>
|
||||||
|
<ol>
|
||||||
|
<li>
|
||||||
|
点击浏览器网址前方的 🔒 图标
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
点击「Cookie」并清除
|
||||||
|
</li>
|
||||||
|
</ol>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<b>强制刷新缓存</b>
|
||||||
|
<ul>
|
||||||
|
<li>Windows: <code>Ctrl + F5</code></li>
|
||||||
|
<li>macOS: <code>Cmd + Shift + R</code></li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
</ol>
|
||||||
|
</FAQItem>
|
||||||
|
|
||||||
|
<FAQItem title="其他相关链接">
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
相关链接
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<a href="https://docs.qq.com/form/page/DWk9GWW9oTmlXZU9V" target="_blank">居家菜谱投稿</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="https://docs.qq.com/sheet/DQk1vdkhFV0twQVNS?tab=dmeahc" target="_blank">晒晒你的菜</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="https://docs.qq.com/sheet/DQk1vdkhFV0twQVNS?tab=snaau2" target="_blank">反馈建议</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
网站相关
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
故障/新功能反馈:
|
||||||
|
<a href="https://github.com/YunYouJun/cook/issues" target="_blank">Issues</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
交流/建议/分享:
|
||||||
|
<a href="https://github.com/YunYouJun/cook/issues" target="_blank">Discussions</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</FAQItem>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
7
pages/settings.vue
Normal file
7
pages/settings.vue
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<button>
|
||||||
|
设置
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
7
pages/user.vue
Normal file
7
pages/user.vue
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<button>
|
||||||
|
<div i-ri-user-line />
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
19
pnpm-lock.yaml
generated
19
pnpm-lock.yaml
generated
@@ -13,6 +13,9 @@ devDependencies:
|
|||||||
'@antfu/eslint-config':
|
'@antfu/eslint-config':
|
||||||
specifier: ^0.39.8
|
specifier: ^0.39.8
|
||||||
version: 0.39.8(eslint@8.46.0)(typescript@5.1.6)
|
version: 0.39.8(eslint@8.46.0)(typescript@5.1.6)
|
||||||
|
'@headlessui/vue':
|
||||||
|
specifier: ^1.7.15
|
||||||
|
version: 1.7.15(vue@3.3.4)
|
||||||
'@iconify-json/carbon':
|
'@iconify-json/carbon':
|
||||||
specifier: ^1.1.18
|
specifier: ^1.1.18
|
||||||
version: 1.1.18
|
version: 1.1.18
|
||||||
@@ -64,6 +67,9 @@ devDependencies:
|
|||||||
'@vueuse/nuxt':
|
'@vueuse/nuxt':
|
||||||
specifier: ^10.2.1
|
specifier: ^10.2.1
|
||||||
version: 10.2.1(nuxt@3.6.3)(rollup@2.79.1)(vue@3.3.4)
|
version: 10.2.1(nuxt@3.6.3)(rollup@2.79.1)(vue@3.3.4)
|
||||||
|
'@yunlefun/vue':
|
||||||
|
specifier: ^0.0.7
|
||||||
|
version: 0.0.7
|
||||||
'@zadigetvoltaire/nuxt-gtm':
|
'@zadigetvoltaire/nuxt-gtm':
|
||||||
specifier: ^0.0.13
|
specifier: ^0.0.13
|
||||||
version: 0.0.13(nuxt@3.6.3)(rollup@2.79.1)(vue@3.3.4)
|
version: 0.0.13(nuxt@3.6.3)(rollup@2.79.1)(vue@3.3.4)
|
||||||
@@ -1956,6 +1962,15 @@ packages:
|
|||||||
'@hapi/hoek': 9.3.0
|
'@hapi/hoek': 9.3.0
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/@headlessui/vue@1.7.15(vue@3.3.4):
|
||||||
|
resolution: {integrity: sha512-3ozVEgQ8mw09nWvUPN+8S6C8l3SM0lVT1aEN/+oP5Y4LF0WNMM9UrVisVTN9LLQ06v/X3EFA0blyL/vg8XNZlg==}
|
||||||
|
engines: {node: '>=10'}
|
||||||
|
peerDependencies:
|
||||||
|
vue: ^3.2.0
|
||||||
|
dependencies:
|
||||||
|
vue: 3.3.4
|
||||||
|
dev: true
|
||||||
|
|
||||||
/@humanwhocodes/config-array@0.11.10:
|
/@humanwhocodes/config-array@0.11.10:
|
||||||
resolution: {integrity: sha512-KVVjQmNUepDVGXNuoRRdmmEjruj0KfiGSbS8LVc12LMsWDQzRXJ0qdhN8L8uUigKpfEHRhlaQFY0ib1tnUbNeQ==}
|
resolution: {integrity: sha512-KVVjQmNUepDVGXNuoRRdmmEjruj0KfiGSbS8LVc12LMsWDQzRXJ0qdhN8L8uUigKpfEHRhlaQFY0ib1tnUbNeQ==}
|
||||||
engines: {node: '>=10.10.0'}
|
engines: {node: '>=10.10.0'}
|
||||||
@@ -4109,6 +4124,10 @@ packages:
|
|||||||
resolution: {integrity: sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==}
|
resolution: {integrity: sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/@yunlefun/vue@0.0.7:
|
||||||
|
resolution: {integrity: sha512-d5CSyg5LDlg/r6lm+99MZrlS9TzqmAA+pEM+7CpezkhsRkRpqXJWg/K12dex7hcewC9gRYb3GrEVnI7NeAuhTw==}
|
||||||
|
dev: true
|
||||||
|
|
||||||
/@zadigetvoltaire/nuxt-gtm@0.0.13(nuxt@3.6.3)(rollup@2.79.1)(vue@3.3.4):
|
/@zadigetvoltaire/nuxt-gtm@0.0.13(nuxt@3.6.3)(rollup@2.79.1)(vue@3.3.4):
|
||||||
resolution: {integrity: sha512-7SgXtIB8uLdLGJaoUAQSGCSbRnNzplNkNVFKIHaVI4We0vqghstBoVPlJCJ9VdwsfdNyk3/C+Lh1uKpzTrtEuw==}
|
resolution: {integrity: sha512-7SgXtIB8uLdLGJaoUAQSGCSbRnNzplNkNVFKIHaVI4We0vqghstBoVPlJCJ9VdwsfdNyk3/C+Lh1uKpzTrtEuw==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
|
|||||||
@@ -5,3 +5,32 @@
|
|||||||
list-style: disc;
|
list-style: disc;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
blockquote {
|
||||||
|
border-left: 0.25em solid #ddd;
|
||||||
|
padding: 0 1em;
|
||||||
|
color: #777;
|
||||||
|
quotes: '\\201C''\\201D''\\2018''\\2019';
|
||||||
|
}
|
||||||
|
|
||||||
|
ol {
|
||||||
|
list-style: decimal;
|
||||||
|
padding-left: 2em;
|
||||||
|
|
||||||
|
li {
|
||||||
|
line-height: 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ul {
|
||||||
|
list-style: disc;
|
||||||
|
padding-left: 2em;
|
||||||
|
|
||||||
|
li {
|
||||||
|
line-height: 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
border-bottom: 1px dashed #ddd;
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,7 +0,0 @@
|
|||||||
{
|
|
||||||
"rewrites": [
|
|
||||||
{ "source": "/about", "destination": "/index.html" },
|
|
||||||
{ "source": "/help", "destination": "/index.html" },
|
|
||||||
{ "source": "/wechat", "destination": "/index.html" }
|
|
||||||
]
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user