Vue3.0新体验之setup
setup介绍
setup是Vue3.0提供的一个新的属性,在setup中通过reactive初始化了一个响应式数据,
然后通过return返回了一个对象,对象中包含了声明的响应式数据和一个方法,,而这些
数据就可以直接使用到了template中了。
setup 的参数说明
setup函数有两个参数,分别是props和context。
1.props
props是setup函数的第一个参数,是组件外部传入进来的属性,与vue2.0的props基本是一致的,比如下面代码
export default {
props: {
value: {
type: String,
default: ""
}
},
setup(props) {
console.log(props.value)
}
}
但是需要注意的是,在setup中,props是不能使用解构的,即不能将上面的代码改写成
setup({value}) {
console.log(value)
}
虽然template中使用的是setup返回的对象,但是对于props,我们不需要在setup中返回,
而是直接可以在template使用,比如上面的value,可以直接在template写成
<custom-component :value="value"></custom-component>
2.context
context是setup函数的第二个参数,context是一个对象,里面包含了三个属性,分别是
attrs,slots,emit.
setup 返回值
setup函数一般会返回一个对象,这个对象里面包含了组件模板里面要使用到的data与一些函数或者事件,
但是setup也可以返回一个函数,这个函数对应的就是Vue2.0的render函数,以在这个函数里面使用JSX。
最后需要注意的是,不要在setup中使用this,在setup中的this和你真正要用到的this是不同的,
通过props和context基本是可以满足我们的开发需求的。
了解Composition API,先从reactive和ref开始
在使用Vue2.0的时候,我们一般声明组件的属性都会像下面的代码一样
export default {
data() {
return {
name: '小黑',
sex: '男'
}
}
}
然后就可以在需要用到的地方比如computed,watch,methods,template等地方使用,但是这样存在一个
比较明显的问题,我声明data的地方与使用data的地方在代码结构中可能相距很远,
而Composition API的诞生的一个很重要的原因就是解决这个问题。
在尤大大在关于Composition API的动机中是这样描述解决的问题的:
1.随着功能的增长,复杂组件的代码变得越来越难以阅读和理解。这种情况在开发人员阅读他人编写的代码时尤为常见。
根本原因是 Vue 现有的 API 迫使我们通过选项组织代码,但是有的时候通过逻辑关系组织代码更有意义。
2.目前缺少一种简洁且低成本的机制来提取和重用多个组件之间的逻辑。
介绍reactive
举个例子
<template>
<!--在模板中通过state.name使用setup中返回的数据-->
<div>{{ state.name }}</div>
</template>
<script>
// 1. 引入reactive
import { reactive } from "vue";
export default {
setup() {
//2. 通过reactive声明一个可响应式的对象
const state = reactive({
name: "小黑"
});
// 5秒后将小黑修改为 小黑变小白
setTimeout(() => {
state.name = "小黑变小白";
}, 1000 * 5);
// 3. 将state添加到一个对象中然后返回
return {
state
};
}
};
</script>
上面的例子就是reactive的一个基本的用法,我们在使用vue2.0的时候,
最常见的一个问题就是经常会遇到一些数据明明修改了值,但是界面却并没有刷新,
这时候就需要使用Vue.set来解决,这个问题是因为Vue2.0使用的Object.defineProperty
无法监听到某些场景比如新增属性,但是到了Vue3.0中通过Proxy将这个问题解决了,
所以我们可以直接在reactive声明的对象上面添加新的属性。
举个例子:
<template>
<div>
<div>姓名:{{ state.name }}</div>
<div>猫名:{{ state.xb }}</div>
</div>
</template>
<script>
import { reactive } from "vue";
export default {
setup() {
const state = reactive({
name: "小黑"
});
// 5秒后新增属性xb 小白
setTimeout(() => {
state.xb = "前端有的玩";
}, 1000 * 5);
return {
state
};
}
};
</script>
上面的例子虽然在state中并没有声明xb属性,但是在5s后我们可以直接给state添加xb属性,
这时候并不需要使用Vue.set来解决新增属性无法响应的问题。
介绍ref
假如现在我们需要在一个函数里面声明用户的信息,那么我们可能会有两种不一样的写法
// 写法1
let name = '小黑'
let sex = '男'
// 写法2
let userInfo = {
name: '小黑',
sex: '男'
}
上面两种不同的声明方式,我们使用的时候也是不同的,对于写法1我们直接使用变量就可以了,
而对于写法2,我们需要写成userInfo.name的方式。我们可以发现userInfo的写法与reactive是比较相似的,
而Vue3.0也提供了另一种写法,就像写法1一样,即ref。
举个例子
<template>
<div>
<div>姓名:{{ name }}</div>
</div>
</template>
<script>
//1.引入
import { ref } from "vue";
export default {
setup() {
//方法1 定义
const name = ref("小黑");
console.log('姓名',name.value)
// 5秒后修改name为 小黑变小白
setTimeout(() => {
name.value = "小黑变小白";
}, 1000 * 5);
return {
name
};
}
};
</script>
reactive与ref的区别
1.reactive传入的是一个对象,返回的是一个响应式对象,而ref传入的是一个基本数据类型(其实引用类型也可以),
返回的是传入值的响应式值
2.reactive获取或修改属性可以直接通过state.prop来操作,而ref返回值需要通过name.value的方式来修改或者读取数据。
但是需要注意的是,在template中并不需要通过.value来获取值,这是因为template中已经做了解套。
在Vue3.0优雅的使用v-model
在Vue2.0和Vue3.0中使用v-model
1.在vue2.0中使用v-model
<template>
<a-input v-model="value" placeholder="Basic usage" />
</template>
<script>
export default {
data() {
return {
value: '',
};
},
};
</script>
2.在Vue3.0中使用v-model
<template>
<!--在vue3.0中,v-model后面需要跟一个modelValue,即要双向绑定的属性名-->
<a-input v-model:value="value" placeholder="Basic usage" />
</template>
<script>
export default {
// 在Vue3.0中也可以继续使用`Vue2.0`的写法
data() {
return {
value: '',
};
},
};
</script>
在vue3.0中,v-model后面需要跟一个modelValue,即要双向绑定的属性名,
Vue3.0就是通过给不同的v-model指定不同的modelValue来实现多个v-model。