Files
smartDriveEEUniApp/pages/speaking_training_expression/speaking_training_expression.vue
2026-01-09 19:41:18 +08:00

241 lines
5.7 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<view class="expression-page">
<view class="hero">
<view class="hero-title">表达</view>
<view class="hero-desc">聚焦即兴与情感让表达更流畅更有感染力</view>
</view>
<view class="subtabs">
<view
v-for="tab in subTabs"
:key="tab.id"
class="subtab"
:class="{ active: tab.id === activeId }"
@click="switchSub(tab.id)"
>
<text class="subtab-name">{{ tab.name }}</text>
<text class="subtab-tip">{{ tab.brief }}</text>
</view>
</view>
<view class="panel" v-if="activeTab">
<view class="panel-header">
<view class="panel-title">{{ activeTab.name }}</view>
<view class="panel-subtitle">{{ activeTab.subtitle }}</view>
</view>
<view class="points">
<view v-for="item in activeTab.points" :key="item.title" class="point-card">
<view class="point-title">{{ item.title }}</view>
<view class="point-body">{{ item.body }}</view>
</view>
</view>
<view class="actions">
<view class="action-card">
<view class="action-title">练习方法</view>
<view class="action-body">{{ activeTab.practice }}</view>
</view>
<view class="action-card">
<view class="action-title">复盘提示</view>
<view class="action-body">{{ activeTab.review }}</view>
</view>
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
activeId: 'improv',
subTabs: [
{
id: 'improv',
name: '即兴表达',
brief: '现场反应、结构、落点',
subtitle: '快速组织开头-主体-结尾,确保 30 秒内给出清晰框架',
points: [
{ title: '框架', body: 'FAB/SCQA/总-分-总任选其一,句首给结论或预告结构。' },
{ title: '铺垫', body: '用 1-2 个事实或案例支撑,每段不超过 3 句,控制语速。' },
{ title: '收束', body: '结尾重复结论+下一步,避免无声结尾或跑题。' },
],
practice: '用 3 组随机词做 60 秒即兴10 秒想结构40 秒输出10 秒总结;录音回听框架是否完整。',
review: '检查是否有“嗯”“啊”等口癖、是否给出明确结论与行动项,如缺失下次优先补齐开头结尾。',
},
{
id: 'emotion',
name: '情感表达',
brief: '情绪、共情、故事化',
subtitle: '通过语气、停顿与例子传递温度,让信息更易被接受',
points: [
{ title: '语气层次', body: '主张句提升能量,关怀句放慢语速、降低音量,形成对比。' },
{ title: '共情回应', body: '用“我理解…”“听起来…”先反馈感受,再给建议或方案。' },
{ title: '故事化', body: '用“冲突-转折-结果”讲 mini case结尾抛问题或启发。' },
],
practice: '选一则客户场景,录制两版:平铺直叙 vs. 强调情感对比,回听音色/停顿变化;保留对比更强的版本。',
review: '看听众是否能复述你的核心观点,若不能,精简信息点并增加停顿与例子。',
},
],
};
},
computed: {
activeTab() {
return this.subTabs.find((t) => t.id === this.activeId);
},
},
methods: {
switchSub(id) {
this.activeId = id;
},
},
onShow() {
uni.setNavigationBarTitle({ title: '表达' });
},
};
</script>
<style>
.expression-page {
min-height: 100vh;
padding: 12px 12px calc(64px + env(safe-area-inset-bottom));
background: #f7f8fb;
box-sizing: border-box;
}
.hero {
background: linear-gradient(135deg, #ff8b6a, #ffb58a);
color: #ffffff;
border-radius: 14px;
padding: 16px 14px;
margin-bottom: 12px;
box-shadow: 0 8px 22px rgba(0, 0, 0, 0.08);
}
.hero-title {
font-size: 20px;
font-weight: 700;
margin-bottom: 6px;
}
.hero-desc {
font-size: 13px;
opacity: 0.92;
}
.subtabs {
display: flex;
gap: 8px;
margin-bottom: 12px;
}
.subtab {
flex: 1;
background: #ffffff;
border: 1px solid #e6e8ed;
border-radius: 10px;
padding: 10px 8px;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.04);
transition: all 0.15s ease;
}
.subtab.active {
border-color: #ff986f;
box-shadow: 0 6px 18px rgba(255, 152, 111, 0.22);
}
.subtab-name {
display: block;
font-weight: 600;
font-size: 14px;
margin-bottom: 4px;
color: #1f2933;
}
.subtab-tip {
display: block;
font-size: 12px;
color: #6b7280;
}
.panel {
background: #ffffff;
border-radius: 14px;
padding: 14px 12px 16px;
box-shadow: 0 10px 26px rgba(0, 0, 0, 0.08);
}
.panel-header {
margin-bottom: 10px;
}
.panel-title {
font-size: 16px;
font-weight: 700;
color: #111827;
margin-bottom: 4px;
}
.panel-subtitle {
font-size: 13px;
color: #4b5563;
}
.points {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 8px;
margin-bottom: 12px;
}
.point-card {
background: #f8fafc;
border: 1px solid #e5e7eb;
border-radius: 10px;
padding: 10px 8px;
min-height: 100px;
box-sizing: border-box;
}
.point-title {
font-size: 13px;
font-weight: 700;
color: #111827;
margin-bottom: 6px;
}
.point-body {
font-size: 12px;
color: #4b5563;
line-height: 1.5;
}
.actions {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 8px;
}
.action-card {
background: #f9fafb;
border: 1px solid #e5e7eb;
border-radius: 10px;
padding: 10px 10px 12px;
}
.action-title {
font-size: 13px;
font-weight: 700;
color: #111827;
margin-bottom: 6px;
}
.action-body {
font-size: 12px;
color: #4b5563;
line-height: 1.5;
}
</style>