一个空间怎么放多个网站如何策划网络推广方案
一、基础概念与核心特性
1. Vue3 相比 Vue2 的改进(通俗版)
问题:Vue3 比 Vue2 好在哪?
 答案:
- 更快: 
- Proxy 代理:Vue2 的响应式像“逐个监听保险箱”(每个属性单独监听),Vue3 的 Proxy 像“直接监控整个房间”(监听整个对象变化)。
 - 编译优化:Vue3 在编译阶段标记哪些是动态内容(如 
{{ count }}),更新时跳过静态内容(如纯文字)。 
 - 更小:通过 Tree-shaking(摇树优化),只打包你用到的功能,减少代码体积。
 - 更好用: 
- Composition API:像搭积木一样组合逻辑(比如把“计数器逻辑”抽成函数,多个组件复用)。
 - 新组件: 
<Teleport>:把组件渲染到任意位置(比如弹窗放到 body 下,避免被父组件样式影响)。<Suspense>:优雅处理异步加载(比如数据加载时显示 Loading 动画)。
 
 
2. Composition API vs Options API(场景对比)
问题:为什么要用 Composition API?
 答案:
-  
Options API(Vue2 风格):
- 把代码按类型分块(data、methods、生命周期),适合简单组件。
 - 缺点:逻辑分散,比如一个“搜索功能”的 data、methods 可能分布在多处。
 
// Options API 示例 export default { data() { return { keyword: '' } }, methods: { search() { ... } }, mounted() { this.search() } } -  
Composition API(Vue3 风格):
- 在 
setup()中,按功能组织代码(比如把搜索相关的数据、方法写在一起)。 - 优点:逻辑复用更方便(类似 React Hooks)。
 
// Composition API 示例 export default { setup() { const keyword = ref(''); const search = () => { ... }; onMounted(search); return { keyword, search }; } } - 在 
 
二、响应式原理(手绘理解)
3. Vue3 的响应式原理
问题:Vue3 如何实现数据变化自动更新视图?
 答案:
-  
Proxy 代理对象:
- 当你修改数据时,Proxy 会“拦截”操作(比如 
obj.a = 1),通知视图更新。 - 对比 Vue2:Vue2 使用 
Object.defineProperty,无法监听新增属性和数组下标变化(必须用this.$set)。 
 - 当你修改数据时,Proxy 会“拦截”操作(比如 
 -  
代码模拟(简化版):
function reactive(obj) { return new Proxy(obj, { get(target, key) { console.log('读取了', key); return Reflect.get(target, key); }, set(target, key, value) { console.log('更新了', key); return Reflect.set(target, key, value); } }); } const obj = reactive({ a: 1 }); obj.a = 2; // 触发 set 拦截,更新视图 
4. ref 和 reactive 的区别(买菜比喻)
 
问题:什么时候用 ref?什么时候用 reactive?
 答案:
-  
ref:- 用于包装 基本类型(数字、字符串等),因为 Proxy 无法直接监听基本类型。
 - 使用方式:必须通过 
.value访问(就像买菜用袋子装,取菜要打开袋子)。 
const count = ref(0); console.log(count.value); // 0 count.value++; -  
reactive:- 用于包装 对象/数组,可以直接访问属性(就像直接拿菜篮子,不用拆包装)。
 
const user = reactive({ name: '张三' }); console.log(user.name); // 张三 user.name = '李四'; -  
总结:
- 简单值用 
ref,复杂对象用reactive。 - 如果不想写 
.value,可以用toRefs解构对象(见下文)。 
 - 简单值用 
 
toRefs 是 Vue 3 中用于处理响应式对象的重要工具函数,主要用于将 reactive 对象转换为普通对象,同时确保每个属性都保持响应性。这在解构响应式对象或将其属性传递给子组件时非常有用。
使用场景
- 解构响应式对象:直接解构 
reactive对象会失去响应性,而使用toRefs可以避免这一问题。 - 组件间通信:通过 
toRefs将响应式数据传递给子组件,确保数据在传递过程中仍能保持响应性。 
基本用法
import { reactive, toRefs } from 'vue';const state = reactive({foo: 1,bar: 2,
});const stateRefs = toRefs(state);
// stateRefs 的每个属性都是 ref 对象,修改它们的值会触发视图更新stateRefs.foo.value++; // 视图会自动更新
 
示例代码
解构并保持响应性
<template><div><p>Foo: {{ foo }}</p><p>Bar: {{ bar }}</p><button @click="incrementFoo">Increment Foo</button></div>
</template><script>
import { reactive, toRefs } from 'vue';export default {setup() {const state = reactive({foo: 1,bar: 2,});const { foo, bar } = toRefs(state);function incrementFoo() {foo.value++;}return {foo,bar,incrementFoo,};},
};
</script>
 
在组合式 API 中使用
import { reactive, toRefs } from 'vue';function useCounter() {const state = reactive({count: 0,});function increment() {state.count++;}return {...toRefs(state),increment,};
}
 
注意事项
- 访问方式:返回的对象属性是 
ref对象,在 JavaScript 中需通过.value访问;模板中则无需.value。 - 适用范围:仅适用于 
reactive对象,不支持普通对象或ref对象。 - 性能影响:大量属性可能带来一定性能开销。
 
总结而言,toRefs 提供了一种便捷的方式来处理响应式对象,尤其在需要解构或传递响应式数据时,能够有效简化逻辑并保持数据的响应性。
 
三、进阶 API 与实战技巧
5. watch 和 watchEffect(场景区分)
 
问题:监听数据变化用哪个?
 答案:
-  
watch:- 明确监听某个数据,适合精确控制(比如监听搜索关键词变化,触发请求)。
 
watch( keyword, (newVal) => { fetchData(newVal) }, { immediate: true } // 立即执行一次 ); -  
watchEffect:- 自动追踪依赖,适合副作用操作(比如根据多个数据变化更新 DOM)。
 
watchEffect(() => { console.log('关键词和页码变化了:', keyword.value, page.value); fetchData(); }); 
6. 组件通信:Provide/Inject(跨层级传参)
问题:爷爷组件如何直接传数据给孙子组件?
 答案:
- 步骤: 
- 爷爷组件用 
provide提供数据。 - 孙子组件用 
inject获取数据。 
 - 爷爷组件用 
 - 代码示例:
// 爷爷组件 import { provide } from 'vue'; setup() { provide('theme', 'dark'); // 提供数据 } // 孙子组件 import { inject } from 'vue'; setup() { const theme = inject('theme', 'light'); // 第二个参数是默认值 return { theme }; } 
四、性能优化(通俗策略)
7. 如何让 Vue3 应用更快?
答案:
-  
代码层面:
- 使用 
v-once标记静态内容(只渲染一次)。 - 用 
v-memo缓存动态组件(比如表格行,只有 ID 变化时才重新渲染)。 
<div v-for="item in list" :key="item.id" v-memo="[item.id]"> {{ item.name }} </div> - 使用 
 -  
打包优化:
- 按需引入组件库(比如 Element Plus 只导入用到的 Button、Input)。
 - 使用异步组件(懒加载),减少首屏代码体积。
 
// 异步加载组件 const AsyncComponent = defineAsyncComponent(() => import('./MyComponent.vue')); 
五、高频面试代码片段
8. 自定义指令:点击外部关闭弹窗
场景:点击弹窗外部区域关闭弹窗。
 代码:
// 全局指令 v-click-outside  
app.directive('click-outside', {  mounted(el, { value: callback }) {  el.handler = (e) => {  if (!el.contains(e.target)) callback();  };  document.addEventListener('click', el.handler);  },  unmounted(el) {  document.removeEventListener('click', el.handler);  }  
});  // 使用  
<template>  <div v-click-outside="closeModal">弹窗内容</div>  
</template>  
 
六、项目经验(回答技巧)
9. 如何回答“封装通用组件”?
示例:
- 场景:封装一个表单组件,支持校验和提交。
 - 步骤: 
- 通过 
props接收表单配置(如字段规则)。 - 使用 
v-model绑定每个输入项的值。 - 暴露 
validate()方法供父组件调用。 - 使用插槽(slot)允许自定义布局。
 
<template> <form @submit.prevent="submit"> <slot></slot> <button type="submit">提交</button> </form> </template> <script> export default { methods: { validate() { /* 校验逻辑 */ }, submit() { this.$emit('submit'); } } } </script> - 通过 
 
总结
以上内容通过通俗比喻、实际场景和代码示例,拆解了 Vue3 的核心知识点。建议边学边写代码实践,结合 Vue3 官方文档 查漏补缺!
