Vue2进阶Vue3学习
-
项目初始化 – 使用vite创建项目
1. npm init vite 2. yarn create vite 3. vue create 项目名称 --vue-cli创建
-
setup
在Vue3中,定义methods、watch、computed、data数据都放在了setup()函数中 vue3.2中<script setup></script>不用写返回值 vue3 <script> import {ref} from 'vue' setup(){ let str = ref('1111') return str } </script>
-
全局引入ElementPlus
1.安装 npm install element-plus --save yarn add element-plus 2. 在main.js中引入 import ElementPlus from 'element-plus' import 'element-plus/dist/index.css' createApp(App).use(ElementPlus).mount('#app')
-
自动按需导入不用配置main.js
1. 安装插件 npm install unplugin-vue-components -D 2.引入配置 import Components from 'unplugin-vue-components/vite' import {ElementPlusResolver} from 'unplugin-vue-components/resolvers' export default defineConfig({ plugins: [ vue(), Components({ resolvers:[ElementPlusResolver()] }) ] })
-
ref,reactive,toRef
处理响应式的数据 reactive 和 ref 都是用来定义响应式数据的 reactive更推荐去定义复杂的数据类型 ref 更推荐定义基本类型 ref定义的数据访问的时候要多一个.value <script setup> import {ref,reactive} from 'vue' let id = ref('22') </script> 1.toRef 创建一个ref类型数据, 并和以前的数据关联 2.toRefs 批量创建ref类型数据, 并和以前数据关联 3.toRef和ref区别 ref-创建出来的数据和以前无关(复制) toRef-创建出来的数据和以前的有关(引用) ref-数据变化会自动更新界面 toRef-数据变化不会自动更新界面
-
父子组件传值
1. 父组件传值子组件props 子组件 <template> {{props.num}} </template> <script setup> const props = defineProps({ num:Number }) </script> 父组件 <template> <List :num="num"> </template> <script setup> import {ref,reactive} from 'vue' const num = ref("333") </script> 2.子组件传递父组件emit <template> <button @click="change()">子组件按钮</button> </template> <script setup> import {ref} from "vue" const emit = defineEmits(['el-child']) const sub = ref("list") function change(){ emit("el-child",sub.val) } </script> 父组件 <template> <List :num="num" @el-child="changeNum"> </template> <script setup> import {ref,reactive} from 'vue' const num = ref("333") function changeNum(v){ num.value =v;//v为子组件传递的值 } </script>
-
生命周期
使用前必须导入 import { onMounted, onUpdated, onUnmounted } from 'vue' setup相当于vue2的beforecreate和create onBeforeMount(()=>{ add().then(res=>{ num.val = res.val }) }) onMounted onUpdated onBeforeUpdated onBeforeUnmount onUnmounted onErrorCaptured //错误捕获
-
this调用
在vue3中this是无法直接使用的,直接使用this是undefined import { getCurrentInstance } from "vue"; 使用getCurrentInstance 方法去获取和使用,它所在页面this。 let this = getCurrentInstance();
-
双向数据绑定
vue2使用的是Object.defineProperty vue3中更改为Proxy vue2利用Object.defineProperty来劫持data数据的getter和setter操作。(缺点:必须循环遍历所有的域值才能劫持每一个属性。缺陷:无法监听数组变化)。将它替换为es6的Proxy,在目标对象之上架了一层拦截,代理的是对象而不是对象的属性。这样可以将原本对对象属性的操作变为对整个对象的操作。javascript引擎在解析的时候希望对象的结构越稳定越好,如果对象一直在变,可优化性降低,proxy不需要对原始对象做太多操作。
-
路由配置及使用
1. 页面使用<router-view></router-view> <router-link :to="{name:'',parmas:{}}"></router-link> 2. router.js路由配置 import { createRouter, createWebHistory } from 'vue-router'; const router = { { path:"/home", name:"Home" component:() => import('./Home.vue') children:[{ path:"/homeChild", name:"HomeChild" component:() => import('./HomeChild.vue') }] } } export const router = createRouter({ history: createWebHistory(), routes:router }) 3. main.js导入路由使用 import { createApp } from 'vue' import App from './App.vue' import router from "./router" const app = createApp(App);app.use(router)app.mount('#app') 4. 使用useRoute和useRouter import {useRoute,useRouter} from 'vue-router' //传递参数使用query的话,指定path或者name都行,但使用params的话,只能使用name指定 const router = useRouter() function pushRouter(){ router.push({ path:"/home", query:{num:1} }) } const route = useRoute() let num = route.query.num
-
computed和watch,watchEffect
import {computed,watch} from 'vue' let num = ref(0) let num1 = 1; let num2 = 2; const clickFunc = ()=>{ num++ } let sun = computed(()=>{ return num1 + num2 }) //watch能一次监听多个数据,如监听一个数据在第一个参数传递就行,多个使用数组传递 watch([num,num2],(nweValue,oldValue)=>{ console.log(newValue,oldValue) },{immediate:true,deep:true} ) //watchEffect不用写监听对象,只要函数内的变量进行改变就会监听,但不会返回nweValue和oldValue watchEffect(()=>{ console.log(num) })
-
nextTick()
定义:在下次 DOM 更新循环结束之后执行延迟回调。在修改数据之后立即使用这个方法,获取更新后的 DOM。nextTick(),是将回调函数延迟在下一次dom更新数据后调用,简单的理解是:当数据更新了,在dom中渲染后,自动执行该函数 在vue2中 vue更新dom是异步的,当更新数据时,在dom渲染之后会执行callback函数 this.$nextTick(()=>{ 获取更新之后的值 console.log(this.$refs.app.innerHTML) }) 在vue3中直接使用 nextTick(){ console.log(DOM) }
-
在setup中不能使用async
1.使用<suspense> <suspense> <template #default> <todo-list /> </template> <template #fallback> <div> Loading... </div> </template> </suspense> <suspense> 组件有两个插槽。它们都只接收一个直接子节点。default 插槽里的节点会尽可能展示出来。如果不能,则展示 fallback 插槽里的节点。 2.使用生命周期钩子函数 onMounted(async()=>{ const res = await axios.get('url') })
-
teleport组件
//传送门组件,渲染到to绑定的元素之下 <teleport to="body"><teleport>
-
其他一些api
详情见https://zhuanlan.zhihu.com/p/146097763 effect() 和 reactive() shallowReactive() readonly() shallowReadonly() isReactive() isReadonly() isProxy() markRaw() 哪些数据是可以被代理的 markRaw() 函数用于让数据不可被代理 toRaw() ReactiveFlags 调度执行 effect - scheduler watchEffect() 异步副作用和 invalidate 停止一个副作用(effect) watchEffect() 与 effect() 的区别 track() 与 trigger() ref() isRef() toRef() toRefs() 自动脱 ref customRef() shallowRef() triggerRef() unref() Lazy 的 effect() computed() effect 的其他选项 onTrack 和 onTrigger