目录
Vue3
一、Vue3 初识
1、Vue3 简介
2、Vue3 特点:
3、创建 Vue3 工程项目
4、Vue3 目录结构分析
二、Composition API
1、setup 函数
2、setup 执行时间
三、ref 响应式函数
1、引言:
2、ref 函数
四、reactive 函数
五、Vue3 响应式原理
1、Vue2.x 的响应式原理
2、Vue3.0 响应式原理:
六、Vue3 中的组件传参
1、父传子
2、子传父
七、Vue3 中的计算属性
八、Vue3 中的 watch 监听器
九、Vue3 生命周期
十、Vue3 中自定义 hook 函数
十一、toRef 与 toRefs
十二、Vue3.0 中的路由
十三、Vue3.0 中的 Vuex
网址:Vue.js
2020.9.18 正式发布 Vue3.0 版本。 耗时 2 年多开发完毕。
向下兼容,可以使用 Vue2.0 语法完成 3.0 使用
1、性能提升
打包大小减少 41% ;
初次渲染快 51% ,更新渲染快 133%
内存占用减少 54%
2、源码升级
使用 Proxy
代替 Object.defineProperty
实现双向数据绑定
重写虚拟 DOM 的实现和 Tree-Shaking (按需打包)
Vue3 更好的支持 Typescript
3、新的特性
== composition API(组合式 api )==
setup 配置
ref 和 reactive
watch 和 watchEffect
provide 和 inject
提供了新的内置组件
Fragment Vue3 中 template 可以不需要顶层元素包裹
Teleport 指定组件挂载到页面的节点位置
Suspense 注意:setup 函数尽量不要和 Vue2.x 混合使用 vue2.x中的(data,methods,computed)可以访问到 setup 中的属性和方法 在 setup 中不能访问 Vue2.x 中的配置数据和方法如(data, methods, computed) 代码如下: 姓名:{{ name }} 年龄:{{ age }} 说话 {{ height }} 它是 Vue3.0 中的一个函数 作用:定义一个响应式的数据,只有数据成为响应式数据,这样当数据变化时,才能被监测到。 使用时需要从 Vue 中引入 语法:const xxx =ref(数据变量);结果 返回一个 RefImpl 的引用对象,获取时为 xxx.value 在页面模板中使用数据直接 使用插值表达式,不需要加value 姓名:{{ name }}异步组件 --
2、ref 函数
ref 函数实现数据响应式的原理还是利用了 Vue2 的 Object.defineProperty() 给数据设置 get set 监听函数,如下图:
接收的数据类型可以是基本类型 (实现响应式原理为Object.defineProperty()),也可以是对象类型(当为对象时,实现响应式的原理就是Proxy不是Object.defineProperty())
点击如下 change 事件,修改 name 和 age
{{ name }}--{{ age }}
{{ job.type }}--{{job.salary}}
说话
1、定义一个对象类型的响应式数据,返回一个Proxy 实例对象(基本类型响应式数据使用ref)。
语法:const 代理对象= reactive(源对象) ,接收一个对象或数组,返回一个代理对象(即Proxy源对象)
使用时先从vue中引入
代码如下:
{{ job.type }} --{{ job.salary }}--{{ job.like.a.b }}--{{job.content}}
{{ item }}
vue3中使用proxy 实现的数据响应去掉了vue2中不能检测到对象添加属性和通过下标修改数组而无法检测的情况。
实现原理:
通过 Object.defineProperty() 对属性的读取,修改进行拦截。(也叫数据劫持)即对数据的操作进行监听
let data = { name: "张三", age: 30 } let p = {} Object.defineProperty(p, 'name', { get() { console.log('访问了name属性'); return data.name }, set(val) { console.log('设置name属性'); data.name = val } }) //如上存在2个问题: // 无法添加和删除属性 // 无法捕获到修改数组下标改变对应数组
vue2.x 存在的问题
对象数据新增属性和删除属性,界面不会响应更新
{{ person.name }}
{{ person.age }}
{{ person.sex }}
数组数据直接通过修改下标,界面不会响应更新
{{ item }}
1、首先看一下vue3是否还存在vue2.x 中的问题。
对象数据新增属性和删除属性,不存在vue2.x 中的问题了。
{{ person.name }}
{{ person.age }}
{{ person.sex }}
数组数据直接通过修改下标,修改数组,不存在vue2.x 中的问题了。
{{ item }}
2、vue3.0响应式原理
vue3.0响应原理代码:
通过Proxy代理,拦截对象中任意属性的变化,包括属性的读取,修改、设置、删除。
通过Reflect 反射对被代理对象的属性进行操作。
let data = { name: "张三", age: 30 } console.log(Proxy); // 使用p 对象代理data, Proxy为window 下的内置代理函数 let p = new Proxy(data, { // 读取属性 get(target, propName) { // target 就是 data console.log(`读取p上个${propName}属性`); return Reflect.get(target, propName) }, // 修改和设置属性 set(target, propName, value) { // value 为赋的值 console.log(`修改p的${propName}属性`); // target[propName] = value Reflect.set(target, propName, value) }, //删除属性 deleteProperty(target, propName) { console.log(`删除p上的${propName}属性`); // return delete target[propName] return Reflect.deleteProperty(target, propName) } })
在父组件中给子组件设置自定义属性 tit,将要传递的参数赋值给tit属性
123
在子组件中接收传过来的属性通过props ,这个和vue2 一样没有变化。
{{ tit }}
给子组件绑定自定义事件,然后在setup中定义该事件对应的方法,因为setup中没有this ,this为undefined,所以vue的开发者为了解决该问题,在setup中提供了2个形参,prop和context
props 为父传子的参数
context 上下文对象,里面有emit 方法,可以实现子传父
子组件中多了 emits选项,该选项类似于props,接收父组件给子组件绑定的自定义方法,如果不加该选项,vue3 会提示警告。但不影响功能
{{ tit }}
在父组件接收自定义事件,该事件对应的执行函数的形参就是传过来的数据,这个就和vue2一样啦。
123
同vue2不同,使用计算属性需要引入computed 方法
姓:
名:
姓名:
vue3 中的watch 也是 组合式api中的一个方法,所以使用时,需要引入
{{ sum }}
{{ fullname }}
{{ userinfo.name }}--{{ userinfo.age }}--{{ userinfo.job.type }}--{{ userinfo.job.salary }}K
1、vue3中的生命周期钩子函数与vue2中基本相同,只有如下发生变化,其他都不变.
beforeDestory => beforeUnmount
destoryed => unmounted
第一种方式:不使用组合式api的方式使用生命周期函数
{{ sum }}
在app.vue 中引入子组件
第二种方式:通过使用组合式api的形式使用生命周期 ,vue3.0和vue2.x的生命周期对照表如下:
setup 等同于 beforeCreate 和created
{{ sum }}
hook函数定义:本质是一个函数,将setup中的公共逻辑抽离出来放在一个单独的js文件,这样哪个组件使用导入即可。
定义:toRef 创建一个ref 响应数据
语法:let name = toRef(person,'name') 将响应对象person中的name属性单独拿出来变成响应属性。
应用:一般用于将响应对象中的某个属性单独提供给外部使用
如下是使用toRef 前的代码: 插值表达式模板中的 person 有点繁琐
{{ person.name }} -- {{ person.age }} -- {{ person.job.type }} -- {{ person.job.salary }}
如下是使用toRef 后 的代码,
{{ name }} -- {{ age }} -- {{ type }} -- {{ salary }}
使用toRefs 可以将对象中的多个属性转换成响应数据,代码如下:
{{ name }} -- {{ age }} -- {{ job.type }} -- {{ job.salary }}
1、首先下载安装vue3.0 对应的vue-router
npm install vue-router@4
2、在src目录下新建router目录,在该目录下新建index.js 文件,代码如下
//1. 从vue-router 引入对应的方法createRouter 和 createWebHashHistory import { createRouter, createWebHashHistory } from "vue-router"; //2.配置路由规则 const routes = [ { path: '/home', component: () => import('@/views/Home') }, { path: '/category', component: () => import('@/views/Category') }, ] //3.创建路由对象 const router = createRouter({ history: createWebHashHistory(), routes }) export default router
3、在main.js 中引入并绑定
// 引入路由 import router from '@/router' // 在全局实例上挂载router,这样每个页面都可以访问路由 createApp(App).use(store).use(router).mount('#app')
1、首先需要安装vuex
npm install vuex@next --save
2、在src目录下创建store 文件夹,该目录下创建index.js文件,代码如下:
import { createStore } from 'vuex' export default createStore({ state: { count: 100 }, getters: { getCount(state) { return state.count * 2 } }, mutations: { setTestA(state, value) { state.count = value } }, actions: { }, modules: { } })
3、在main.js 引入然后使用挂载
import { createApp } from 'vue' import App from './App.vue' // 引入 store import store from '@/store' // 挂载使用 这样全局就可以使用store了 createApp(App).use(store).mount('#app')
4.在页面组件中使用store
{{ count }} ----{{ double }}
使用 Vite 来创建 Vue3 工程项目 :
_ref 来操作普通 html
计算属性 :