setup
1.在setup里面使用组合式api
2.setup 是在组件创建之间执行,所以在setup中避免使用this,因为它不会找到组件实例,
3.组件中用到的数据,方法等需要写在setup中
4.值需要return
5.不要与vue2混用
基本数据类型
<h1>{{msg}}</h1>
export default{
setup(){
const msg = 'hello'
return{
msg
}
}
}
对象
<h1>{{person.name}}</h1>
const person = {
name:"lisa"
}
return{
person
}
ref
1.作用:定义一个响应式数据
使用ref需要引一下
import {ref} from 'vue'
让值改变
const msg = ref('lalisa')
想拿到msg里面的值,
js里面,
console.log(msg.value)
页面上直接{{msg}}就行
2.接收的数据类型可以是基本大护具类型也可以是对象数据类型。
3.基本数据类型的数据:响应式依靠object.defaultproperty()的get与set完成的
3.对象类型的数据:内部求助了vue3中的一个新函数-reactive函数
reactive
1.作用:定义一个对象类型的响应式数据 ps:基本数据类型用ref函数
2.语法 const 代理对象 = reactive(源对象) 接收一个对象或者数据,返回一个代理对象
<h2>{{person.name}}</h2>
import {reactive} from 'vue'
const person = reactive({
name:"xiaoming"
})
return{
parson
}
响应原理:
1.vue2中是通过object.definproperty()来劫持数据的get与set
存在问题:
不能检测到新增属性,删除属性,更新方法:强制更新 或者是$set
2.vue3中是通过proxy:拦截对象中的任意属性的变化,包括:属性值的读写,属性的添加,删除等。不支持proxy时,还会使用object.defautproperty
reactive与ref对比:
从定义数据解读:
1.ref:定义基本类型数据
reactive:定义对象或数组类型数据
从响应原理角度:
ref:通过object.defaultproperty
reactive:通过proxy
从使用方面:
ref需要变量名.value
reactive不需要
简单例子:
HelloWorld组件里面的内容
<template>
<h1>{{aa}}</h1>
<h1>{{ msg }}</h1>
<h2>{{persons.name}}</h2>
<h2>{{person.name}}</h2>
<p>{{ user.name }}:{{user.age}}</p>
<button @click="add">点击增加</button>
</template>
<script>
import {ref} from 'vue'
import {reactive} from 'vue'
export default{
setup(){
const aa = '哇偶'
const msg = ref('lalisa')
console.log(msg.value)
const persons = {
name:'小明'
}
const person = reactive({
name:'Lalisa'
})
const user = reactive({ name: "jennie", age: 12 });
function add() {
// ++user.age
user.age++
}
return{
aa,
msg, // 基本数据
person, // 个人信息
persons,
user, // 个人信息
add, // 点击让年龄加加的方法
}
}
}
</script>
app.vue里面的内容就是引入上面那个组件
<script setup>
import HelloWorld from './components/HelloWorld.vue'
</script>
<template>
<HelloWorld msg="Hello Vue 3 + Vite" />
</template>
<style>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style>
!vue3中重要的api
1.toRef
作用:创建一个ref对象,其value值指向另一个对象中的某个属性
vue3中新的组件:
1.Fragment
在vue2中:组件必须有一个根标签
在vue3中:组件中可以没有根标签,内部会将多个标点包含在一个Fragment虚拟元素中
好处:减少标点层级 减少内存占用
2.Teleport
provide与inject
简单来说就是祖辈给除了你父辈以外的组件进行传值。 可以在祖辈组件中用privide来写入你要传的值 然后在子组件中用inject来接收
祖代 组件
<template>
<h2>祖代 组件车型:{{name}}-价格:{{price}}</h2>
<hello></hello>
</template>
<script>
import hello from './components/HelloWorld.vue'
import {reactive,toRefs,provide} from 'vue'
export default {
name:"App",
components:{
hello
},
setup(){
let car = reactive({
name:'奔驰',
price:'100w'
})
provide('car',car) // 给后代传入数据
return{
...toRefs(car)
}
}
};
</script>
<style scoped>
</style>
孙组件
<template>
<div class="ha">
<h2>子组件:哇哇哇哇--{{car.name}} {{car.price}}</h2>
<one></one>
</div>
</template>
<script>
import one from '../components/one.vue'
import { inject } from "vue";
export default {
components:{
one
},
setup(){
const car = inject('car')
console.log(car)
return{
car
}
}
};
</script>
<style scoped>
</style>
teleport 传送代码
在另外一个组件里面引用一下,这个的意思就是说
假如:没有使用teleport的时候,在A组件里面引入了这个B组件,那么点击 点我弹窗这个按钮的时候,B就会把A组件的元素撑大,那么使用了这个teleport这个api,就可以把代码发送到html body 或者别的元素id ,比如现在发送到body,就不会撑大A组件的元素
<template>
<div>
<button @click="isShow = true">点我弹窗</button>
<teleport to="body">
<div class='mask' v-if="isShow">
<div class="dialog">
<h3>我是一个弹窗</h3>
<h4>一些内容</h4>
<h4>一些内容</h4>
<h4>一些内容</h4>
<h4>一些内容</h4>
<button @click="isShow = false">关闭弹窗</button>
</div>
</div>
</teleport>
</div>
</template>
<script>
import { ref } from "vue";
export default {
setup() {
let isShow = ref(false);
return {
isShow
};
}
};
</script>
<style scoped>
.dialog {
width: 300px;
height: 300px;
background-color: yellow;
text-align:center;
position: absolute;
top:50%;
left:50%;
transform: translate(-50%,-50%);
}
.mask{
position: absolute;
top:0;
bottom: 0;
left:0;
right:0;
background-color:rgba(0,0,0,0.4)
}
</style>