当前位置: 首页 > article >正文

vue高频八股

一、基础知识1.二、指令概念带有v-前缀的特殊html属性用于在模板中表达逻辑用于将响应式数据绑定到 DOM 元素上或在 DOM 元素上进行一些操作。1.v-if和v-show有什么区别1v - if功能条件渲染。当表达式的值为 true 时该元素及其包含的所有子元素会被渲染到 DOM 中当表达式的值为 false 时该元素将不会被渲染到 DOM 中template中对应的DOM会被转化为注释。性能具有惰性渲染的特性在初始渲染时如果条件为假则不会执行任何渲染操作直到条件变为真才会开始渲染。切换时涉及创建或销毁 DOM 元素因此有较高的切换开销但对初次渲染有优化效果。使用场景适合那些需要根据条件决定是否生成 DOM 的情况或者在不需要渲染大量未使用的 DOM 时2v-show功能条件显示。不论条件真假元素总是会被渲染到 DOM 中只是通过CSS 的 display属性来控制元素的可见性display: none/block/flex/gird等。性能在初始渲染时会一次性编译并添加所有元素到 DOM 树中之后只通过修改样式来切换元素的显示状态所以其初始渲染开销可能较大但在切换显示隐藏状态时由于仅涉及 CSS 属性的改变性能消耗相对较小。使用场景适用于频繁切换显示/隐藏状态且 DOM 结构较为复杂的情况因为避免了反复创建和销毁 DOM 元素带来的性能损耗。2.v - if 和 v - else - if / v - elsev - if根据表达式的值决定是否渲染元素。v - else - if在 v - if 之后使用提供额外的条件判断。v - else与 v - if 或者 v - else - if 配合使用当前面的条件不满足时渲染内容。template div !-- 输入分数 -- input typenumber v-modelscore placeholder输入分数(0-100) / !-- 根据分数显示等级 -- p v-ifscore 90优秀 /p p v-else-ifscore 60及格 /p p v-else不及格 /p /div /template script setup import { ref } from vue const score ref(0) /script3.v - show类似于 v - if但不同之处在于它通过 CSS 的 display 属性控制元素显示/隐藏DOM 元素始终会被渲染只是切换可见性。template div !-- 切换按钮 -- button clicktoggle切换显示/隐藏/button !-- v-show 控制显示隐藏 -- p v-showisVisible我会显示和隐藏/p /div /template script setup import { ref } from vue const isVisible ref(true) const toggle () { isVisible.value !isVisible.value } /script4.v - for用于循环渲染列表或数组数据可以遍历数组、对象或生成迭代器的任何可迭代对象。template div !-- 最简单的遍历数组 -- ul li v-forfruit in fruits{{ fruit }}/li /ul /div /template script setup import { ref } from vue const fruits ref([苹果, 香蕉, 橙子, 葡萄]) /script5.v - bind简写 :绑定元素属性到实例数据例如 v - bind:href url 可以动态绑定链接地址简写为 :href url。1动态绑定链接template div !-- 最基础的用法动态绑定属性 -- img v-bind:srcimageUrl alt图片 / !-- 简写最常用 -- img :srcimageUrl alt图片 / /div /template script setup import { ref } from vue const imageUrl ref(https://picsum.photos/200/100) /script2动态绑定 classtemplate !-- 根据 isActive 决定是否高亮 -- div :class{ active: isActive }我是内容/div button clickisActive !isActive切换高亮/button /template script setup import { ref } from vue const isActive ref(false) /script style .active { background-color: yellow; font-weight: bold; } /style注意div :class{ active: isActive }我是内容/div{ active: isActive } 一个对象active是 CSS 类名就是 style 里那个 .activeisActive是一个变量true 或 false所以当isActivetrue时说明active有效所以classactive则下面的style的.active才会作用到div上。效果:class 动态开关 CSS 类样式写在style里而:style 动态写 CSS 属性值样式直接写在行内3动态绑定 styletemplate !-- 动态改变文字颜色 -- p :style{ color: textColor }我会变颜色/p button clicktextColor red变红/button button clicktextColor blue变蓝/button /template script setup import { ref } from vue const textColor ref(black) /script4批量绑定多个属性template !-- 用对象一次性绑定多个属性 -- div v-bindattrs批量绑定/div /template script setup const attrs { id: myDiv, class: box highlight, data-id: 123, title: 鼠标悬停提示 } /script6.v - on简写 绑定事件例如 v - on:click method 可以绑定点击事件简写为 click method。1点击事件 传参数template button clicksayName(小明)点我/button /template script setup const sayName (name) { alert(我叫 name) } /script2直接写简单逻辑不用单独定义函数template button clickcount点击次数{{ count }}/button /template script setup import { ref } from vue const count ref(0) /script3鼠标移入/移出事件template div mouseenterisHover true mouseleaveisHover false :style{ background: isHover ? yellow : gray } 鼠标移进来变黄 /div /template script setup import { ref } from vue const isHover ref(false) /script4获取事件对象template input inputhandleInput / /template script setup const handleInput (event) { console.log(event.target.value) // 打印输入框的内容 } /script5 阻止默认行为比如阻止表单提交刷新页面template form submit.preventsubmitForm button typesubmit提交/button /form /template script setup const submitForm () { console.log(表单提交了但页面没刷新) } /script6常用事件修饰符很实用template !-- 阻止冒泡 -- div clickparentClick button click.stopchildClick点我/button /div !-- 只触发一次 -- button click.oncedoOnce只生效一次/button !-- 回车键触发 -- input keyup.entersearch / !-- 阻止默认行为简写 -- a hrefhttps://baidu.com click.preventgo链接/a /template7.v - model用于表单元素的双向数据绑定。template div !-- v-model 绑定输入框 -- input v-modelmessage placeholder输入点什么... / p你输入的是{{ message }}/p /div /template script setup import { ref } from vue const message ref() /script注用input写template input :valuemessage inputmessage $event.target.value / p{{ message }}/p /templatev-model 就是上面那两行代码的语法糖三、渐进式框架的理解1.模块化渐进式框架通常将功能划分为多个独立的模块或组件每个模块可以单独引入和使用这样开发者可以根据项目需求选择性地集成所需的部分。2.低侵入性它不会强制要求开发者遵循严格的规则集或重构整个应用才能使用框架而是尽可能地与现有代码库和第三方库无缝融合。例子你有个老项目里面全是 jQuery 写的没问题你在某个角落里用 Vue 写一个点赞按钮其他 jQuery 代码照跑不误Vue 不会说你那个 jQuery 必须删掉听我的。3.灵活性开发者能够轻松地从小规模开始仅使用框架的基本功能并随着项目的复杂度增加逐步添加更高级的功能。4.可扩展性框架的设计支持自定义扩展这意味着开发者可以在需要时构建自己的插件或模块来满足特定业务需求。5.易于上手四、vue的生命周期beforeCreate是new Vue() 之后触发的第一个钩子在当前阶段 data、methods、computed 以及 watch 上的数据和方法都不能被访问。created在实例创建完成后发生当前阶段已经完成了数据观测也就是可以使用数据更改数据在这里更改数据不会触发 updated 函数。可以做一些初始数据的获取在当前阶段无法与 Dom 进行交互如果非要想可以通过 vm.$nextTick 来访问 Dom。beforeMount发生在挂载之前在这之前 template 模板已导入渲染函数编译。而当前阶段虚拟 Dom 已经创建完成即将开始渲染。在此时也可以对数据进行更改不会触发 updated。mounted在挂载完成后发生在当前阶段真实的 Dom 挂载完毕数据完成双向绑定可以访问到 Dom 节点使用 $refs 属性对 Dom 进行操作。beforeUpdate发生在更新之前也就是响应式数据发生更新虚拟 dom 重新渲染之前被触发你可以在当前阶段进行更改数据不会造成重渲染。updated发生在更新完成之后当前阶段组件 Dom 已完成更新。要注意的是避免在此期间更改数据因为这可能会导致无限循环的更新。beforeDestroyVue2/beforeUnmountVue3发生在实例销毁之前在当前阶段实例完全可以被使用我们可以在这时进行善后收尾工作比如清除计时器。destroyedVue2/unmountedVue3发生在实例销毁之后这个时候只剩下了 dom 空壳。组件已被拆解数据绑定被卸除监听被移出子实例也统统被销毁。activatedkeep - alive 专属组件被激活时调用。deactivatedkeep - alive 专属组件被移除时调用。errorCaptured错误被捕获时调用。五、双向数据绑定原理什么是双向数据绑定 数据变 → 页面变页面变输入框打字→ 数据变。input v-modelname / p{{ name }}/p你在输入框打张name自动变张页面也跟着显示张。核心原理怎么知道数据变了答案监控数据的变化数据一变化就去更新页面。Vue 2 和 Vue 3 监控数据变化的方式不一样。1.vue2:Object.defineProperty2.vue3:Proxy代理六、虚拟 DOM 实现原理七、computed 的实现原理computed 和 watch 有什么区别及运用场景八、为什么在 Vue3.0 采用了 Proxy抛弃了 Object.defineProperty九、Vue 组件间通信有哪些方式1.父子组件通信1props:父传子父组件把数据通过props递给子组件子组件只能用不能改。在子组件定义const props defineProps([属性名1属性名2......])在父组件中v-bind:属性1父组件要传递的数据!-- 父组件 Parent.vue -- template div Child :money1000 :task写代码 / /div /template script setup import Child from ./Child.vue /script!-- 子组件 Child.vue -- template div p老板给了{{ props.money }}块钱/p p任务{{ props.task }}/p /div /template script setup // 定义要接收什么 const props defineProps([money, task]) // 可以用但不能改 props.money 2000 ❌ 会报错 /script注意!-- 父组件 Parent.vue -- template div Child :moneydollar :taskobj / /div /template script setup import Child from ./Child.vue import {ref} from vue const dollarref(0); const objref({ work1 }) /script那么在子组件的template中就应该是props.money props.obj.work2$emit发出子传父子组件向父组件传递数据通过触发自定义事件。子组件触发一个事件父组件监听这个事件。就像员工喊老板我干完了老板听到后给奖励。子组件中定义const emit defineEmits([done]),done也可以是其他自定义的值和定义const propsdefineProps([属性名])一样const finishWork () {emit(done,xxx)}父组件中v-on:done父组件中要除非的函数例子子组件emit(done)触发 → 父组件done监听到 → 执行handleDone!-- 子组件 Child.vue -- template div button clickfinishWork任务完成/button /div /template script setup 1. 声明我这个组件会发出一个叫 done 的事件 const emit defineEmits([done]) 2. 函数执行会触发发出 done 事件并可以带数据 const finishWork () { emit(done, 任务已完成请验收) // 触发事件可以带数据 } /script!-- 父组件 Parent.vue -- template div 3. 监听父组件监听到这个事件就执行handleDone函数 Child donehandleDone / p{{ message }}/p /div /template script setup import { ref } from vue import Child from ./Child.vue const message ref() const handleDone (data) { message.value data // 收到子组件的汇报任务已完成请验收 alert(奖励100块) } /script3ref:略2.隔代组件通信爷孙组件1$attrs / $listeners透传爸爸组件里要props辅助特点爷爷组件要向孙子组件传递属性或者方法要经过爸爸组件。$attrs 包含了父作用域中不被 props 所识别且获取的特性绑定class 和 style 除外。当一个组件没有声明任何 props 时这里会包含所有父作用域的绑定class 和 style 除外并且可以通过 v - bind $attrs 传入内部组件。通常配合 inheritAttrs 选项一起使用。$listeners 包含了父作用域中的不含.native 修饰器的v - on 事件监听器。它可以通过 v - on $listeners 传入内部组件。这里爷爷组件传了三个属性/函数给爸爸组件!-- 爷爷组件 -- template Parent :money1000 :task写代码 successhandleSuccess / /template script setup import Parent from ./Parent.vue const handleSuccess (msg) { console.log(收到, msg) } /script!-- 爸爸组件中间人 -- template p爸爸自己用了{{ money }}元/p !-- 爸爸自己只用了 money其他没有的属性原样传给孙子 -- Child v-bind$attrs v-on$listeners / v-bind$attrs透传属性 v-on$listeners透传事件(在vue3中这个被合并到$attrs了所以其实不 用写v-on$listenersv-bind$attrs把属性和事件全透传了) /template script setup import Child from ./Child.vue 爸爸只声明了 money所以 task 和 success 事件就变成了 $attrs defineProps([money]) 如果爸爸组件什么都没声明defineProps([])则爷爷传给爸爸的数据会全部传给孙子 /script!-- 孙子组件 -- template div !-- 孙子直接收到爷爷的 task 和事件 -- p任务{{ $attrs.task }}/p button click$attrs.onSuccess(干完了)汇报/button /div /template2provide / inject依赖注入特点爷爷组件要向孙子组件传递属性或者方法不用经过爸爸组件处理同意。祖先组件中通过 provider 来提供变量然后在子孙组件中通过 inject 来注入变量。provide / inject API 主要解决了跨级组件间的通信问题不过它的使用场景主要是子组件获取上级组件的状态跨级组件间建立了一种主动提供与依赖注入的关系。使用场景a祖宗组件和后代组件b状态提示当有多个组件需要使用到同一个状态(state)(数据)时。可以将state提升到这些组件共同的祖先组件中声明所有这些组件便都可以通过祖先元素来访问到这个state。例子 eg: 在共同祖宗组件中 import {provide, ref} from vue const count ref(0); const increment function(){ count.value; } 设置依赖注入 provide(count, { count, increment }); // ↑ ↑ // 数据 方法 在组件想要用祖宗组件数据的各个后代组件中 import { ref , inject} from vue 依赖注入从count中拿 const { count, increment } inject(count);3.兄弟组件通信1EventBus$emit / $on通过一个空的 Vue 实例作为中央事件总线事件中心用它来触发事件和监听事件从而实现任何组件间的通信包括父子、隔代、兄弟组件。2Vuex / Pinia用于状态管理适用于复杂的应用场景。

相关文章:

vue高频八股

一、基础知识:1.二、指令:概念:带有v-前缀的特殊html属性,用于在模板中表达逻辑,用于将响应式数据绑定到 DOM 元素上或在 DOM 元素上进行一些操作。1.v-if和v-show有什么区别:(1)v -…...

别再硬啃C++了!用LabVIEW玩转海康工业相机,从枚举设备到存BMP图保姆级教程

用LabVIEW轻松驾驭海康工业相机:从设备发现到图像保存全流程解析 工业视觉领域的技术门槛往往让许多开发者望而却步,尤其是面对复杂的C SDK文档时。但如果你熟悉LabVIEW的图形化编程环境,完全可以避开底层代码的困扰,快速实现海康…...

低空智联网:构建未来空中信息高速公路的架构蓝图

1. 低空智联网:重新定义空中信息高速公路 想象一下这样的场景:数百架无人机在城市上空有序穿梭,有的在配送快递,有的在监测空气质量,还有的在执行紧急救援任务。它们彼此之间能够实时通信,自动避让&#xf…...

从统计到生成建模的多变量分布采样

原文:towardsdatascience.com/sampling-from-multivariate-distributions-from-statistical-to-generative-modeling-0177e55a9061 https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/37181833a50332ce6287a8359b435e89.png 来源…...

PCL快速部署指南:Ubuntu20下APT安装与版本管理技巧

1. 为什么选择APT安装PCL? 第一次接触点云库PCL的朋友,可能会被它的依赖关系吓到。我自己刚开始折腾的时候,光是解决VTK、FLANN这些依赖项的版本冲突就花了两天时间。后来发现,对于大多数应用场景来说,直接用Ubuntu的…...

Adafruit micro:bit库深度解析:Arduino嵌入式开发实战

1. Adafruit micro:bit 库技术解析:面向嵌入式工程师的 Arduino 集成实践指南micro:bit 是一款由英国 BBC 主导开发、专为青少年编程教育设计的微型嵌入式开发板,其核心控制器为 Nordic Semiconductor 的 nRF51822 —— 一颗集成 Cortex-M0 内核、2.4GHz…...

网站 SEO 检测报告如何与网站分析数据进行对比分析_网站 SEO 检测报告中的页面结构分析有什么用

网站 SEO 检测报告如何与网站分析数据进行对比分析 在当今的互联网时代,网站的成功与否往往取决于其在搜索引擎上的排名。因此,网站 SEO(搜索引擎优化)检测报告和网站分析数据的对比分析显得尤为重要。通过对比分析,可…...

嵌入式Boa Web服务器搭建与优化指南

1. 嵌入式轻量级Web服务器搭建实战:Boa移植与应用 作为一名在嵌入式领域摸爬滚打多年的工程师,我深知在资源受限环境下搭建Web服务的痛点。今天要分享的Boa服务器方案,正是解决这类问题的利器——这个仅有70KB的可执行文件,却能稳…...

SecGPT-14B知识库更新:让OpenClaw掌握最新CVE漏洞检测能力

SecGPT-14B知识库更新:让OpenClaw掌握最新CVE漏洞检测能力 1. 为什么需要持续更新漏洞知识库 去年我在用OpenClaw做自动化安全扫描时,发现一个尴尬现象:虽然它能完美识别2022年前的常见漏洞特征,但对新曝光的CVE漏洞却总是"…...

嵌入式C语言宏定义实战技巧与安全规范

1. 嵌入式开发中宏定义的核心价值在嵌入式C语言开发领域,宏定义(Macro)是每个工程师必须掌握的利器。不同于普通变量或函数,宏在预处理阶段就完成文本替换,这种特性带来了四大核心优势:可移植性强化&#x…...

OpenClaw性能调优:千问3.5-9B响应速度提升30%的实操方法

OpenClaw性能调优:千问3.5-9B响应速度提升30%的实操方法 1. 为什么需要性能调优 第一次在本地部署OpenClaw对接千问3.5-9B模型时,我被它的响应速度惊到了——平均每个简单指令需要等待5-7秒才能得到响应。作为一个追求效率的工具,这样的延迟…...

OpenClaw跨平台控制:千问3.5-35B-A3B-FP8任务手机端触发方案

OpenClaw跨平台控制:千问3.5-35B-A3B-FP8任务手机端触发方案 1. 为什么需要移动端触发自动化任务? 上周三凌晨两点,我被手机闹铃惊醒——服务器监控报警显示生产环境出现异常。当我手忙脚乱打开电脑准备排查时,突然想到&#xf…...

OpenClaw+Qwen2.5-VL-7B:低成本自动化学习助手

OpenClawQwen2.5-VL-7B:低成本自动化学习助手 1. 为什么需要自动化学习助手 作为一个经常需要处理大量学习资料的开发者,我一直在寻找能够提升学习效率的工具。传统的学习方式需要手动整理资料、做笔记、制作练习题,这些重复性工作不仅耗时…...

飞书机器人接入指南:OpenClaw调用千问3.5-27B实现智能问答

飞书机器人接入指南:OpenClaw调用千问3.5-27B实现智能问答 1. 为什么选择OpenClaw飞书千问的组合? 去年我负责团队的知识管理时,每天要处理大量技术文档的检索和摘要需求。最初尝试用现成的SaaS机器人,但遇到三个痛点&#xff1…...

OpenClaw植物养护仪:Qwen3-14b_int4_awq分析的传感器数据与照料建议

OpenClaw植物养护仪:Qwen3-14b_int4_awq分析的传感器数据与照料建议 1. 为什么需要智能植物养护助手 去年冬天,我养了三年的一盆琴叶榕突然开始落叶。作为程序员,我第一反应是写个脚本监控它的生长状态——但很快发现,植物养护远…...

Supabase注册与新增用户全解析:5个关键区别及适用场景指南

Supabase用户管理系统设计指南:注册与手动创建的5大核心差异 在构建现代SaaS平台时,用户管理系统往往是整个架构的基石。Supabase作为开源的Firebase替代方案,提供了完整的认证和用户管理解决方案。但很多开发者在使用过程中,常常…...

从智能音箱到医疗设备:RC正弦波振荡器的10个意想不到的应用场景

从智能音箱到医疗设备:RC正弦波振荡器的10个意想不到的应用场景 在电子工程领域,RC正弦波振荡器就像一位低调的幕后英雄,它不显山露水,却在无数设备中默默发挥着关键作用。这种基于运算放大器和RC网络的经典电路,以其结…...

如何利用 Bing Webmaster Tools 来优化 SEO 自然排名

如何利用 Bing Webmaster Tools 来优化 SEO 自然排名 在当今互联网的竞争环境中,搜索引擎优化(SEO)是一个至关重要的环节。而在众多搜索引擎中,Bing作为全球第二大搜索引擎,其市场份额在逐年增长。因此,如…...

轻松搞定Excel公式错误:SpreadJS让表格开发不再头疼

在技术领域,我们常常被那些闪耀的、可见的成果所吸引。今天,这个焦点无疑是大语言模型技术。它们的流畅对话、惊人的创造力,让我们得以一窥未来的轮廓。然而,作为在企业一线构建、部署和维护复杂系统的实践者,我们深知…...

LongCat 为 OpenClaw 装上效率引擎:你的自动化任务还能再快 30%

在技术领域,我们常常被那些闪耀的、可见的成果所吸引。今天,这个焦点无疑是大语言模型技术。它们的流畅对话、惊人的创造力,让我们得以一窥未来的轮廓。然而,作为在企业一线构建、部署和维护复杂系统的实践者,我们深知…...

2026年04月04日最热门的开源项目(Github)

根据本期榜单的数据,可以从多个维度对项目进行分析: 1. 项目分布 语言使用情况:榜单中使用的编程语言包括JavaScript(1个项目)、TypeScript(6个项目)、Python(5个项目)…...

OpenClaw+Qwen3.5-9B低成本运营:个人自媒体内容自动化生产

OpenClawQwen3.5-9B低成本运营:个人自媒体内容自动化生产 1. 为什么选择这个技术组合 去年开始全职做科技类自媒体后,我发现自己陷入了"创作-发布-运营"的死亡循环。每周要产出3篇技术文章,还要同步到6个平台,最后连陪…...

学术海报自动生成:OpenClaw+Phi-3-vision科研工作流实践

学术海报自动生成:OpenClawPhi-3-vision科研工作流实践 1. 为什么需要自动化海报生成 作为一名经常参加学术会议的科研工作者,我深刻体会到制作学术海报的痛苦。每次会议前,我们团队都要花费大量时间在PPT或Photoshop中手动调整布局、对齐文…...

OpenClaw技能开发入门:为Qwen3.5-9B定制图片分类插件

OpenClaw技能开发入门:为Qwen3.5-9B定制图片分类插件 1. 为什么需要开发图片分类技能 上周整理手机相册时,我对着3000多张杂乱无章的照片头疼不已——旅行风景、工作截图、宠物照片全都混在一起。手动分类不仅耗时费力,还经常因为主观判断不…...

Kmestepper:单头称重控制系统嵌入式协同驱动框架

1. Kmestepper 库概述:面向单头称重控制系统的嵌入式运动与称重协同驱动框架Kmestepper 是专为 KmeIoT 单头称重设备(1-Head Weigher Device)设计的嵌入式底层驱动库,其核心定位并非通用步进电机或称重传感器抽象层,而…...

别再乱开槽了!手把手教你用HFSS仿真设计一个带Wi-Fi陷波的超宽带天线

别再乱开槽了!手把手教你用HFSS仿真设计一个带Wi-Fi陷波的超宽带天线 在射频工程实践中,超宽带天线设计常面临一个棘手问题:如何在不影响整体性能的前提下,精准抑制特定干扰频段。以2.4GHz Wi-Fi频段为例,当它与其他通…...

别再死记硬背了!用这10个XSS-Labs关卡,手把手教你理解前端过滤与绕过逻辑

从XSS-Labs关卡构建前端安全思维模型:10个实战场景解析 当你在浏览器地址栏输入javascript:alert(1)时,是否思考过为什么有些网站会弹出对话框而有些却毫无反应?这背后隐藏着前端工程师与安全研究者之间持续多年的攻防博弈。XSS-Labs作为经典…...

大疆照片的‘测绘模式’和‘畸变矫正’到底怎么用?一个案例讲清测绘项目中的元数据配置要点

大疆无人机测绘实战:从参数配置到三维建模的精度控制全解析 去年参与某开发区1:500地形测绘项目时,我们团队使用大疆Mavic 3E无人机采集数据后,在ContextCapture中空三解算时遇到了模型局部扭曲的问题。经过排查发现,问题根源竟是…...

别急着重装!Makefile报错‘Command not found‘的通用排查思路:以蜂鸟E203的RISC-V工具链为例

Makefile报错"Command not found"的深度排查指南:从RISC-V工具链到通用解决方案 当你满怀期待地克隆了一个开源项目,准备开始编译时,终端却无情地抛出一行红色错误:"riscv-nuclei-elf-gcc: Command not found"…...

【几何之美】莫利定理(Morley‘s Theorem)的视觉化证明与初中数学思维

1. 莫利定理:藏在三角形里的数学奇迹 第一次听说莫利定理时,我正盯着教室墙上的三角板发呆。谁能想到,这个看似普通的几何图形里,竟然藏着如此精妙的规律——把任意三角形的三个内角各分成三等份,靠近每条边的两条三等…...