VUE Setup 框架模板
为了方便阅读,我把setup分几个部份提取
<script setup> // 一、导入相关依赖,比如 ref、reactive等 // 二、定义props,即组件接收数据 // 三、定义data,即组件数据 // 四、定义emits,即组件相关事件 // 五、定义methods,即组件方法 // 六、定义computed,即计算属性 // 七、定义watch,即监听数据 // 八、定义组件生命周期 // 九、定义组件暴露接口 </script>
<script setup> // 常见内部依赖 import { ref, reactive, toRefs, computed, watch, onMounted, onUpdated, onUnmounted, getCurrentInstance } from 'vue' // 有些是不需要导入比如: // defineProps 、defineEmits、defineExpose // 函数或接口的导入,比如 import $string from '@/common/js/string.js' </script>
<script setup>
// 方法一:简洁定义props
//const props = defineProps(['propA', 'propB'])
// 方法二:详细定义props
// 建议采用方法二,对每个props进行严格设置 const props = defineProps({ // 基础的类型检查 (`null` 和 `undefined` 会通过任何类型验证) propA: Number, // 多个可能的类型 propB: [String, Number], // 必填的字符串 propC: { type: String, required: true }, // 带有默认值的数字 propD: { type: Number, default: 100 }, // 带有默认值的对象 propE: { type: Object, // 对象或数组默认值必须从一个工厂函数获取 default: function() { return { message: 'hello' } } }, // 自定义验证函数 propF: { validator: function(value) { // 这个值必须匹配下列字符串中的一个 return ['success', 'warning', 'danger'].indexOf(value) !== -1 } } }) // 在script内,可以使用props.propA 取值 // 在template内,可以使用插值语法取值:<view>{{propA}}</view> // 如果不需要取在script内取值,可以直接 defineProps({}); </script>
注意:
1、props建议采用驼峰写法,且严格区分大小写。比如:articleClass
2、type可选类型有:
String
Number
Boolean
Array
Object
Date
Function
Symbol
3、在default、validator内不可以访问<script setup> 中定义的其他变量,因为在编译时整个表达式都会被移到外部的函数中。
4、默认情况下,当组件中含有不在prop列表内的属性时,默认该属性会直接附加到组件的根节点上面。比如:
组件test代码:<input type="text" class="account"/>
父组件调用test时,增加了属性type与class,且这二个属性未在组件test的props内定义:<test class=”input” type=”number”/>
此时组件代码就变成了:<test class=”account input” type=”number”/>
采用的原则是:除class与style之外的属性是替换。class、style是合并。
如果你不希望组件的根元素继承特性,你可以在组件的选项中设置 inheritAttrs: false,但是inheritAttrs 不会影响到class、style的绑定!
vue setup内不支持配置项,此时,我们仍需要在<script>中配置,如下:
<script> export default { inheritAttrs: false } </script>
5、组件的数据双向绑定(v-model)及修饰符,详见:https://www.cnblogs.com/wm218/p/16692821.html
以下是定义data相关的响应式函数,有必要对这类函数进行深入了解:
- reactive() : 详见:https://www.cnblogs.com/wm218/p/16692382.html
- toRef()、toRefs() 详见:https://www.cnblogs.com/wm218/p/16688020.html
- readonly() 详见:https://www.cnblogs.com/wm218/p/16692888.html
- shallowRef() 详见:https://www.cnblogs.com/wm218/p/16693041.html
- shallowReactive() 详见:https://www.cnblogs.com/wm218/p/16693517.html
- triggerRef() 详见:https://www.cnblogs.com/wm218/p/16693610.html
- shallowReadonly() 详见:https://www.cnblogs.com/wm218/p/16693681.html
- toRaw() 详见:https://www.cnblogs.com/wm218/p/16694279.html
- markRaw() 详见:https://www.cnblogs.com/wm218/p/16694267.html
- customRef() 详见:https://www.cnblogs.com/wm218/p/16674010.html
- isRef()、unref()、isProxy()、isReactive()、isReadonly() 详见:https://www.cnblogs.com/wm218/p/16696784.html
组件test.vue
<template> <button @click="instance.emit('getInfo', student)">点击传递学生信息到父组件</button> </template> <script setup> import { reactive, getCurrentInstance } from 'vue' var student = reactive({ name: '张三', age: 15, contact: { phone: '18714896998', qq: '103422412', email: 'wm218@qq.com' } }) // 定义:自定义事件 defineEmits(['getInfo']) // 定义带验证函数的自定义事件 // 不过,即使验证不通过,父组件仍是会执行。只是在日志提示警告:[Vue warn]: Invalid event arguments: event validation failed for event "getInfo". // 所以带验证的功能没啥鸟用。 //defineEmits({ // 'getInfo': student => { // return student.age > 15 ? true : false // } //}) // 获取当前实例 var instance = getCurrentInstance() </script>
父组件调用事件:
<template> <test ref="student" @getInfo="printStudent"></test> </template> <script setup> function printStudent(data) { console.log(data.name); } </script>
组件方法和JS里的函数定义是一样的,比如:
function method1(p1, p2) { // to do... } const method2 = (p1, p2)=>{ // to do... }
基本语法:
const plusOne = computed(() => count.value + 1)
全部语法:
const writableComputed = computed({ get() { return count.value }, set(val) { count.value = val } })
computed() 简介,详见:https://www.cnblogs.com/wm218/p/16696645.html
侦听管家相关方法及事件:effectScope()、getCurrentScope()、onScopeDispose()
详见:https://www.cnblogs.com/wm218/p/16697249.html
在setup内可以使用watch() 或watchEffect()监听数据变化。这二个函数在使用前也必需引入。
<script setup>
import {
watch,
watchEffect
} from 'vue'
</script>
watch() 与 watchEffect()简介,详见:https://www.cnblogs.com/wm218/p/16695413.html
侦听管家相关方法及事件:effectScope()、getCurrentScope()、onScopeDispose()
详见:https://www.cnblogs.com/wm218/p/16697249.html
onBeforeMount()、onMounted() 、onBeforeUnmount()、onUnmounted() ,
说明:组件挂载、卸载生命周期
详见:https://www.cnblogs.com/wm218/p/16698819.html
onBeforeUpdate()、onUpdated()
说明:视图更新生命周期
详见:https://www.cnblogs.com/wm218/p/16698882.html
onActivated()、onDeactivated()
说明:被<KeepAlive>缓存组件的生命周期
详见:https://www.cnblogs.com/wm218/p/16700048.html
组件可以将内部数据、方法通过defineExpose()函数暴露给调用方使用。
defineExpose()函数不需要引入,可以直接使用。
在<script setup>中,默认defineExpose()是关闭的。
<script setup> import { ref } from 'vue' const count = ref(0) const fn = ()=>{ // to don... } defineExpose({ count, // 暴露数据 fn // 暴露方法 }) </script>