# createApp

在 Vue 3 中,改变全局 Vue 行为的API现在被移动到了由新的createApp 方法所创建的应用实例上。

调用 createApp 返回一个应用实例。该实例提供了一个应用上下文。应用实例挂载的整个组件树共享相同的上下文,该上下文提供了之前在 Vue 2.x 中“全局”的配置。

另外,由于 createApp 方法返回应用实例本身,因此可以在其后链式调用其它方法

vue3.0中使用createApp 来创建vue实例
import { createApp } from 'vue'
const app = createApp({})
import { createApp } from 'vue'
import App from './App.vue'
const app = createApp(App);
app.mount('#app');

main.js 下加载router、vuex
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
const app = createApp(App);
app.use(store)
app.use(router)
app.mount('#app');
合并之后的代码:
createApp(App).use(store).use(router).mount('#app')

# setup函数

1、简介

setup函数是vue3中专门为组件提供的新属性。

2、执行时机

创建组件实例,然后初始化props,紧接着就调用setup函数,会在beforeCreate钩子之前被调用。 3、模板中使用

如果setup返回一个对象,则对象的属性将会被合并到组件模板的渲染上下文。

4、如何使用

<template>
    <div>
         {{name}}
    </div>
</template>
<script>
import { reactive } from "vue"
export default {
props:{
    item:String
}
//setup函数会在beforeCreate之后,created之前执行 setup相当于是预设配置
//setup函数的第一个形参,接收props数据,通过props.item获取
setup(props){
//创建响应式数据对象
const state = reactive({
name:'abc'
})
//setup函数中将响应式数据对象return出去供template使用
return state
}
}
</script>

注意:在setup()函数中无法访问到this

# reactive函数

1、简介 reactive()函数接收一个普通对象,返回一个响应式的数据对象 2、基本语法 3、定义响应式数据供template使用

按需导入reactive函数
import { reactive} from "vue"
创建响应式数据对象
const state = reactive({ id:1 })

# ref的使用

1、简介 ref()函数用来根据给定的值创建一个响应式的数据对象,ref()函数调用的返回值是一个对象,这个对象 上只包含一个value属性 2、基本语法

import { ref } from "vue"
2)在setup()函数中调用ref()函数,创建响应式数据对象
setup(){
    var c = ref(10); //初始化值为10
    return {c}
}
3)在template中访问响应式数据
<template>
    <div>
        {{c}}
    </div>
</template>
<template>
<div>
<p>{{c}}</p>
<button @click="change()">click</button>
</div>
</template>
<script>
import { ref } from "vue"
export default {
setup(){
    var c = ref(10); //初始化值为10
    const change=()=>{ //方法的定义
    c.value+=1; //想改变值或获取值 必须.value
    }
    return {
        c,
        change
        };
    }
}
</script>

# ref()和reactive的不同

reactive的用法与ref的用法相似,也是将数据变成响应式数据,当数据发生变化时UI也会自动更新。 不同的是ref用于基本数据类型,而reactive是用于复杂数据类型 运行发现,基本数据传递给reactive,reactive并不会将它包装成porxy对象,并且当数据变化时,界面不会同步渲染变化

<template>
<div>
    <p>{{a}}</p>
</div>
</template>
<script>
import { ref,reactive,onMounted } from "vue"
export default {
setup(){
    const state = reactive({
        a:ref(99)
        })
    onMounted(()=>{ //生命周期-挂载完成
    setInterval(function(){
        state.a +=10
        },1000)
    })
    return state;
}
}
</script>

# toRefs的使用

1、简介 toRefs()函数可以将reactive()创建出来的响应式对象,转换为普通对象,只不过这个对象上的每个属性节点,都是ref()类型的响应式数据比如:当想要从一个组合逻辑函数中返回响应式对象时,用toRefs 是很有效的,该 API 让消费组件可以解构 / 扩展(使用 ... 操作符)返回的对象,并不会丢失响应性

1)按需导入toRefs函数

import { reactive ,toRefs } from "vue";

2)...toRefs(state)创建响应式数据对象

setup(){
let state = reactive({id:10});
return {
...toRefs(state)
};
}

3)在template中访问响应式数据

<template>
<div>
    <p>{{id}}</p>
</div>
</template>
return { //setup如果只返回state,可以return state但还有其它对象
//...state , 单向数据绑定,不支持双向数据渲染
//ES6中的扩展运算符和解构会把双向数据渲染的特性取消,除非用到toRefs来处理
//toRefs函数可以将reactive创建出来的对象都转化为ref形式的响应式数据
...toRefs(state), //转成ref形式的响应式数据
change //事件处理函数
}

# computed计算属性的使用

computed()用来创建计算属性,computed()函数的返回值是一个 ref 的实例

1)按需导入computed()
import { reactive ,toRefs ,computed} from "vue";
2)在setup()函数中调用computed()函数
setup(){
let state = reactive({
id:10,
n1:computed(()=>state.id+1) //计算属性的方式
n2:computed(function(){
state.id+2
})
});
}
3)在template中访问响应式数据
<template>
<div>
<p>{{n1}}</p>
<p>{{n2}}</p>
</div>
</template>
<template>
<div>
<p>{{n}}</p>
<button @click="change()">click</button>
</div>
</template>
<script>
import { reactive ,toRefs ,computed} from "vue";
export default {
setup() {
    let state = reactive({
    id:10,
    n:computed(()=>state.id+10) //计算属性的方式
    });

    function change() {
        state.id+=1;
        console.log(state.id);
    }
    return {
    ...toRefs(state),
    change
    }
},

# watch的使用

watch() 函数用来监视某些数据项的变化,从而触发某些特定的操作

1)按需导入watch()
import { reactive ,toRefs ,watch} from "vue";
2)在setup()函数中调用watch()函数

setup() {
let state = reactive({
id:10,
});
watch(() => console.log(state.id))
},
<template>
<div>
<p>{{id}}</p>
<p>{{type}}</p>
<button @click="change()">click</button>
</div>
</template>
<script>
import { reactive ,toRefs ,watch} from "vue";
export default {
setup() {
    let state = reactive({
        id:10,
        type:'偶数'
    });
    //监听state.id的值的变化
    watch(() => state.id, (cur, old) => {
        if(cur % 2 == 0 ){
            state.type = '偶数'
        }else {
            state.type = '奇数'
        }
    })

    function change() {
    state.id+=1;
    }
    return {
    ...toRefs(state),
    change
    }
},
};
</script>

4、清除监听

<template>
<div>
<p>{{id}}</p>
<p>{{type}}</p>
<button @click="change()">click</button>
</div>
</template>
<script>
import { reactive ,toRefs ,watch} from "vue";
export default {
setup() {
    let state = reactive({
        id:10,
        type:'偶数'
        });
    // 创建监听,并得到停止函数
    const stop = watch(() => state.id, (cur, old) => {
        if(cur % 2 == 0 ){
            state.type = '偶数'
        }else {
            state.type = '奇数'
        }
    })
    function change() {
        state.id+=1;
        if(state.id == 15){
        // 调用停止函数,清除对应的监听
            stop()
        }
    }
    return {
    ...toRefs(state),
    change
    }
    },
};
</script>

# 生命周期钩子函数

1)新版的生命周期函数,可以按需导入到组件中,且只能在 setup() 函数中使用
import { onMounted, onUpdated, onUnmounted} from "vue";
2)在setup()函数中调用computed()函数
setup(){
    onMounted(() => {
    console.log('mounted!')
    })
    onUpdated(() => {
    console.log('updated!')
    })
    onUnmounted(() => {
    console.log('unmounted!')
    })
}

3、新旧对比

beforeCreate -> use setup()

created -> use setup()

beforeMount -> onBeforeMount

mounted -> onMounted

beforeUpdate -> onBeforeUpdate

updated -> onUpdated

beforeDestroy -> onBeforeUnmount

destroyed -> onUnmounted

errorCaptured -> onErrorCaptured

# provide和inject

1、简介 provide()和 inject()可以实现嵌套组件之间的数据传递。这两个函数只能在 setup()函数中使用。

父级组件中使用 provide()函数向下传递数据;子级组件中使用 inject()获取上层传递过来的数据。

父组件:
1)按需导入provide()
import { reactive ,toRefs ,provide} from "vue";
2)在setup()函数中调用provide()函数
setup() {
// 父级组件通过 provide 函数向子级组件共享数据
//provide('要共享的数据名称', 被共享的数据)
provide('globalColor', 'red')
},
子组件:
1)按需导入inject()
import { reactive,toRefs,inject} from "vue"
2)在setup()函数中调用inject()函数
setup(props){
const state = reactive({
//调用 inject 函数时,通过指定的数据名称,获取到父级共享的数据
color : inject("globalColor")
})
return state
}

# Suspense 异步组件

1、什么是Suspense组件

Suspense组件用于在等待某个异步组件解析时显示后备内容。

2、何时使用它

1、在页面加载之前显示加载动画 2、显示占位符内容 3、处理延迟加载的图像

插槽包裹异步组件
<Suspense>
<template #default>
<Async/>
</template>
</Suspense>
具名插槽的缩写是在 vue2.6.0 新增,跟 v-on 和 v-bind 一样,v-slot 也有缩写, 替换为字符 #。
例如 v-slot:header 可以被重写为 #header

插槽包裹渲染异步组件之前的内容
<Suspense>
<template #fallback>
<h1>Loading...</h1>
</template>
</Suspense>

# Vue Router 4

现在我们安装 vue-router 版本的时候,默认还是安装的 3.x 版本的, 由于vue3 的更新发生很大的变化,所以为了兼容处理,vue-router 也将发布最新版 4.x 版本了。

1、创建方式

利用createRouter 用来创建router对象

2、路由模式 router 3的用法:

const router = new VueRouter({mode: 'hash' / 'history'})

router 4的用法

createWebHashHistory路由模式路径带#号
createWebHashHistory (hash)
createWebHistory路由模式路径不带#号()
createWebHistory(history)
import { createRouter,createWebHashHistory } from 'vue-router'
const router = createRouter({
history: createWebHashHistory(),
routes
})

3、组件中的使用

因为setup中不能访 this,所以提供两个api来获取 router 和 route ,useRouter() 和 useRoute()

# 路由守卫

路由守卫分类

1 、全局前置守卫 beforeEach

router.beforeEach((to, from, next) =>{
to: Route:导航到的目标Route对象
from: Route:当前路线被导航离开
next: Function:必须调用此函数来解析钩子
console.log(to);
if (!sessionStorage.getItem("username")) { //如果没有签到或打卡
if (to.path !== '/home') {
next('/home')
}
};
next()
})

2 、全局后置守卫 afterEach

router.afterEach((to, from) =>{
// ...
})

3、 全局解析守卫 beforeResolve 和router.beforeEach类似,区别是在导航被确认之前,同时在所有组件内守卫和异步路由组件被解析之 后,解析守卫就被调用

4 、路由专享守卫 beforeEnter

5 、组件内守卫 beforeRouteEnter,beforeRouteUpdate,beforeRouteLeave

<script>
import { reactive, toRefs } from "vue"
export default {
setup(props, context) {
const state = reactive({});
return {
...toRefs(state),
};
},
beforeRouteEnter (to, from, next) { //组件内守卫
// 在渲染该组件的对应路由被 confirm 前调用
// 不!能!获取组件实例 `this`
// 因为当守卫执行前,组件实例还没被创建
},
beforeRouteUpdate (to, from, next) {
// 在当前路由改变,但是该组件被复用时调用
// 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候,
// 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
// 可以访问组件实例 `this`
},
//离开守卫通常用来禁止用户在还未保存修改前突然离开。导航该可以通过next(false)来取消
beforeRouteLeave (to, from, next) {
// 导航离开该组件的对应路由时调用
// 可以访问组件实例 `this`
}
}
</script>

# 导航解析流程

1) 导航被触发

2) 在失活的组件里调用离开守卫beforeRouteLeave(to,from,next)

3)调用全局前置守卫 beforeEach(to,from,next)

4) 在复用的组件里调用beoreRouteUpdate(to,from,next)

5) 在路由配置里调用路由独享的守卫beforeEnter()

6)解析异步路由组件

7)在被激活的组件里调用beforeRouteEnter(to,from,next)

8)调用全局解析组件beforeResolve

9) 导航被确认

10) 调用全局后置守卫afterEach()

11)触发DOM更新

12) 用创建好的实例调用beforeRouteEnter守卫中传递给next的回调函数

# Vuex4

1、创建方式

创建 store 容器实例

import { createStore } from 'vuex'
const state = {
isNavShow:true
};
var getters = {
showNav(state){
return state.isNavShow
}
}
const actions={
SHOWNAV({commit}){
commit('SHOWNAV');
},
HIDENAV({commit}){
commit('HIDENAV');
}
};
const mutations = {
SHOWNAV(state){
state.isNavShow=true;
},
HIDENAV(state){
state.isNavShow=false;
},
};
const store = createStore({
state,
getters,
actions,
mutations
})
//导出store对象
export default store;

2、组件中的使用

import { useStore } from "vuex"; //导入vuex
export default {
props:{
name:String
},
setup(props) {
let store = useStore(); //定义store
const state = reactive({});
return {
...toRefs(state),
store
};
},
}

3、State 和 Getters 的用法

import { useStore } from "vuex"; //导入vuex
export default {
props:{
name:String
},
setup(props, context) {
let store = useStore(); //定义store
const state = reactive({
showNav:computed(()=>store.getters.showNav)
});
return {
...toRefs(state),
store
};
},
}

4、Mutations 和 Actions 的用法

import { useStore } from "vuex"; //导入vuex
export default {
props:{
name:String
},
setup(props, context) {
let store = useStore(); //定义store
const state = reactive({
showNav:computed(()=>store.getters.showNav)
});
return {
...toRefs(state),
store
};
},
}
import { useStore } from "vuex"; //导入vuex
export default {
props:{
name:String
},
setup(props, context) {
let store = useStore(); //定义store
const state = reactive({});
onUnmounted(()=>{ //生命周期-销毁
store.dispatch('SHOWNAV'); //触发actions
//store.commit('SHOWNAV'), // 触发mutations
})
onMounted(()=>{ //生命周期-挂载完
store.dispatch('HIDENAV');
})
return {
...toRefs(state),
store
}
}
Last Updated: 11/10/2022, 8:55:17 PM