node需要16.0版本以上,如何升级node参考[mac升级node](https://blog.csdn.net/weixin_43676252/article/details/128578911)
npm init vue@latest
<script>
// vue2写法
export default {
setup() {
console.log('setup')
let count = 1
const 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 = 1
const addcount = () => {
console.log(count);
}
</script>
<template>
<button @click="addcount">+{{ count }}</button>
</template>
共同点:用函数调用的方式生成响应式数据
区别:
用法:推荐使用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>
需注意:
<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>
<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 |
---|---|
beforeCreate/created | setup |
beforeMount | onBeforeMount |
mounted | onMounted |
beforeUpdate | onBeforeUpdate |
updated | onUpdated |
beforeUnmount | onBeforeUnmount |
unmounted | onUnmounted |
父传子
<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>