vue 3

一、安装前提

node需要16.0版本以上,如何升级node参考[mac升级node](https://blog.csdn.net/weixin_43676252/article/details/128578911)

二、创建vue3项目

npm init vue@latest

三、setup

<script>
// vue2写法
export default {setup() { console.log('setup')let count = 1const addcount = () => { console.log(count);}return {count,addcount}},beforeCreate() { console.log('beforeCreate')}
}
</script>
<template><button @click="addcount">+{{ count }}</button>
</template>

注意:setup比beforeCreate先执行,setup中生命的变量和函数,一定要return出去,才能在dom中使用和调用,如果变量和函数太多的话,这种方式显然不方便,所以,vue3中有了setup语法糖的用法,用法如下:

<script setup>//vue3写法let count = 1const addcount = () => { console.log(count);}
</script>
<template><button @click="addcount">+{{ count }}</button>
</template>

四、reactive和ref

共同点:用函数调用的方式生成响应式数据
区别:

  • reactive的参数只能是对象类型
  • ref可以是对象类型,也可以是简单类型
  • ref在脚本区域必须通过.value访问修改
  • ref内部实现依赖于reactive

用法:推荐使用ref

<script setup>
// reactive
import { reactive } from "vue";
const  param = reactive({ count: 0 });
const addcount = () => {console.log(param);param.count++
};
// ref
import { ref } from 'vue'
const refCount = ref(0)
const addrefCount = () => { refCount.value++
}
</script>
<template><!--  reactive --><button @click="addcount">+{{ param.count }}</button><!-- ref --><button @click="addrefCount">+{{ refCount }}</button>
</template>

五、computed计算属性函数

需注意:

  • 计算属性函数中,只负责计算数值,不应该有异步请求或者修改dom之类的操作,这些操作可以放在watch中实现
  • 避免直接修改计算属性的值,例子中的newArr
    用法:
<script setup>
import { ref,computed } from 'vue'
const refArr= ref([1,2,3,4,5,6])
const newArr = computed(() => { return refArr.value.filter(item=>item>2)
})
</script>
<template><div>{{ refArr }}</div> //[ 1, 2, 3, 4, 5, 6 ]<div>{{ newArr }}</div>//[ 3, 4, 5, 6 ]
</template>

如果改变refArr的值

<script setup>
import { ref,computed } from 'vue'
const refArr= ref([1,2,3,4,5,6])
const newArr = computed(() => { return refArr.value.filter(item=>item>2)
})
setTimeout(() => {refArr.value.push(7,8)
}, 3000);
</script>
<template><div>{{ refArr }}</div> //一开始是[ 1, 2, 3, 4, 5, 6 ],三秒之后是[ 1, 2, 3, 4, 5, 6, 7, 8 ]<div>{{ newArr }}</div>//一开始是[ 3, 4, 5, 6 ],三秒之后是[ 3, 4, 5, 6, 7, 8 ]
</template>

六、watch函数

<script setup>
import { ref, watch } from 'vue'const count = ref(0)
const age = ref(18)
const addCount = () => { count.value++
}
const addAge = () => { age.value++
}// 监听一个变量
watch(count, (newCount,oldCount) =>{
console.log(count.value,newCount,oldCount); //1 1 0
})// 监听多个变量
watch([count, age], ([newCount, newAge], [oldCount, oldAge]) => { 
console.log(count.value,newCount,oldCount); //1 1 0
console.log(age.value,newAge,oldAge); //1 1 0
})// immediate和deep用法
// watch(count, (newCount,oldCount) =>{
// console.log(count.value,newCount,oldCount); //1 1 0
// }, {immediate:true,deep:true})// watch监听的ref对象默认是浅层监听,直接修改嵌套的对象属性不会触发回掉
const state = ref({ age: 10 })
const addstate = () => { state.value.age++
}
watch(state, () => { console.log(state) //不会打印
})
watch(state, () => { console.log(state.value.age) //开启deep,会打印
}, { deep: true })// 只监听对象中的某个字段
const json = ref({ name: '章三', age: 18 })
const addJsonAge = () => { json.value.age++
}
watch(() => json.value.age, (newAge,oldAge) => { 
console.log(json.value.age,newAge,oldAge);
})
</script>
<template><button @click="addCount">++{{ count }}</button><button @click="addAge">++{{ age }}</button><button @click="addstate">++{{ state.age }}</button><button @click="addJsonAge">++{{ json.age }}</button>
</template>

七、生命周期API

选项式API组合式API
beforeCreate/createdsetup
beforeMountonBeforeMount
mountedonMounted
beforeUpdateonBeforeUpdate
updatedonUpdated
beforeUnmountonBeforeUnmount
unmountedonUnmounted

八、父子传值

父传子

<script setup>
import { ref } from 'vue'
import son from '@/views/son.vue'
const count = ref(200)
</script><template><h2>父组件</h2><son :count="count"/>
</template><style scoped>
</style>
<script setup>
const props = defineProps({count:Number
})
console.log(props.count);
</script><template><div>子组件</div><div>父组件传过来的值{{ count }}</div>
</template><style scoped>
</style>

子传父

<script setup>
import { ref } from 'vue'
import son from '@/views/son.vue'
const count = ref()
const getCount = (param) => { count.value = param
}
</script><template><h2>父组件</h2><div>子组件传过来的{{ count }}</div><son @get-count="getCount"/>
</template><style scoped>
</style>
<script setup>
// defineEmits(['事件名称''事件名称'])
const emit = defineEmits(['get-count'])
const sendCount = () => { console.log(1);emit('get-count',300)
}
</script><template><div>子组件</div><button @click="sendCount">点我</button>
</template><style scoped>
</style>

九、模版引用

vue2:

this.$refs.form.submit()

vue3:访问当前组件的dom

<script setup>
import { ref,onMounted } from 'vue'
import son from '@/views/son.vue'
// 第一步 通过ref生成ref对象
const parentRef = ref(null)// 第三步,挂载之后才可以调用到
onMounted(() => {console.log(parentRef.value);
})</script><template><!-- 第二步 通过ref标识绑定ref对象 --><div ref="parentRef">父组件</div><son  />
</template><style scoped>
</style>

vue3访问子组件的属性和方法

<script setup>
import { ref,onMounted } from 'vue'
import son from '@/views/son.vue'
// 第一步 通过ref生成ref对象
const sonRef = ref(null)// 第三步,挂载之后才可以调用到
onMounted(() => {sonRef.value.setName()console.log(sonRef.value.name);
})</script><template><!-- 第二步 通过ref标识绑定ref对象 --><div >父组件</div><son ref="sonRef" />
</template><style scoped>
</style>
<script setup>
import { ref } from 'vue'
const name = ref('test name')
const setName = () => { name.value = 'test new name'
}
// 默认情况下<script setup>语法糖下组件内部的属性和方法是不开发给父组件的,
// 可以通过defineExpose编译宏知道哪些属性和方法允许访问
defineExpose({name,setName
})
</script><template><div>子组件</div>
</template><style scoped>
</style>