文章目录
- 一、Vue3介绍
- 二、Vue3项目创建
- 1)使用vue-cli创建vue3项目
- 2)使用vite创建vue3项目
- 三、Setup函数
- vue2的创建vue实例和vue3创建vue实例的区别
- 四、ref和reactive
- 1)ref函数
- 2)reactive函数
- 3)reactive对比ref
- 4)setup的两个注意点
- 五、计算属性与监听属性
- 1)计算属性(computed函数)
- 2)监听属性(watch函数)
- 六、Vue3生命周期
- 七、toRef
一、Vue3介绍
关于vue项目的版本,新项目使用vue3,有部分老项目使用vue2。
vue3官方文档
vue3的变化
1.性能的提升-打包大小减少41%-初次渲染快55%, 更新渲染快133%-内存减少54%2.源码的升级使用Proxy代替defineProperty实现响应式重写虚拟DOM的实现和Tree-Shaking3.拥抱TypeScriptVue3可以更好的支持TypeScript4.新的特性Composition API(组合API)setup配置ref与reactivewatch与watchEffectprovide与inject新的内置组件FragmentTeleportSuspense其他改变新的生命周期钩子data 选项应始终被声明为一个函数移除keyCode支持作为 v-on 的修饰符# vue2配置项与vue3组合式的区别vue2 :配置项APInew Vue({el:'#app',data:{}})vue3: 组合式APIlet name='kiki'let add=()=>{ }
二、Vue3项目创建
1)使用vue-cli创建vue3项目
创建跟之前的vue2一样,只是在选择vue版本的时候选择vue3版本,同样用pycharm打开然后配置好配置项后运行即可。
vue create 名称 // 选择需要的配置 到版本选择3.X即可 npm run server // 运行服务器
vue3的项目简单解释
'main.js'import { createApp } from 'vue' # 通过 createApp创建vue实例import App from './App.vue' # 根组件import router from './router' # vue-routerimport store from './store' #vuexvar vue = createApp(App) # 创建vue实例vue.use(store)#使用vuexvue.use(router)# 使用vue-routervue.mount('#app')# 挂在index.html中得div'其他地方写起来跟之前写vue2完全一致,vue3是兼容的'
2)使用vite创建vue3项目
Vite 是一个轻量级的、速度极快的构建工具,对 Vue SFC 提供第一优先级支持。作者是尤雨溪,同时也是 Vue 的作者!是新建的前端构架工具,最大的优势就是速度快。
vite使用步骤
1. 安装---默认最新版npm create vue@latest // 这个命令可以根据自己的需求选择功能(如vue-router)npm create vite@latest //这个命令没有选择第三方插件2. 在项目中执行npm install 命令 ,虽然vite创建非常快,但是它没有安装依赖,所以需要自己安装一下没有这个node_modules依赖3 运行npm run dev启动项目注意点:4. vueRouter跟之前一样5. Pinia:用来替换Vuex的,新一代的状态管理器
三、Setup函数
简化代码和项目的简洁度,
vue
新增了setup
函数。
-
setup为Vue3.0中一个新的配置项,值为一个函数
-
setup是所有Composition API(组合API)编写的位置
-
组件中所用到的:数据、方法等等,均要配置在setup中
-
setup函数的返回值:返回一个对象,对象中的属性、方法, 在模板中均可以直接使用
-
注意:
尽量不要与Vue2.x配置混用- Vue2.x配置(data、methos、computed…)中可以访问到setup中的属性、方法。
但在setup中不能访问到Vue2.x配置(data、methos、computed…)。
如果有重名, setup优先。
- Vue2.x配置(data、methos、computed…)中可以访问到setup中的属性、方法。
任意一个页面组件看看效果
<template><div class="home"><h1>Setup函数</h1><hr><p>名字:{{name}}</p><p>年龄:{{age}}</p><button @click="addAge">点击年龄+10</button></div></template><script>export default {name: 'HomeView',setup(){// setup中没有this了// 以后所有的变量定义函数编写,都写在这个函数中// 定义变量 如果这么写,变量渲染没问题,但是没有响应式,页面变了,变量不会变// vue3中,默认是没有响应式的//1.定义变量,跟正常js一样,但是推荐使用let,而不是使用varlet name = 'jack'let age = 18//2.定义函数let addAge = () => {age+=10console.log(age) //可以发现变量是变了,但是没有响应式}//必须要有返回值,是个对象,返回的对象,可以在模版中使用return {name,age,addAge}}}</script>
vue2的创建vue实例和vue3创建vue实例的区别
'Vue2'1.new Vew()--->是Vue的实例,里面有$store,$refs....'Vue3'1.createApp(App)--->是个对象,对象里有东西,没有$store,$refs....等对象,当需要使用直接导入使用2.vue3的<template>,不需要写一个标签了3.定义变量/函数,都写在setup函数中,都要return函数,在<template>才能使用4.但是失去了响应式总结:1.在setup中定义的变量和函数,在之前配置项api中可以直接使用this.变量,函数调用即可2.但是在原来配置项中定义的变量,函数,在setup中无法使用
四、ref和reactive
1.导入使用:import {ref, reactive} from 'vue'2.基本数据类型(数字,字符串,布尔)如果要加响应式使用ref包裹,在模板中直接读取定义量js中通过对象.value取值3.对象,数组引用使用reactive,ref可以包对象类型,但是用的时候必须.value。操作数据与读取数据:均不需要.value
1)ref函数
- 作用: 定义一个响应式的数据
- 语法:
const xxx = ref(initValue)
- 创建一个包含响应式数据的引用对象(reference对象,简称ref对象)。
- JS中操作数据:
xxx.value
- 模板中读取数据: 不需要.value,直接:
<div>{{xxx}}</div>
- 备注:
- 接收的数据可以是:基本类型、也可以是对象类型。
- 基本类型的数据:响应式依然是靠
Object.defineProperty()
的ge
t与set
完成的 - 对象类型的数据:内部 求助 了Vue3.0中的一个新函数——
reactive函数
<template><div class="home"><h1>Setup函数</h1><hr><h3>ref函数</h3><p>名字:{{name}}</p><p>年龄:{{age}}</p><button @click="addAge">点击年龄+10</button> <button @click="handlerChange('吴彦祖')">点击修改名字</button></div></template><script>import {ref,reactive} from "vue";export default {name: 'HomeView',setup(){let name = ref('jack')let age = ref(18) //已经不是数字了,是RefImpl的对象//2.定义函数let addAge = () => {age.value+=10console.log(age) }let handlerChange = (data)=>{name.value = data //属性.value就可以对属性进行操作console.log(name)}//必须要有返回值,是个对象,返回的对象,可以在模版中使用return {name,age,addAge,handlerChange}}}</script>
2)reactive函数
- 作用: 定义一个对象类型的响应式数据(
基本类型不要用它,要用ref函数
) - 语法:
const 代理对象= reactive(源对象)
接收一个对象(或数组),返回一个代理对象(Proxy的实例对象,简称proxy对象) - reactive定义的响应式数据是“深层次的”
- 内部基于 ES6 的 Proxy 实现,通过代理对象操作源对象内部数据进行操作
<template><div class="home"><h1>Setup函数</h1><hr><h3>reactive函数</h3><p>用户名:{{userinfo.name}}</p><p>年龄:{{userinfo.age}}</p><p>爱好:{{userinfo.hobby[0]}},{{userinfo.hobby[1]}}</p><button @click="handlerClick">点击年龄+1</button></div></template><script>import {ref,reactive} from "vue";export default {name: 'HomeView',setup(){let userinfo=reactive({'name':'oscar','age':23,'hobby':['jump','rap']})let handlerClick = ()=>{userinfo.age++console.log(userinfo)}//必须要有返回值,是个对象,返回的对象,可以在模版中使用return {userinfo,handlerClick}}}</script>
3)reactive对比ref
从定义数据角度对比:ref用来定义:基本类型数据reactive用来定义:对象(或数组)类型数据备注:ref也可以用来定义对象(或数组)类型数据, 它内部会自动通过reactive转为代理对象从原理角度对比:ref通过Object.defineProperty()的get与set来实现响应式(数据劫持)。reactive通过使用Proxy来实现响应式(数据劫持), 并通过Reflect操作源对象内部的数据。从使用角度对比:ref定义的数据:操作数据需要.value,读取数据时模板中直接读取不需要.value。reactive定义的数据:操作数据与读取数据:均不需要.value。
4)setup的两个注意点
setup执行的时机在beforeCreate之前执行一次,this是undefined。setup的参数props:值为对象,包含:组件外部传递过来,且组件内部声明接收了的属性。context:上下文对象attrs: 值为对象,包含:组件外部传递过来,但没有在props配置中声明的属性, 相当于 this.$attrs。slots: 收到的插槽内容, 相当于 this.$slots。emit: 分发自定义事件的函数, 相当于 this.$emit。
五、计算属性与监听属性
1)计算属性(computed函数)
通过绑定ref和rective来编写计算(computed)
<script>import {ref, reactive,computed} from "vue";export default {name: 'StatsView',setup() {let person = reactive({firstname:'',lastname:'',})//计算属性----》获取值 ,单拎出来写// person.fullName = computed(()=>{// return person.firstname + person.lastname// })//计算属性----》修改值 //组合使用person.fullName = computed({get(){ //获取 触发它的执行return person.firstname + person.lastname},set(NewValue){ //修改 触发它,传入修改后的值console.log(NewValue)person.firstname = NewValue.substring(0,1)person.lastname = NewValue.slice(1)}})return {person,}},}</script><template><div><h1>计算属性:computed</h1><hr><p>姓:<input type="text" v-model="person.firstname"></p><p>名:<input type="text" v-model="person.lastname"></p><p>全名:{{person.fullName}}</p><p>全名修改:<input type="text" v-model="person.fullName"></p></div></template>
2)监听属性(watch函数)
<script>import {ref, reactive,computed,watch} from "vue";export default {name: 'StatsView',setup() {let count = ref(0)let AddCount = ()=>{count.value++}//监听基本类型watch(count,(NewValue,OldValue)=>{console.log(OldValue,NewValue)})//监听对象let userinfo = reactive({name:'jack',age:22})let handlerName=()=>{userinfo.name = '彭于晏'}watch(()=>userinfo.name,(NewValue,OldValue)=>{console.log('名字变更了:'+userinfo.name)})//可以同时监听多个变量/*const sum = ref(100)const msg = ref('很好')watch([sum, msg], (newValue, oldValue) => {console.log('sum或msg变化了', newValue, oldValue)}) */return {person,count,AddCount,userinfo,handlerName}},}</script><template><div><h1>监听属性:watch---基本类型</h1><p>数量:{{count}}</p><button @click="AddCount">点击数量+1</button><hr><h1>监听属性:watch---对象</h1><p>名字:{{userinfo.name}}</p><button @click="handlerName">点击变换名字</button><hr></div></template>
六、Vue3生命周期
- Vue3.0中可以继续使用Vue2.x中的生命周期钩子,但有有两个被更名:
- beforeDestroy改名为 beforeUnmount
- destroyed改名为 unmounted
- Vue3.0也提供了 Composition API 形式的生命周期钩子,与Vue2.x中钩子对应关系如下:
- beforeCreate===>setup()
- created=======>setup()
- beforeMount ===>onBeforeMount
- mounted=======>onMounted
- beforeUpdate===>onBeforeUpdate
- updated =======>onUpdated
- beforeUnmount ==>onBeforeUnmount
- unmounted =====>onUnmounted
七、toRef
- toRef的作用:创建一个 ref 对象,其value值指向另一个对象中的某个属性。
- 语法:
const name =toRef(person,'name')
- 应用: 要将响应式对象中的某个属性单独提供给外部使用时。
- 扩展:
toRefs
与toRef
功能一致,但可以批量创建多个ref 对象,语法:toRefs(person)
<script>import {ref,reactive,toRef,toRefs} from "vue";export default {name:'TorefView.',setup(){let data = reactive({name:'jack',age:22,hobby:'rap'})console.log({...toRefs(data)}) //解压赋值let count = ref(11)return {...toRefs(data),count} //解压赋值,后续写影响}}</script><template><h1>toRef函数</h1><hr><p>名字:{{name}}</p><p>年龄:{{age}}</p><p>爱好:{{hobby}}</p></template>