热身
模板标签的基本使用
<script setup>
import {ref} from 'vue';
const msg=ref('你好,vue3')
</script>
<template>
<span>{{msg}}</span>
</template>
简单
生命周期钩子
<script setup>
import {onMounted,onUnmounted,ref} from 'vue';
const count=ref(1)
const timter=ref('')
onMounted(()=>{
timer.value=setInterval(()=>{
count.value++
},1000)
})
onUnmounted(()=>{
clearInterval(timer.value)
})
</script>
<template>
</template
下一次dom刷新
<template>
<div>
<div ref="myParagraph" @click="changeMsg">
{{ msg }}
</div>
</div>
</template>
<script setup lang="ts">
import {ref,nextTick} from 'vue';
const myParagraph = ref<HTMLDivElement|null>(null)
const msg=ref('你好!vue')
const changeMsg=()=>{
msg.value="努力学习的仔仔"
nextTick(()=>{
console.log(myParagraph.value?.textContent)
})
}
</script>
<style lang="scss" scoped>
</style>
插槽用法 默认插槽和具名插槽
//父
<script setup>
import {ref} from 'vue';
import Child from './components/Child.vue'
const msg=ref('hello')
</script>
<template>
<Child>
<span>{{msg}}</span>
<template #header>
<h2>这是头部内容</h2>
</template>
<template #footer>
<h2>这是低部内容</h2>
</template>
</Child>
</template>
//子
<script setup>
</script>
<template>
<slot></slot>
<slot name="header"></slot>
<slot name="footer"></slot>
</template>
动态css(style中绑定变量)
<script setup>
import {ref,onMounted} from 'vue';
const myColor=ref('red')
const colorList=['red','blue','green']
onMounted(()=>{
setInterval(()=>{
myColor.value=colorList[Math.floor(Math.random()*3)]
},1000)
})
</script>
<template>
<p>我是p标签</p>
</template>
<style scoped>
p{
color: v-bind('myColor')
}
</style>
ref全家桶使用(ref、Ref、toRef、toRefs、isRef、unRef)
<script setup lang="ts">
import { ref, Ref, reactive,isRef, toRef } from "vue"
const initial = ref(10)
const count = ref(0)
// 挑战 1: 更新 ref
function update(value:number) {
// 实现...
count.value=value
}
/**
* 挑战 2: 检查`count`是否为一个 ref 对象
* 确保以下输出为1
*/
console.log(
isRef(count)?1:0
// impl ? 1 : 0
)
/**
* 挑战 3: 如果参数是一个 ref,则返回内部值,否则返回参数本身
* 确保以下输出为true
*/
function initialCount(value: number | Ref<number>) {
// 确保以下输出为true
console.log(isRef(value)?value.value:value === 10)
}
initialCount(initial)
/**
* 挑战 4:
* 为源响应式对象上的某个 `property` 新创建一个 `ref`。
* 然后,`ref` 可以被传递,它会保持对其源`property`的响应式连接。
* 确保以下输出为true
*/
const state = reactive({
foo: 1,
bar: 2,
})
const fooRef = toRef(state,'foo') // 修改这里的实现...
// 修改引用将更新原引用
fooRef.value++
console.log(state.foo === 2)
// 修改原引用也会更新`ref`
state.foo++
console.log(fooRef.value === 3)
</script>
<template>
<div>
<h1>msg</h1>
<p>
<span @click="update(count - 1)">-</span>
{{ count }}
<span @click="update(count + 1)">+</span>
</p>
</div>
</template>
事件修饰符(stop、once、provent、self)
<script setup lang="ts">
const click1 = () => {
console.log('click1')
}
const click2 = () => {
//
// e.stopPropagation()
console.log('click2')
}
</script>
<template>
<div @click="click1">
<div @click.stop="click2">
click me
</div>
</div>
</template>
响应式丢失
<script setup lang="ts">
import { reactive,toRefs } from 'vue';
function useCount(){
const state=reactive({
count:5
})
const change=(value:number)=>{
state.count=value
console.log(state.count)
}
return {
state:toRefs(state),
change
}
}
const {state:{count},change}=useCount()
console.log(count)
</script>
<template>
<button @click="change(count+1)">+1</button>
{{ count }}
<button @click="change(count-1)">-1</button>
</template>
toRefs是为了解决用ref或者reactive创建的响应式对象,被再次赋值或解构为一个新的变量时响应式丢失问题
组件间的 v-model
//父
<Child v-model:capitalize="first" v-model="last"/>
//子
<script setup lang="ts">
import { computed } from 'vue';
const props=defineProps(['capitalize','modelValue'])
const emits=defineEmits(['update:capitalize','update:modelValue'])
const change=(e:Event)=>{
let value=(e.target as HTMLInputElement).value
value=value.charAt(0).toUpperCase() + value.slice(1)
emits('update:capitalize',value)
}
const value=computed({
get(){
return props.modelValue
},
set(value){
emits('update:modelValue',value)
}
})
</script>
<template>
<input :value="capitalize" @input="change"/>
<input v-model="value"/>
</template>
钩子函数 vModelText的使用
<script setup lang="ts">
import { ref, vModelText } from 'vue';
const _vModelText = vModelText
vModelText.beforeUpdate = function (el, binding) {
if (el.value && binding.modifiers.capitalize) {
el.value = el.value.charAt(0).toUpperCase() + el.value.slice(1)
}
}
const v = ref('')
</script>
<template>
<input type="text" v-model.capitalize="v" />
</template>
props验证
<script setup lang="ts">
interface Props {
type: "primary" | "ghost" | "dashed" | "link" | "text" | "default"
}
withDefaults(defineProps<Props>(), {
type: "default"
})
</script>
<template>
<button>Button</button>
</template>
withDefaults 是 Vue 3 提供的一个工具函数,用于合并两个对象生成一个新的响应式对象
计算属性的读写
<script setup lang="ts">
import { ref, computed } from "vue"
const count = ref(1)
const plusOne = computed({
get(){
return count.value + 1
},
set(value){
count.value=value-1
}
})
/**
* 确保 `plusOne` 可以被写入。
* 最终我们得到的结果应该是 `plusOne` 等于 3 和 `count` 等于 2。
*/
plusOne.value++
</script>
<template>
<div>
<p>{{ count }}</p>
<p>{{ plusOne }}</p>
</div>
</template>
watch的使用
<script setup lang="ts">
import { ref, watch } from "vue"
const count = ref(0)
/**
* 挑战 1: Watch 一次
* 确保副作用函数只执行一次
*/
const unWatch=watch(count, () => {
console.log("Only triggered once")
unWatch()
})
count.value = 1
setTimeout(() => count.value = 2)
/**
* 挑战 2: Watch 对象
* 确保副作用函数被正确触发
*/
const state = ref({
count: 0,
})
watch(()=>state.value.count, () => {
console.log("The state.count updated")
})
// watch(state, () => {
// console.log("The state.count updated")
// },{
// deep:true
// })
state.value.count = 2
/**
* 挑战 3: 副作用函数刷新时机
* 确保正确访问到更新后的`eleRef`值
*/
const eleRef = ref()
const age = ref(2)
watch(age, () => {
console.log(eleRef.value)
},{
flush:"post"
})
age.value = 18
</script>
<template>
<div>
<p>
{{ count }}
</p>
<p ref="eleRef">
{{ age }}
</p>
</div>
</template>
shallowRef 的使用
<script setup lang="ts">
import { shallowRef, watch } from "vue"
const state = shallowRef({ count: 1 })
// 回调没被触发
watch(state, () => {
console.log("State.count Updated")
}, { deep: true })
/**
* 修改以下代码使watch回调被触发
*
*/
//下边代码不会触发
state.value.count=2
//正确的做法
state.value = {count:2}
</script>
<template>
<div>
<p>
{{ state.count }}
</p>
</div>
</template>
依赖注入
//父
provide('type','张三')
//子孙
const type=inject('type')