这里写目录标题
创建vue3项目
1.首先把vue-cli更新到4.5版本
npm i -g @vue/cli
2.vue create xxxx
1.路由
(1).路由需要安装Vue Router 4.0
npm install vue-router@next
(2).创建路由文件router/index.js
(3)去main.js挂载上路由
2.生命周期
setup 里面拿不到this
3.globalProperties
4.vuex
安装vuex
npm install vuex@next --save
创建store/index.js
挂载到vue上
组件内使用
<script>
import { onMounted,ref,reactive } from 'vue'
import { useStore } from 'vuex'
export default {
name:'home',
setup(){
const store = useStore()
console.log(store)
},
}
</script>
5.获取元素标签
原来vue2里面直接通过this.$refs.xx可以获取,但是在vue3里面需要,在setup里面const ce=ruf(null) 然后return出来,注意这个变量必须与标签上的ref要一致
**
vue3的新增加API
响应性 API
**
1.watch && watchEffect
watchEffect() 会立即执行传入的函数,并响应式侦听其依赖,并在其依赖变更时重新运行该函数。
<script>
import { watch,ref } from 'vue'
export default {
name:'modelPage',
props:{
showOrHide:Boolean
},
setup(props){
const showOrHides=ref(props.showOrHide)
watch(()=>props.showOrHide,(newl,old)=>{
showOrHides=newl
})
return{
showOrHides
}
},
}
</script>
const count = ref(0)
// 初次直接执行,打印出 0
watchEffect(() => console.log(count.value))
setTimeout(() => {
// 被侦听的数据发生变化,触发函数打印出 1
count.value++
}, 1000)
停止watchEffect监听
const stop = watchEffect(() => {
/* ... */
})
// 停止侦听
stop()
总结:
2.computed
const count = ref(1)
const plusOne = computed({
get: () => count.value + 1,
set: val => {
count.value = val - 1
}
})
plusOne.value = 1
console.log(count.value) // 0
3.isRef && isProxy && isReactive && isReadonly
isRef 用来判断某个值是否为ref()创建出来的对象
isProxy 检查对象是 reactive 还是 readonly创建的代理
isReactive 检查对象是否是 reactive创建的响应式 proxy
isReadonly 检查对象是否是由readonly创建的只读代理。
4.reactive && ref && toRef
reactive返回对象的响应式副本
ref接受一个内部值并返回一个响应式且可变的 ref 对象。ref 对象具有指向内部值的单个 property .value
toRef 是将某个对象中的某个值转化为响应式数据,其接收两个参数,第一个参数为 obj 对象;第二个参数为对象中的属性名
<template>
<p>{{ state1 }}</p>
<button @click="add1">增加ref</button>
<p>{{ state2 }}</p>
<button @click="add2">增加toRef</button>
<p>{{state3.count}}</p>
<button @click="add3">增加reactive</button>
</template>
<script>
import {reactive,ref, toRef} from 'vue'
export default {
setup() {
const obj = {count: 3}
const state1 = ref(obj.count)
const state2 = toRef(obj, 'count')
const state3=reactive({count:1})
function add1() {
state1.value ++
console.log('原始值:', obj);
console.log('响应式数据对象:', state1);
}
function add2() {
state2.value ++
console.log('原始值:', obj);
console.log('响应式数据对象:', state2);
}
function add3(){
state3.count++
console.log('原始值:', state3)
console.log('响应式数据对象:', state3.count);
}
return {state1, state2,state3, add1, add2,add3}
}
}
</script>
总结:
用 reactive() 创建的响应式对象,整个对象是响应式的,而对象里的每一项都是普通的值。当你把它用展开运算符展开后,整个对象的普通值都不是响应式的;
ref() 创建的响应式是将某个对象中的属性变成响应式数据,修改响应式数据是不会影响到原始数据。ref的本质是拷贝,与原始数据没有引用关系,ui视图会改变
toRef() 创建的响应式是将某个对象中的属性变成响应式数据,修改响应式数据是会影响到原始数据的。toRef的本质是引用,与原始数据有关联,ui视图不会改变
4.toRefs
toRefs() 可以将 reactive() 创建出来的响应式对象转换成内容为 ref 响应式的值的普通对象
当你需要展开 reactive() 创建的响应式对象,又不想让他们失去响应式特点的时候,就需要用 toRefs() 将它进行转
<template>
<div>
<p>当前的count值为:{{count}}</p>
<button @click="add">点击+1</button>
</div>
</template>
<script>
// 1\. 导入 toRefs
import {toRefs} from 'vue'
export default {
setup() {
// 定义响应式数据对象
const state = reactive({
count: 0
})
// 定义简单的函数,使count每次+1
const add = () => {
state.count++
}
// 将setup函数的内容return出去,供外界使用
return {
// 将 state 展开导出,同时将其属性都转化为 ref 形式的响应式数据
...toRefs(state),
add
}
}
}
</script>
5.shallowReactive && shallowRef
shallowReactive创建一个响应式代理,该代理跟踪其自身 property 的响应性,但不执行嵌套对象的深度响应式转换 (暴露原始值)。
const state = shallowReactive({
foo: 1,
nested: {
bar: 2
}
})
// 改变状态本身的性质是响应式的
state.foo++
// …但是不转换嵌套对象
isReactive(state.nested) // false
shallowRef创建一个 ref,它跟踪自己的 .value 更改,但不会使其值成为响应式的。
const foo = shallowRef({})
// 改变 ref 的值是响应式的
foo.value = {}
// 但是这个值不会被转换。
isReactive(foo.value) // false
1.teleport 传送门
to=“body” 把它传送到body上
<template>
<teleport to="body">
<div v-if="showOrHides" class="modelBox">
<div>
<div class="box">
<p></p>
<p></p>
<p></p>
<p></p>
</div>
<div class="box">
<p></p>
<p></p>
<p></p>
<p></p>
</div>
</div>
</div>
</teleport>
</template>
<script>
import { onMounted,watch,ref } from 'vue'
export default {
name:'modelPage',
props:{
showOrHide:Boolean
},
setup(props){
const showOrHides=ref(props.showOrHide)
watch(()=>props.showOrHide,(newl,old)=>{
showOrHides=newl
})
return{
showOrHides
}
},
}
</script>
<style>
.modelBox{
background-color:rgba(0, 0, 0, 0.1);
position: fixed;
top:0;
left: 0;
overflow: auto;
width:100%;
height:100%;
z-index: 2000;
}
.box{
width: 50px;
height:50px;
margin: 100px;
top: 50%;
left: 50%;
position: absolute;
margin-left:-25px;
margin-top:-25px;
}
.box:nth-of-type(2){
transform: rotate(45deg);
}
.box p{
width: 15px;
height: 15px;
background: #409eff;
border-radius: 50%;
position: absolute;
animation: run 1.5s infinite linear;
}
.box p:nth-of-type(1){ /*左上*/
left: 0;
top: 0;
}
.box p:nth-of-type(2){ /*右上*/
right: 0;
top: 0;
}
.box p:nth-of-type(3){ /*左下*/
left: 0;
bottom: 0;
}
.box p:nth-of-type(4){ /*右下*/
right: 0;
bottom: 0;
}
/*动画效果*/
@keyframes run{
0%{
transform: scale(0);
}
50%{
transform: scale(1);
}
100%{
transform: scale(0);
}
}
/*延迟动画效果 负值是解决蹦动的效果*/
.box:nth-of-type(1) p:nth-of-type(1){
animation-delay: -0.1s;
}
.box:nth-of-type(2) p:nth-of-type(1){
animation-delay: -0.3s;
}
.box:nth-of-type(1) p:nth-of-type(2){
animation-delay: -0.5s;
}
.box:nth-of-type(2) p:nth-of-type(2){
animation-delay: -0.7s;
}
.box:nth-of-type(1) p:nth-of-type(3){
animation-delay: -0.9s;
}
.box:nth-of-type(2) p:nth-of-type(3){
animation-delay: -1.1s;
}
.box:nth-of-type(1) p:nth-of-type(4){
animation-delay: -1.3s;
}
.box:nth-of-type(2) p:nth-of-type(4){
animation-delay: -1.5s;
}
</style>
然后去要使用的地方引入该组件
2.fragments
template 可以拥有多个根
3.emits
emits 可以是数组或对象,从组件触发自定义事件,emits 可以是简单的数组,或者对象作为替代,允许配置和事件验证。
<template>
<div @click="$emit('check')">
<h3>自定义事件</h3>
</div>
<template>
export default{
emits:['check]
}
$emit('click')定义的名字是click,会触发两次
<template>
<div @click="$emit('click')">
<h3>自定义事件</h3>
</div>
<template>
export default{
emits:['click]
}