# 1. 首先 step 里面是没有 this 的
在 setup 中你应该避免使用 this,因为它不会找到组件实例。setup 的调用发生在 data property、computed property 或 methods 被解析之前,所以它们无法在 setup 中被获取。 — coderwhy
<template> | |
<div></div> | |
</template> | |
<script> | |
export default { | |
setup() { | |
console.log(this); | |
} | |
} | |
</script> | |
<style scoped></style> |
参考结果:
# 2.step 有两个参数 (props/context)
# props
props 是用来接受其他父组件传来的数据,而想要在 setup 里面获取到 props 的数据,则需要 setup 第一个参数 props 来获取,切记不可用 this.props.info 来获取切记不可用 this!
// Home.vue | |
<template> | |
<div></div> | |
</template> | |
<script> | |
export default { | |
props: { | |
info: { | |
type: Object, | |
required: true, | |
}, | |
}, | |
// 这里的 props 是形参,可随意命名 | |
setup(props) { | |
console.log(props); | |
}, | |
}; | |
</script> | |
<style scoped> | |
</style> | |
// App.vue | |
<template> | |
<div> | |
<home info="{name:'Neko',age:16}"></home> | |
</div> | |
</template> | |
<script> | |
import Home from "./Home.vue"; | |
export default { | |
components: { | |
Home, | |
}, | |
}; | |
</script> | |
<style scoped></style> |
参考结果:
# context
context (也称为 SetupContext) 里面有三个常用属性 (attrs/slotsemit), 意思都是顾名思义
attrs: 所有的非 prop 的 attribute (就是子组件没有使用 props 接收但父组件传递过来的数据)
slots: 父组件传递过来的插槽 (在渲染函数返回时会有作用)
emit: 当我们组件内部需要发出事件是会用到 emit (因为我们不能访问 this, 所以不可通过 this.$emit 发出事件)
// Home.vue | |
<template> | |
<div></div> | |
</template> | |
<script> | |
export default { | |
props: { | |
info: { | |
type: Object, | |
required: true, | |
}, | |
}, | |
// 这里的 props 是形参,可随意命名 | |
//setup (props, { attrs, emit, slots}) { // 也可写成对象解构 | |
setup(props, context) { | |
// console.log(props); | |
console.log(context); | |
}, | |
}; | |
</script> | |
<style scoped> | |
</style> | |
// App.vue | |
<template> | |
<div> | |
<home | |
:info="{ name: 'Neko', age: 16 }" | |
id="homeId" | |
class="homeClass" | |
></home> | |
</div> | |
</template> | |
<script> | |
import Home from "./Home.vue"; | |
export default { | |
components: { | |
Home, | |
}, | |
}; | |
</script> | |
<style scoped></style> |
参考结果:
# 3.setup 中返回数据
// Home.vue | |
<template> | |
<div> | |
<h2>{{ name }}</h2> | |
<h2>{{ age }}</h2> | |
</div> | |
</template> | |
<script> | |
export default { | |
props: { | |
info: { | |
type: Object, | |
required: true, | |
}, | |
}, | |
// 这里的 props 是形参,可随意命名 | |
//setup (props, { attrs, emit, slots}) { // 也可写成对象解构 | |
setup(props, context) { | |
// console.log(props); | |
console.log(context); | |
return { | |
name: "Neko", | |
age: 16, | |
}; | |
}, | |
}; | |
</script> | |
<style scoped></style> | |
// App.vue | |
<template> | |
<div> | |
<home | |
:info="{ name: 'Neko', age: 16 }" | |
id="homeId" | |
class="homeClass" | |
></home> | |
</div> | |
</template> | |
<script> | |
import Home from "./Home.vue"; | |
export default { | |
components: { | |
Home, | |
}, | |
}; | |
</script> | |
<style scoped></style> |
参考结果:
# 4.setup 定义方法
// Home.vue | |
<template> | |
<div> | |
<h2>{{ counter }}</h2> | |
<button @click="increment">+1</button> | |
</div> | |
</template> | |
<script> | |
export default { | |
setup() { | |
let counter = 0; // | |
const increment = () => { // 点击五次时:请参考结果 | |
counter++; increment函数也是个闭包,所以会引用外面的counter | |
console.log(counter); | |
}; | |
return { | |
counter, | |
increment, | |
}; | |
}, | |
}; | |
</script> | |
<style scoped> | |
</style> | |
// App.vue | |
<template> | |
<div> | |
<home></home> | |
</div> | |
</template> | |
<script> | |
import Home from "./Home.vue"; | |
export default { | |
components: { | |
Home, | |
}, | |
}; | |
</script> | |
<style scoped> | |
</style> |
参考结果:
当我点击 increment 执行了 5 次时:我们会发现数据在页面渲染时没有发生任何变化,但在 control 打印时,确实是已经改变了,是因为默认情况下定义的变量是一个普通的变量,他不是响应式的。这就涉及到响应式 API 了 (reaactive/ref)
🍡Vue3-reactive 基本用法 ●~●~●biu✏️Vue3-ref 基本用法