基于vue2快速上手vue3
创建vue项目
首先现在德vue3已经成为了默认德版本了,现在的创建vue项目的方式有两种:
1:使用脚手架,不走和vue2大致是一样的但是需要注意的是我们vue的版本必须要在4.5以上才能创建vue3项目,现在如果你还再使用vue2过渡到vue3的时候必须要更新开发者工具,不然它无法工作
2:使用一个新的构建工具vite这是vue团队基于vue推出的一套工具,它于weakpack不同之处就在于weaked是将我们所有的代码打包好后,然后将所有的志愿上传到服务器,然后再生成一个服务器端口,vite的原理是我先给你一个端口,你需要访问那部分资源,我再去加载
使用vite,需要自己打开项目文件夹去下载依赖
下面的知识点依然是基于脚手架去学习
分析vue3工程结构
main.js的变化
- vue2引入的是vue,vue3引入的是creatApp
- 因为引入的不再是一个构建函数所以创建的也不再是vm,而是app,app和vm有什么区别?其实他们的作用是类似的只不过app里去除了许多用不上的方法,属性
注意vue3并不兼用vue2的写法
App的变化
app中最大的变化即使书写html时不必加上一个根标签,当然你习惯了写也可以,其他的变化不大
常用的Composition API
组合式API
了解setup
例子如下:
首先式这个setup配置项的作用:在vue2的时候我们习惯于将数据放在data配置项中,方法放在methods配置项中,在vue3中就不再这样使用了,我们统一将这些数据方法都放在setup配置项中,然后将这些数据作为一个对象返回即可,在vue3中依然可以使用data,methods这些配置项,但不推荐混合使用因为setup无法访问data与methods中的数据,其次就是重名的问题
setup的两个注意点
首先setup中的参数问题:
首先是因为setup的执行时间所以无法访问到this(vc),所以之前通过this使用的数据都无法再访问,所以通过传递参数的方式调用这些参数
第一个参数是props:我们声明接受后(和vue2一样都要声明接受)的数据都会被做成代理对象放到props里面,这些数据都是响应式的
第2个参数是context:里面有几个十分有用的属性
attrs:props没有声明接收的属性都会放到attrs里面
slots:所拥有的插槽的信息,注意在vue3里面使用插槽必须要使用v-slot指令
emit:用于触发自定义事件,注意在vue3中使用自定义事件的时候,需要在触发事件的组件中使用一个emits配置项声明所定义的自定义事件,不然的话会有警告
ref函数
我们之前学习 vue2的时候有一个ref属性,这个属性的作用是为了获取dom节点
ref函数的作用
在上面的那个例子中我们提到了一个响应式数据的问题,也就是说我们上面的数据并不是响应式的我们更改setup中的数据后,页面的数据并不会更新,所以要实现相应式的数据我们必须要使用ref函数
ref函数的工作原理
我们将数据交给ref后,它会生成一个ref引用实例对象,然后它会将我们的数据保存在value中,并生成代理(set,get函数),然后根据set和get的调用页面进行更新,所以我们在使用ref函数后如果需要在setup中使用ref代理的数据就应该使用该ref引用对象中的value属性 ,但在模版中就不需要再使用value了,因为vue会自动帮我们调用.value
首先vue将我们的数据拿走后生成了一个引用实例对象
并通过object.denif…的方式配置好了该属性,就类似于vue2中的-data,然后再将value定义到引用对象身上方便访问
例子如下:
ref处理对象类型的数据
为普通的数据添加ref对象的时候:使用代理后可以直接通过使用value来使用对象,对象也是一样的使用,因为它深层已经为我们设置好了(它求助了reactive函数),就不需要我们自己考虑了
例子如下:
使用ref代理对象类型的数据的时候确实使用了,get和set代理了job这个变量,不过job.value底层求助了reactive来生成代理对象
reactive函数
作用:同样是生成响应式数据,不过这个函数只能用于生成对象类型的响应式数据,而ref则什么数据都可以使用,使用reactive代理对象数据后,在我们的script中使用对象数据也不需要加上.value(在html模版中直接使用即可)
其次reactive处理的对象式深层的也就是说,即使对象里面在嵌套几个对象数据它依旧能监测到
注意如果想要使数组里面的数据也变成响应式的数据也推荐使用reactive
对比ref和reactive
vue3中的响应式原理
vue2中检测对象数据的问题:就是说get和set只能监测的数据的修改和获取,但是对于增加属性和删除属性对象是无法监测到的,所以在vue2中对于对象增加和删除属性的方法是使用this.$set()与this.$delete方法
vue2中检测数组数据的问题:我们增加数组数据和删除数组数据只要调用数组中相应的方法vue就可以监测到但是通过下标修改数组的值是无法被vue监测到的,只能通过数组的方法进行修改
下面模拟vue2中的响应式原理
vue3中使用了reactive代理的方式,所以vue2中有关对象和数组的一些问题也被解决了
原理如下:简单点说就是使用了代理,代理了我们setup中的数据,所以我们在修改setup中的数据就可以通过代理完成,也正是因为代理所以我们可以在数据修改之前完成数据的响应(就是在代理的捕获函数中完成相应的代码),也正因为代理里面有增加删除的方法,所以vue3中没有vue2的问题
不过vue3的底层使用了反射,而不是直接返回对象的属性
计算属性和监视属性
计算属性
在vue3中虽然可以继续使用computed配置项但不推荐使用,vue3中的计算属性变成了一个函数
例子如下:
计算属性的简写写法
因为vue3中可以监视到对象属性的增删改查,所以可以改进上述代码
完整写法:
监视属性
监视ref定义的属性
监视ref定义的一个属性
同时监视多个属性
首先最简单的就是为每个属性都设置一个watch函数
其次可以多个属性使用一个wacth,只不过newvalue和oldvalue都变成了一个数组
如果watch函数想要设置immediate与其他的参数如何设置?直接将其作为第三个参数
监视reactive定义的属性
监视reactive定义的属性中的某个数据
监视reactive定义的属性中的某些数据
watchEffect函数
vue3中生命周期钩子的使用
自定义hook函数
例子如下:
toRef
最直接的作用就是将我们setup中的对象数据交出去的时候,在模版中使用时可以不再写重复的代码
toRefs
作用批量处理一个对象里面的所有属性
上面的代码中之所以要使用展开语法,是因为对象里面无法直接再写一个对象
其他的组合API
shallowReactive与shallowRef
首先是shallowReactive,浅层次的数据代理,只处理第一层的数据,其他的不管
就例如下面的例子中你修改person对象中的name,age,job 属性都是响应式的,但是j1就不是响应式的了
其次是shallowRef只会处理基本数据类型
readonly与shallowReadonly
readonly的主要作用是保护一个响应式的数据,使其所有的数据都不可被更改
shallowReadonly的主要作用是保护一个响应式的数据,但其只会保护第一层数据,其它层次的数据是可以更改的
toRaw与markRaw
markRaw的作用:如果如下代码我们直接给person添加一个属性的话那么这个属性一定是响应式的,有没有办法让这个数据不是响应式的呢?有的就是使用markRaw经过这个方法处理的数据都不是响应式的,但是数据还是会更改
customRef
这个函数的作用是自定义一个ref函数,里面获取值的逻辑以及更改值得逻辑都需要自己去实现
provide与inject
例子如下:
响应式数据的判断
Composition API的优势
新的组件
Fragment组件
Teleport
Vue3中的其他改变
router使用方法的改变
首先是创建router方式的改变:首先roure的创建也不再是通过引入钩爪函数来创建router,而是通过引入createRouter函数来改变,其次就是mode:history也被createWebHashHistory()所代替了
例子如下:
import { createRouter,createWebHashHistory} from "vue-router"
//1. 定义要使用到的路由组件 (一定要使用文件的全名,得包含文件后缀名)
import Found from "../page/Found.vue"
import Me from "../page/Me.vue"
import Country from "../page/Country.vue"
import View from "../page/View.vue"
// 2. 创建路由实例
const router = createRouter({
// (1)采用hash 模式
history: createWebHashHistory(),
// 配置路由路径
routes:[
//当浏览器没有任何 #锚点信息时,默认也给显示一个组件。
{
path: "/",
redirect: "/found",
},
{
path: "/found",
component: Found
},
{
path: "/country",
component: Country
},
{
path: "/view",
component: View
},
{
path: "/me",
component: Me
}
]
})
// 4. 导出router
export default router
在main.js中的改变
因为vue3中不再引入vue所以直接使用即可
import { createApp } from 'vue'
import App from './App.vue'
// 引入我们的路由器
import router from "./router"
const app=createApp(App);
// 使用我们自己创建的路由
app.use(router);
app.mount('#app')
在app或其他组件中的改变:
因为在setup中无法使用this,所以this. $ route和this.$router,也被两个函数所代替了:useRoute, useRouter
// 创建一个变量来保存router
const router= useRouter();
vuex使用方法的改变
一、基本结构
src/store/index.js中,代码如下:
// vue3中创建store实例对象的方法createStore()按需引入
import { createStore } from 'vuex'
export default createStore({
state: {
},
mutations: {
},
actions: {
},
getters: {
},
modules: {
}
})
2.注意一定要先在main.js中use,我们自己创建的store才能在其他组件中使用
import { createApp } from 'vue'
import App from '@/App.vue'
import store from '@/store/index.js' // 引入
const app = createApp(App)
app
// ...
.use(store)
.mount('#app')
export default app
3.基本使用:
<template>
<h2>{{ state.title }}</h2>
<div>{{ state.count }}</div>
<button @click="onCount">Count</button>
</template>
<script>
import { useStore } from 'vuex'
import { computed } from 'vue'
export default {
setup() {
const store = useStore() // 引入 useStore 类似 vue2 的 this.$store
const state = computed(() => { // 使用计算属性来监听数据的变化
return store.state
})
const onCount = () => {
store.commit('increment') // 触发 vuex 里定义的函数
}
return { // 返回出去供 template 模板访问
state,
onCount
}
}
}
</script>
4.注意看上面的代码:在模板中是没有办法直接使用store,要先使用计算属性监视state或者 let state=store.state;使用一个变量保存store.state,然后将该变量返回
上面的方法不知道为什么没有生效:(已经解决,没有在main.js中使用,还直接在模版中使用了store)
不过我们可以直接引入我们我们创建的store
<template>
<div>测试组件</div>
<hr>
<!-- 页面中直接使用渲染时与vue2中的使用方法相同 -->
<div>获取Store中的state、getters: {{$store.getters.formatInfo}}</div>
<button @click='handleClick'>点击</button>
</template>
<script>
// 按需引入useStore()方法
import { useStore } from 'vuex'
export default {
name: 'Test',
setup () {
// this.$store.state.info
// Vue3中store类似于Vue2中this.$store
// useStore()方法创建store对象,相当于src/store/index.js中的store实例对象
const store = useStore()
console.log(store.state.info) // hello
// 修改info的值
const handleClick = () => {
// 触发mutations,用于同步修改state的信息
// store.commit('updateInfo', 'nihao')
// 触发actions,用于异步修改state的信息
store.dispatch('updateInfo', 'hi')
}
return { handleClick }
}
}
</script>
如何通过ret函数获取dom节点
狗蛋儿588: 能不能换成白色主题? 黑色主题眼睛看着难受
小饼儿~: b站尚硅谷
CSDN-Ada助手: 多亏了你这篇博客, 解决了问题: https://ask.csdn.net/questions/8036779, 请多输出高质量博客, 帮助更多的人
2301_79697819: main33333错了
永恒达芬奇: 大佬'这个有word或者pdf版吗?想直接导入平板做笔记来着。感谢ing