官网地址:组合式 API:setup() | Vue.js (vuejs.org)
setup()
钩子是在组件中使用组合式 API 的入口,通常只在以下情况下使用:
需要在非单文件组件中使用组合式 API 时。
需要在基于选项式 API 的组件中集成基于组合式 API 的代码时。
一、数据的定义
1. 常用
<template>
<h2>message:{{ message }}</h2>
<button @click ="changeMessage">修改message</button>
<hr>
<h2>账号:{{ account.username }}</h2>
<h2>密码:{{ account.password }}</h2>
<button @click="changeAccount">修改账号</button>
<hr>
<!--默认情况下在template使用ref会自动解包(自动取出其中的value)-->
<h2>当前计数: {{ counter }}</h2><!--不用写counter.value-->
<button @click="increment">+1</button>
<button @click="counter++">+1</button><!--已经帮你自动解包,不需要.value-->
<hr>
<h2>当前计数:{{ info.counter }}</h2>
<!--修改的时候需要些.value 用的时候 不用写 info是个变量-->
<button @click="info.counter.value++">+1</button>
<hr>
<form>
账号:<input type="text" v-model="account.username">
密码:<input type="password" v-model="account.password">
</form>
<hr>
<show-info name="cn" age="20"></show-info>
</template>
<script>
import { onMounted, reactive,ref } from 'vue';
import ShowInfo from './Showinfo.vue'
export default {
components:{//局部注册
ShowInfo
},
setup(){
// 1.定义普通的数据 不是响应式
let message = "hello world"
function changeMessage(){
message = "你好世界"
console.log(message)
}
// 2.1.定义响应式的数据
// reactive 函数 定义复杂类型的数据
// import { reactive } from 'vue';
// 当我们使用该函数处理数据之后,数据再次被使用就会进行依赖收集
// 当数据发生改变时,所有收集到的依赖都是进行对应的响应式操作
// 条件一:多应用于本地数据
// 条件二:多个数据间有关系(集合)
const account = reactive({//账户包括账号,和密码 (包裹对象)
"username":"admin" ,
"password":"123456"//本地产生的数据
})
function changeAccount(){
account.username = " jinery "
}
// 2.2.counter定义响应式数据
// ref 定义简单类型的数据(也可以定义复杂类型的数据)
// 其他场景基本都用ref
const counter = ref(100) //counter = 100
//const message = ref("Hello World!") //message=Hello World!
function increment (){
counter.value++
console.log(counter.value)
}
//复杂类型ref
// const musics = ref([])
// onMounted(()=>{
// const serverMusics = ["111","222","333"]
// musics.value = serverMusics
// })
//3.ref 是浅层解包
const info ={
counter
}
return{
message,
changeMessage,
account,
changeAccount,
counter,
increment,
info,
}
}
}
</script>
<style>
</style>
定义响应式数据 ref reactive 相关的说明见上代码注释
2.其他
当然还有一个 readonly 这个函数是不能被修改的,比如 A发给B一个WPS文件的只读
APP.vue
<template>
<h2>App: {{ info }}</h2>
<show-info :info="info" roInfo="roInfo"
@ChangeInfoName="ChangeInfoName"
@ChangeRoInfoName="ChangeRoInfoName">
</show-info>
</template>
<script>
import { reactive, readonly } from 'vue'
import ShowInfo from './ShowInfo.vue'
export default {
components: {
ShowInfo
},
setup(){
//本地定义多个数据,都需要传递给子组件
//name/age/height
const info = reactive({
name: "cn",
age: 20,
height: 1.80
})
function ChangeInfoName(payload){//用 payload 接收到 CN
info.name = payload // cn变成 CN 真正修改的代码
}
const roInfo = readonly(info)//roInfo不能被修改,可以修改info
//可以传入 普通 reactive ref 这三种的对象
function ChangeRoInfoName(payload){
info.name = payload
}
return{
info,
ChangeInfoName,
roInfo,
ChangeRoInfoName
}
}
}
</script>
<style>
</style>
ShowInfo.vue
<template>
<h2>ShowInfo: {{ info }}</h2>
<!-- <button @click="info.name='kobo'">gai</button>不规范 -->
<button @click="ShowinfoClick">ShowInfo点击</button>
<hr>
<!--使用readonly数据-->
<h2>ShowInfo: {{ roInfo }}</h2>
<!--无效代码-->
<!-- <button @click="roInfo.name='jinrey'">gai</button> -->
<button @click="roInfoBtnClick">roInfo按钮</button>
</template>
<script>
export default {
props: {
//reactive数据
info:{
type: Object,
default: () => ({})
},
//readonly数据 数据传入其他地方使用但是不能被修改
roInfo:{
type: Object,
default: () => ({})
}
},
emits:["ChangeInfoName","ChangeRoInfoName"],//发送该函数的结果 "CN"
setup(props,context){
function ShowinfoClick(){
context.emit("ChangeInfoName","CN")
}
function roInfoBtnClick(){
context.emit("ChangeRoInfoName","jinrey")
}
return{
ShowinfoClick,
roInfoBtnClick,
}
}
}
</script>
<style>
</style>
二、解构数据属性
官网地址:响应式 API:工具函数 | Vue.js (vuejs.org)
toRefs()
将一个响应式对象转换为一个普通对象,这个普通对象的每个属性都是指向源对象相应属性的 ref。每个单独的 ref 都是使用 toRef() 创建的。
<template>
<div>
<h2>{{ name }} - {{ age }} - {{ height }}</h2>
<button @click = "age++">修改age</button>
<button @click = "height = 1.88">修改height</button>
</div>
</template>
<script setup> // Vue3 提供的写法
import { reactive,toRefs,toRef } from 'vue'
// setup 函数 可以省略 ,setup加到 <script>中,return也不需要了
//在setup 被调用之前,data computed methods 等都没有被解析;
//所以无法在setup中获取this
//set up 不能使用this context.emit
const info = reactive({
name: "CN",
age : "20",
height:"1.80",
})
// const { name ,age} = info 这样解构属性数据不再是响应式
const {name ,age} = toRefs(info) //解构多个 s
// 将rective 返回对象中的属性转化为ref 再次解构出来的name age 本身都是ref
const height = toRef(info,"height") //解构单个
// unref(nameRef) == nameRef.value 可以获取到属性的值
// unref("cn") == cn
</script>
<style>
</style>
三、计算属性编写
响应式 API:核心 | Vue.js (vuejs.org)
接受一个 getter 函数,返回一个只读的响应式 ref 对象。该 ref 通过 .value
暴露 getter 函数的返回值。它也可以接受一个带有 get
和 set
函数的对象来创建一个可写的 ref 对象。
算法的体现,一个算法函数。
<template>
<h2>{{ fullname }}</h2>
<button @click="setFullname">设置fullname</button>
<h2>{{ score }} - {{ scoreLevel }}</h2>
</template>
<script>
import { reactive,computed,ref} from 'vue'
export default {
setup(){
//定义数据
const names = reactive({
firstName: "ch",
lastName: "n"
})
const fullname = computed({//编写一个计算属性
set: function(newValue){//传值names给newValue
//tempNames 是 ch 和 n
const tempNames = newValue.split(" ")//split() 用空格分隔
names.firstName = tempNames[0] //从ch -> CH
names.lastName = tempNames[1] //从n ->N
},
get: function(){
return names.firstName + " " +names.lastName
}
})
function setFullname(){//更改函数,点击事件
fullname.value = "CH N" //计算程序的值有更改
}
const score = ref(99) //传值 99
const scoreLevel = computed(() => {//计算属性
return score.value >= 60 ? "1" : "2"
})
return{
names,
fullname,
score,
scoreLevel,
setFullname,
}
}
}
</script>
<style>
</style>
四、待续写...
且听下回分析……(懒ing)