入口-setup
在组件渲染时会优先执行 setup 中代码,执行时机为 beforeCreate 之前


setup 方法中的对象若想要在 template 中使用,需要将方法 return 出去:
<script>
export default {setup() {console.log('setup had run')const msg = "hello vue3"const logMsg = () => {console.log(msg)}return {msg,logMsg}}
}
</script><template><div><!-- 输出 msg 信息到页面 -->{{msg}}<br><button @click="logMsg"> botton</button></div>
</template>

以上代码可以用语法糖将其简化,只需在 script 标签添加 setup 即可,语法糖替代我们完成了 return 操作以及 export default 的操作
<script setup>console.log('setup had run')const msg = "hello vue3"const logMsg = () => {console.log(msg)}
</script>
reactive 和 ref 函数
reactive 的使用示例,将 state 的对象内容包裹:
<script setup>
//导入函数
import { reactive } from 'vue'
//执行函数,传入一个对象类型的参数,变量接收
const state = reactive({count: 0
})
const addCount = () => {state.count++
}
</script><template><div><button v-on:click="addCount">{{state.count}}</button></div>
</template>

若不使用 reactive 函数,则对象不会被动态的渲染到页面
若想要对非对象类型也添加,则可以使用 ref 函数
ref 即支持简单类型,也支持对象类型
<script setup>
//导入函数
import { ref } from 'vue'
//执行函数,传入一个对象类型的参数,变量接收
const state = ref({count: 0
})
const addCount = () => {//ref 产生的响应式对象数据,需要通过 .value() 获取state.value.count++
}
</script><template><div><button v-on:click="addCount">{{state.count}}</button></div>
</template>
computed 计算属性函数
<script setup>
//导入函数
import { ref } from 'vue'
//执行函数,传入一个对象类型的参数,变量接收
const count = ref(0)
const addCount = () => {//ref 产生的响应式对象数据,需要通过 .value() 获取count.value++
}
const arr = ref([1,2,3,4,5,6,7,8])
//导入 computed
import {computed} from 'vue'
//拿到 大于2 的所有数
const moreThan2 = computed(()=>{return arr.value.filter(item => item > 2)
})
</script><template><div><button v-on:click="addCount">{{count}}</button></div><br><div>{{arr}}<br>大于2的元素有:{{moreThan2}}</div>
</template>

设置 3 秒后执行自定义函数:
setTimeout(() => {arr.value.push(9,10)
},3000)
watch 基本使用和深度侦听
基本使用,侦听数据源
ref 对象无需加 value
//单个数据源
watch(count,(newVal,oldVal) => {console.log('侦听到了 count 变换',newVal,oldVal)
})//多个数据源
watch([c1,c2],([newC1,newC2],[oldC1,oldC2]) => {console.log('侦听到了 c1,c2 变换',[newC1,newC2],[oldC1,oldC2])
})
深度侦听,侦听对象以及对象的所有属性
watch(state,() => {console.log('侦听到了 count 变换')
},deep)
如果需要精确深度监听对象的某一个或几个属性,使用如下写法
第一个写监听的参数,第二个写要执行的回调函数
watch(() => state.value.count,() => console.log('count 发生了变换')
)
如果加 immediate ,则会在侦听器创建时立即触发回调
watch(state,() => {console.log('侦听到了 count 变换')
},immediate)
这种方式常在输入框的提示菜单中应用
生命周期函数
在特定的时期自动执行的函数
有:
setup
onBeforeMount :组件挂载前
onMounted
onBeforeUpdate : 组件刷新前
onUpdate
onBeforeUnmount : 组件删除前
onUnmounted
函数可以多次调用,顺次执行
onMountde( () => {console.log('组件挂载完毕,执行了函数1')
})onMountde( () => {console.log('组件挂载完毕,执行了函数2')
})onMountde( () => {console.log('组件挂载完毕,执行了函数3')
})
父子通信-父传子
父组件:可变参数传递时加冒号
<script setup>
import { ref } from 'vue';
import SonCom from './Son.vue'
const count = ref(0)
setTimeout(() => {count.value = 200
},3000)
</script><template><div><h1>父组件App</h1><SonCom :count="count" message="this is father" /></div>
</template>
子组件:通过 defineProps 接受父组件的数据
<script setup>const props = defineProps({message: String,count: Number})
</script><template><h3>子组件Son</h3><div>父组件传入的数据:{{message}}父组件传入可变参数:{{count}}</div>
</template>
父子通信-子传父
父组件通过 @ 标记事件
子组件通过 $emit 方法完善触发事件
<script setup>
import { ref } from 'vue';
import SonCom from './Son.vue'
const count = ref(0)
const countAdd = (num) => {count.value += num
}
</script><template><div><h1>父组件App</h1><SonCom @count-add="countAdd" />{{count}}</div>
</template>
<script setup>const emit = defineEmits(['count-add'])//子组件传递参数告诉父组件加多少const addCount = () => {emit('count-add',5)}
</script><template><h3>子组件Son</h3><div><button @click="addCount">触发自定义事件</button></div>
</template>

模版引用
通过 ref 标识获得真实的 dom 标签对象或者组件实例对象
<script setup>
import { onMounted } from 'vue';
import { ref } from 'vue';
import Son from './Son.vue';
//这就是 h1 标签的 dom 对象的标识
const h1Ref = ref(null)
//组件挂载完毕后,可以通过标识获取 dom 对象
onMounted(() =>{console.log(h1Ref.value)
})
//组件对象的 ref 标识,记得在 template 中挂载该组件后才能获取到该组件对象
const sonRef = ref(null)
onMounted(() => {console.log(sonRef.value)
})
</script><template><h1 ref="h1Ref">dom h1</h1><Son ref="sonRef"/>
</template>
挂载组件:
<script setup>import { ref } from 'vue';//如果想要将组件的属性暴露给其他属性,写在 defineExpose 中const a = ref(0)defineExpose({a})
</script><template><h1>子组件</h1>
</template>

provide 和 inject
顶层组件向任意的底层组件传递数据和方法,实现跨层组件通信
顶层组件:
<script setup>
import { onMounted } from 'vue';
import { ref } from 'vue';
import Son from './Son.vue';
import { provide } from 'vue';
//顶层提供数据
provide('top-key',6)
const count = ref(0)
provide('count-key',count)
setTimeout(() =>{count.value++
},1000)
</script><template><h1 ref="h1Ref">dom h1</h1><Son/>
</template>
中间组件:
<script setup>import { ref } from 'vue';import SonSon from './SonOfSon.vue'
</script><template><h2>子组件</h2><SonSon/>
</template>
底层组件:
<script setup>import { inject } from 'vue';
const topKey = inject('top-key')
const countKey = inject('count-key')
</script><template><h3>弟中之弟</h3>顶层组件传递过来数据:{{topKey}},{{countKey}}
</template>
顶层组件可以通过 provide 和 inject 直接传输数据

如果想要在底层组件修改顶层组件的值,可以从顶层组件中传递一个修改值的方法给底层
