1. 父组件向子组件传值(props)
props 推荐使用对象写法,便于类型、默认值和必填约束。
<!-- Child.vue -->
<template>
<view>{{ name || "默认值" }}</view>
</template>
<script>
export default {
props: {
name: {
type: String,
default: "kwydy",
required: false,
},
},
};
</script>
<!-- Parent.vue -->
<template>
<Child :name="userName" />
</template>
<script>
import Child from "./Child.vue";
export default {
components: { Child },
data() {
return {
userName: "Alice",
};
},
};
</script>
2. 子组件向父组件传值($emit)
子组件通过事件抛出数据,父组件监听事件并处理。
<!-- Child.vue -->
<template>
<button @click="notifyParent">向父组件传值</button>
</template>
<script>
export default {
methods: {
notifyParent() {
this.$emit("submit", { message: "你好父组件" });
},
},
};
</script>
<!-- Parent.vue -->
<template>
<Child @submit="handleSubmit" />
</template>
<script>
import Child from "./Child.vue";
export default {
components: { Child },
methods: {
handleSubmit(payload) {
console.log(payload.message);
},
},
};
</script>
3. DOM 更新时机($nextTick)
数据刚修改后,DOM 还没完成更新。依赖真实 DOM 的逻辑要放进 this.$nextTick。
this.message = "changed";
this.$nextTick(() => {
// 此时 DOM 已更新
this.calcHeight();
});
典型场景:
- 列表异步加载后测量高度。
v-if切换后初始化第三方插件。- 表格数据更新后自动滚动到底部。
4. 数据初始化避免模板报错
如果模板里直接访问 groupDetail.data.name,那就要保证 data 初始值存在。
data() {
return {
groupDetail: { data: {} },
};
}
否则接口返回前,模板渲染可能报 Cannot read property 'name' of undefined。
5. this 指向踩坑(尤其在回调里)
在非箭头函数或第三方回调里,this 可能不是 Vue 实例。常见做法:
- 使用箭头函数保留词法作用域。
- 提前缓存实例:
const vm = this。 - 如果是在实例外部,直接引用实例变量(如
vue.noData = false)。
const vm = this;
request().then((res) => {
vm.noData = res.data.records.length === 0;
});
6. 快速检查清单
- 父传子:
props是否声明类型与默认值。 - 子传父:
$emit事件名是否与父组件监听一致。 - DOM 操作:是否放在
$nextTick。 - 深层对象:是否在
data里给了完整初始结构。 - 异步回调:是否确认
this指向正确。