新建vue3项目
vue3对比vue2有新的新建方式,对比传统的webpack,新的Vite,速度更快
步骤
//创建
npm create vue@latest
//安装依赖
npm install
//运行
npm run dev
vue3目录结构
除了项目中的md文件可以删除,其他的都不建议动
hello_vue3
vue3的入口文件为index.html,src中重点关注两个文件 main.ts 和 app.vue
其中main.ts
//导入一个盆
import { createApp } from "vue"
//导入根
import App from "./App.vue"
//引用
createApp(App).mount('#app')
其中app.vue 为基本的三段格式
<template>
<Person/>
</template>
<script lang="ts">
import Person from './components/person.vue'
export default {
name: 'App',
components:{Person}
}
</script>
<style>
</style>
组合式API(Composition API)
组合式与传统的选项式不一样,其数据方法都写在setup()方法中,使用return将数据返回
且使用组合式,this将为undefined
下面是一个简单的使用组合式的页面
<template>
<div>
<h2>姓名:{{ name }}</h2>
<h2>年龄:{{ age }}</h2>
<h2>地址:{{ address }}</h2>
<button @click="showtel">点击显示地址</button>
</div>
</template>
<script lang = "ts">
export default {
name : 'Person',
setup () {
let name ='uu'
let age = 16
let address = '湖南长沙'
function showtel () {
alert (address)
}
return {name,age,address,showtel}
}
}
</script>
<style scoped>
</style>
setup与Options API
setup的生命周期在选项式api的前面,所有
1.setup无法获取到选项式api(data,methods)中的数据与方法,但是反之可以
2.选项式中使用this可以进行数据的调用
setup语法糖
vue3中可以所用script标签来代替,且不需要return
<script lang = "ts">
export default {
name : 'Person',
}
</script>
<script lang="ts" setup>
let name ='uu'
let age = 16
let address = '湖南长沙'
function showtel () {
alert (address)
}
</script>
其中如果觉得为此多些一个script来定义name有些麻烦,还可以
安装插件 vite-plugin-vue-setup-extend
变成
<script setup name="Person"></script>
ref创建_基本类型的响应式数据
使用import导入ref
import {ref} from 'vue'
需要修改成响应式的数据使用ref包裹,修改则改value值
let name =ref('uu')
function changeName () {
name.value = '李四'
}
reactive创建_对象的响应数据
使用reactive方法包裹对象,修改则直接引用修改,操作数组也是使用reactive,可以直接进行更改
import { ref,reactive } from 'vue'
let p = reactive({name:'uuu',age:12,address:'chinese'});
function cc () {
p.name = '王五'
}
ref创建对象类型的响应数据
上面有指出使用ref来创建基本类型的响应数据,ref也可以用于创建对象的响应数据,只是需要使用value来读取
let p = ref({name:'uuu',age:12,address:'chinese'});
function cc () {
p.value.name = '春风拂面'
//如果p是数组
//p.value[0].name = ''
}
ref与reactive的区别
ref可以直接将整个对象进行覆盖,reactive不行,不过可是使用object.assign
所有:
当所用基本类型时使用ref
当对象层级不深时使用ref reactive都可以
当对象层级深时使用reactive
toref与torefs
作用:把响应式里的东西拿出来,并且具备响应式的能力
let {name,age} = toRefs(p)
let address = toRef(p,'address')
//以上都是响应式,且更改后对象里的数据也会更改 p就是上面定义的对象
computed计算属性
computed计算属性中可以放一下计算方法,其好处是当页面多次引用这个数据时,只要所依赖的数据不发生改变,那么只会做一次计算;
具体实现如下
//一下实现 computed属于使用ref的只读,不可修改
import {computed,ref} from 'vue'
let firstname = ref('zhang')
let lastname = ref('san')
let name = computed(()=>{
return firstname.value.slice(0,1).toUpperCase()+firstname.value.slice(1)+' '+lastname.value
});
要使用方法更改,需要使用get,set方法
let name = computed({
get () {
return firstname.value.slice(0,1).toUpperCase()+firstname.value.slice(1)+' '+lastname.value
},
set (val) {
const [str1,str2] = val.split('-')
firstname.value = str1
lastname.value = str2
}
})
function modifyName () {
name.value = 'li-si'
}
watch监听
watch可以监视四种数据:
ref定义的数据
reactive定义的数据
函数返回一个值(getter函数)
一个保函上述内容的数组
一共会出现五种情况
情况一
监视ref定义的基本数据类型的值,直接写数据名即可,监视的是其value值的改变
//监视对象是name(ref定义),其监视的是值的变化
watch (name,(newvalue,oldvlue)=>{
console.log(newvalue,oldvlue)
})
//----------------
//停止监视的方法
const stopwatch = watch (age,(newvalue,oldvlue)=>{
console.log('age',newvalue,oldvlue)
if(newvalue == 20){
stopwatch()
}
})
情况二
监视ref定义的对象
//单纯的监视对象,只有整个的值发生变化才会调用函数
watch (person,(newvalue,oldvlue)=>{
console.log('age',newvalue,oldvlue)
})
//可以后面跟参数,达到检测属性(deep),以及在创建对象时就进行监测()
watch (person,(newvalue,oldvlue)=>{
console.log('age',newvalue,oldvlue)
},{deep:true})
//上面改变对象某个属性后,其后值为一样的,只有整个对象发生改变时才不一样
情况三
检测reactive定义的对象,其默认是开启深度检测的,且无法关闭
//代码上与上面没什么区别,不同的点有打印检测的前后值都一样
//原因是其地址值没有发生变化,并非创建了一个新的对象
情况四
监测对象的属性时,且该属性的类型为基本类型要写成函数函数式,如果该属性是函数,也推荐使用函数式(不然函数替换时无法监测)
//监测对象如果是对象类型,建议写成函数式,注意:监测的如果是函数的地址值,需要手动开启深度
watch (()=>person.car,(newvalue,oldvlue)=>{
console.log('person',newvalue,oldvlue)
},{deep:true})
情况五
监测上述多个属性
watch ([()=>person.name,person.car],(newvalue,oldvlue)=>{
console.log('person',newvalue,oldvlue)
},{deep:true})
watchEffect
官网解释:立即运行一个函数,同时响应式的追踪其依赖,并在更改其依赖时执行此函数
可理解为这也是一个监听方法,且不需要指定具体监视什么数据,其函数内用到了什么数据,即监听什么数据
watchEffect(()=>{
if (temp >= 50 || height >= 60) {
console.log('发送一个请求')
}
})
标签的ref属性
可以用来html标签上,也可以用在组件标签上
html标签可以拿到dom元素
组件标签可以难道组件实例对象(需要用defineExpose()方法暴露)
props的使用
用于父类给子类传输数据
其中父类可直接在组件标签中定义
<Person a="上善若水"/>
子类页面使用defineProps接收
//html代码可以直接引用传输名,但是打印不行
<h2>{{ a }}</h2>
import {defineProps} from 'vue'; //define宏定义,不引用也可以直接使用
//defineProps接收数组
let x = defineProps(['a'])
//将defineProps整体定义起来,打印出来是一个函数
console.log(x)
接收共有几种格式
import { type Persons } from '@/types';
//只接收list
defineProps(['list'])
//接收list+类型限定
defineProps<{list:Persons}>()
//接收list + 限定类型 + 限制必要性(?)+指定默认值
withDefaults(defineProps<{list?:Persons}>(),{
list:()=>[{name:'fdsf',age:12,address:'湖南长沙'}]
})
vue3的生命周期
vue3与vue2有所不同
setup内即是 创建与创建前
其余的 挂载前、挂载、更新前、更新…卸载(vue2是销毁),使用no…调用回调函数,如下
//挂载前
onBeforeMount(()=>{})
其中父与子的生命周期,是先加载子,再加载父
hooks
hooks把模块化发挥到极致
ts文件命名:use开头 如useOrder
如下
import { ref } from 'vue';
//定义一个无名函数
export default function () {
let num = ref(10)
function sum () {
num.value += 1
}
//向外部提供
return {num,sum}
}
引用
import useSum from '@/hooks/useSum';
const {num,sum} = useSum()