最近跟着技术胖学习了vue3 和 typescript 记录一下自己的学习过程
现在写一个简单的菜单选择功能
1 <template> 2 <div class="hello"> 3 <div> 4 <h2>欢迎光临呱呱的小店</h2> 5 <div>请选择你喜欢的服务员</div> 6 </div> 7 <div> 8 <button 9 v-for="(item, index) in girls" 10 :key="index" 11 @click="girlsnumFun(index)" 12 > 13 {{ item }} 14 </button> 15 </div> 16 <div>当前选择的是 【{{ girlsnum }}】</div> 17 </div> 18 </template>
1 <script lang="ts"> 2 import { defineComponent, ref } from "vue"; 3 export default defineComponent({ 4 name: "hello", 5 setup() { 6 const girls = ref(["服务员1", "服务员2", "服务员3"]); 7 const girlsnum = ref(''); 8 const girlsnumFun = (item: number) => { 9 girlsnum.value = girls.value[item]; 10 }; 11 return { 12 girls, 13 girlsnum, 14 girlsnumFun, 15 }; 16 }, 17 }); 18 </script>
setup()
- setup 是一个新的组件选项 ,作为在组件内使用 composition api 的入口
- 调用时机: 创建组件实例 ,初始化props,紧接着调用setup函数。从生命周期钩子的视角来看,它会在
beforeCreate
钩子之前被调用 - 返回一个对象,则对象的属性将会被合并到组件模板的渲染上下文
- 返回一个函数,函数中也能使用当前
setup
函数作用域中的响应式数据
1 import { h, ref, reactive } from 'vue' 2 3 export default { 4 setup() { 5 const count = ref(0) 6 const object = reactive({ foo: 'bar' }) 7 8 return () => h('div', [count.value, object.foo]) 9 }, 10 }
- 参数
该函数接收 props
作为其第一个参数 然而不要解构 props
对象,那样会使其失去响应性
1 export default { 2 props: { 3 name: String, 4 }, 5 setup(props) { 6 console.log(props.name) 7 }, 8 }
注意 props
对象是响应式的,watchEffect
或 watch
会观察和响应 props
的更新:
1 export default { 2 props: { 3 name: String, 4 }, 5 setup(props) { 6 watchEffect(() => { 7 console.log(`name is: ` + props.name) 8 }) 9 }, 10 }
- 类型定义
1 interface Data { 2 [key: string]: unknown 3 } 4 5 interface SetupContext { 6 attrs: Data 7 slots: Slots 8 emit: (event: string, ...args: unknown[]) => void 9 } 10 11 function setup(props: Data, context: SetupContext): Data
ref()
- ref() 在获取变量的过程中需要加上.value 注意:
setup
返回的 ref 在模板中会自动解开,不需要写.value
- ref的实现 ref的底层是reactive ref的对象具有对应的getter和setter。getter总是经过cover 转化后的响应式对象raw ,触发Vue的依赖收集。 ref的对象赋值会调用setter 调用会通知deps,通知依赖这一状态的对象更新,并重新更新raw ,raw被保存为新的响应式包装对象。
- 注意如果将一个新的 ref 分配给现有的 ref, 将替换旧的 ref
- 注意当嵌套在 reactive
Object
中时,ref 才会解套。从Array
或者Map
等原生集合类中访问 ref 时,不会自动解套:
const arr = reactive([ref(0)]) // 这里需要 .value console.log(arr[0].value) const map = reactive(new Map([['foo', ref(0)]])) // 这里需要 .value console.log(map.get('foo').value)
- 类型定义
1 interface Ref<T> { 2 value: T 3 } 4 5 function ref<T>(value: T): Ref<T>
const foo = ref<string | number>('foo') // foo 的类型: Ref<string | number> foo.value = 123 // 能够通过!