珠海网站建设的公司排名网络营销公司怎么注册
setup
理解:Vue3.0 中一个新的配置项,值为一个函数
setup 是所有 Composition API(组合API)“表演的舞台”
组件中所用到的数据、方法等,均要配置在 setup 中
setup 函数的两种返回值:
- 若返回一个对象,则对象中的属性、方法,在模板中均可以直接使用
- 若返回一个渲染函数,则可以自定义渲染内容
<template><h1>《官居一品》主人公信息</h1><ul><li>姓名:{{ name }}</li><li>年龄:{{ age }}</li></ul><button @click="majorManInfo">信息获取</button>
</template><script>
import { h } from 'vue'
export default {name: 'HomeView',setup() {// 暂不考虑响应式的问题let name = '沈默'let age = 20function majorManInfo() {console.log(`《官居一品》主人公:姓名:${name},年龄:${age}`)}// 返回一个渲染函数,可以自定义渲染内容(很少使用)// return () => h('h1', '沈拙言')// 返回一个对象,对象的属性、方法在模板中可以直接使用(常用)return {name,age,majorManInfo,}},
}
注意点
1. 尽量不要与 Vue2.x 配置混用
- Vue2.x 配置(data、methods、computed...)中可以访问到 setup 中的属性、方法
- 在 setup 中不能访问到 Vue2.x 配置(data、methods、computed...)
- 如有重名,setup 优先
2. setup 不能是一个 async 函数,因为返回值不再是 return 的对象,而是一个 promise 包裹的对象,此时模板中的数据和方法将无法正常展示和使用
setup 注意点
setup 执行时机
在 beforeCreate 之前执行一次
且 this 是 undefined,因此在 setup 中无法通过 this 获取任何东西
beforeCreate() {console.log(`--- beforeCreate ---`)
},
setup() {console.log(`--- setup ---`)console.log(`setup 中 this 值为 ${this}`)return {}
},
输出结果:
setup 参数
props:值为对象,包含:组件外部传递过来,且组件内部声明接收了的属性
context:上下文对象
- attrs:值为对象,包含:组件外部传递过来,但没有在 props 配置中声明的属性,相当于 this.$attrs
- 组件外部传递过来,且在组件内部的 props 配置中声明的属性,会直接作为 VueComponent 的自身属性
- slots:收到的插槽内容。相当于 this.$slots
- emit:分发自定义事件的函数,相当于 this.$emit
setup(a, b, c) {console.log(a)console.log(b)console.log(c)
},
输出结果表明:setup 函数只有两个参数
props 参数
值为对象,包含:组件外部传递过来,且组件内部声明接收了的属性
<!-- App.vue -->
<template><Demo :friends="friends" :master="master"></Demo>
</template>
<script>
import Demo from '@/components/Demo.vue'
import { reactive } from 'vue'
export default {components: { Demo },setup() {let majorMan = '沈默',friends = reactive(['徐渭', '褚大绶', '陶大临', '孙鑨', '孙铤', '吴兑']),master = reactive({name: '徐阶',age: 50,goverPost: '大明次辅',})return {majorMan,friends,master,}},
}
</script>
// Demo.vue
export default {name: 'Demo',props: {majorMan: {type: String,default: '',}friends: {type: Array,default: [],},master: {type: Object,default: {},},},setup(props) {console.log(props)},
}
注意 props 中简单数据类型和引用数据类型的区别
context
attrs:包含父组件传递过来,且在子组件的 props 中未接收的数据
props: {majorMan: {type: String,default: '',},friends: {type: Array,default: [],},
},
setup(props, context) {console.log(context.attrs)
},
emit:分发自定义事件的函数
<!-- App.vue -->
<template><div class="about"><Demo @manInfo="showInfo" :majorMan="majorMan"></Demo></div>
</template>
<script>
import Demo from '@/components/Demo.vue'
import { reactive } from 'vue'export default {components: { Demo },setup() {let majorMan = '沈默'function showInfo(value) {alert(`自定义事件触发,${value}`)}return {majorMan,showInfo,}},
}
</script>
// Demo 组件
import { onMounted } from 'vue'
export default {name: 'Demo',props: {majorMan: {type: String,default: '',},},setup(props, context) {onMounted(() => {context.emit('manInfo', props.majorMan)})return {}},
}
slots:收到的插槽内容
<!-- App.vue -->
<template><div class="about"><Demo @manInfo="showInfo" :majorMan="majorMan"><h3>姓名:{{ majorMan }}</h3><template #slotName><ul><li v-for="item in friends">{{ item }}</li></ul></template></Demo></div>
</template><script>
import Demo from '@/components/Demo.vue'
import { reactive } from 'vue'
export default {components: { Demo },setup() {let majorMan = '沈默',friends = reactive(['徐渭', '褚大绶', '陶大临', '孙鑨', '孙铤', '吴兑']),return {majorMan,friends,}},
}
</script>
<!-- Demo.vue -->
<template><h1>《官居一品》主人公信息</h1><slot></slot><slot name="slotName"></slot>
</template><script>
export default {name: 'Demo',setup(props, context) {console.log(context.slots)return {}},
}
</script>
default 默认插槽一个,slotName 具名插槽一个
ref
refImpl:reference implement 引用实现
import { ref } from 'vue'
setup() {let name = ref('沈默')console.log(name)
}
想要将数据变成响应式的,需要借助 ref。经过 ref 加工的数据变成了一个引用对象(引用实现的实例对象)
get 和 set 方法位于引用对象的原型链上
import { ref } from 'vue'
export default {name: 'HomeView',setup() {let name = ref('沈默'),age = ref(20),goverPost = ref('浙江巡按')function threeYears() {// 当我们想要获取和修改数据时,需要使用 .value// 但在 html 模板中并不需要 .value,因为 vue3 会自动解析 .value 值age.value = '23'goverPost.value = '苏州同知'}return {name,age,goverPost,threeYears,}},
}
ref 函数总结
作用:定义一个响应式的数据语法:
创建一个包含响应式数据的引用对象(reference 对象)
const xxx = ref(initValue)JS 中操作数据:xxx.value
模板中读取数据:不需要 .value,直接 <div>{{ xxx }}</div>备注:
接收的数据可以是基本类型,也可以是对象类型
基本类型的数据:响应式依然是靠 Object.defineProperty() 的 get 与 set 完成的
对象类型的数据:内部“求助”了 Vue3.0 中的一个新函数 --- reactive 函数
reactive
用来定义对象类型的响应式数据
响应式数据结构
setup() {let majorMan = reactive({name: '沈默',age: 36,address: '北京城正阳门棋盘天街棋盘胡同',})function showInfo() {console.log(majorMan)}return {majorMan,showInfo,}
},
响应式数据修改
setup() {let majorMan = reactive({name: '沈默',age: 36,hobby: ['读书', '看报', '睡觉'],goverPost: '内阁总理大臣',})function threeYearsAgo() {majorMan.age = 33// 在 vue2 中直接通过数组的索引值修改数组元素值是行不通的majorMan.hobby[2] = '工作'majorMan.goverPost = '内阁首辅'}return {majorMan,threeYearsAgo,}
},
reactive 函数总结
作用:定义一个对象类型的响应式数据(基本数据类型建议使用 ref 函数)语法:
const 代理对象 = reactive(被代理对象)
接收一个对象(或数组),返回一个代理器对象(Proxy 的实例对象,简称为 proxy 对象)示例:
const majorMan = reactive({name: '沈默',age: 20
})reactive 定义的响应式数据是“深层次的”
内部基于 ES6 的 Proxy 实现,通过代理对象操作对象内部数据来实现响应式
ref 和 reactive 对比
定义数据角度对比ref 用来定义基本数据类型reactive 用来定义引用数据类型(对象或数组)备注:ref 也可以用来定义引用数据类型,它内部会自动通过 reactive 转为代理对象原理角度对比ref 通过 Object.defineProperty() 的 get 与 set 来实现响应式(数据劫持)reactive 通过使用 Proxy 来实现响应式(数据劫持),并通过 Reflect 操作元对象内部的数据使用角度对比ref 定义的数据,在 js 中操作时需要 .value,读取数据时模板中之间读取不需要 .valuereactive 定义的数据在操作数据和读取数据时都不需要 .value
conputed 计算属性
<template><h3>{{ majorMan.fullName }}</h3><h3>{{ fullName }}</h3>
</template><script>
import { reactive, computed } from 'vue'
export default {setup() {let majorMan = reactive({firstName: '沈默',secondName: '拙言',lastName: '江南',})// 简写形式,fullName 是只读的,不可修改majorMan.fullName = computed(() => {return `${majorMan.firstName}字${majorMan.secondName}号${majorMan.lastName}`})// 完整写法,可读取可修改let fullName = computed({get() {return `${majorMan.firstName}-${majorMan.secondName}-${majorMan.lastName}`},set(value) {const nameArr = value.split('-')majorMan.firstName = nameArr[0]majorMan.secondName = nameArr[1]majorMan.lastName = nameArr[2]},})return {majorMan,fullName}},
}
也可以使用 Vue2 的计算属性的写法,但是不建议这样使用