第一部分:单文件组件语法
vue3创建响应式对象:ref
接受一个内部值并返回一个响应式且可变的 ref 对象。
ref 对象仅有一个.value,指向该内部值。
<template>
<div>
<h1>ref</h1>
我是sum:{{sum}}
<button @click="fn">点我</button>
</div>
</template>
<script>
/*
接受一个内部值并返回一个响应式且可变的 ref 对象。
ref 对象仅有一个 .value property,指向该内部值。
*/
// 如果将对象分配为 ref 值,则它将被 reactive 函数处理为深层的响应式对象。
import { ref } from "vue";
export default {
setup(){
let obj = {name:"张三",age:18}
let obj1 = ref(obj)
// ref一般用于处理简单数据类型,也可以处理响应式数据类型
let sum = ref(1)
function fn(){
console.log(sum)
sum.value+=1
console.log(obj1)
}
return {
sum,
fn
}
}
}
</script>
vue3创建响应式对象:toRef
<template>
<div>
<h2>toRef</h2>
<button @click="fn">点我toRef</button>
</div>
</template>
<script>
/*
可以用来为源响应式对象上的某个 property 新创建一个 ref。
然后,ref 可以被传递,它会保持对其源 property 的响应式连接。
*/
import { toRef,reactive } from "vue";
export default {
setup(){
let state =reactive({foo: 1,bar: 2})
const fooRef = toRef(state,'foo')
function fn(){
console.log(++fooRef.value)//2
console.log(state.foo)//2
}
return {
fn
}
}
}
</script>
vue3创建响应式对象:toRefs
<template>
<div>
{{obj.name}}{{obj.age}}
{{newObj.name}}{{newObj.age}}
<button @click="fn">toRefs</button>
</div>
</template>
<script>
/*
将响应式对象转换为普通对象,其中结果对象的每
个 property 都是指向原始对象相应 property 的 ref。
*/
import { reactive,toRefs } from "vue";
export default {
setup(){
let obj = reactive({name:'张三',age:18})
let newObj = toRefs(obj)
function fn(){
newObj.age.value+=2
}
return {
obj,
fn,
newObj
}
}
}
</script>
vue3中Computed
<template>
<div>
<h2>computed</h2>
{{sum}}
{{sum1}}
{{sum2}}
<button @click="fn">点我computed</button>
</div>
</template>
<script>
import { ref,computed, reactive } from 'vue'
export default {
setup(){
let arr = ref([1,2,3])
const sum = computed(()=>{
return arr.value.reduce((prev,cur)=>{
return prev+cur
},0)
})
let arr1 = reactive([1,2,3,4,5,6,7,8])
const sum1 = computed(()=>{
return arr1.reduce((prev,cur)=>{
return prev+cur
},0)
})
let arr2 = reactive([1,23,4,5,6])
const sum2 = computed({
get(){
return arr2.reduce((value,index)=>{
return value+index
},0)
},
set(val){
console.log('我是set',val)
}
})
function fn(){
// 当改变计算属性的值时调用set
console.log(sum2.value+=1)
}
return {
sum,
sum1,
sum2,
fn
}
}
}
</script>
vue3中watch
watch
需要侦听特定的数据源,并在单独的回调函数中执行副作用。默认情况下,它也是惰性的——即回调仅在侦听源发生变化时被调用。
<template>
<div>
<h2>watch</h2>
{{obj.num}}
{{obj2.num2}}
<button @click="fn">点我</button>
</div>
</template>
<script>
import { reactive, watch } from "vue";
export default {
setup(){
let obj = reactive({num:1})
let obj2 = reactive({num2:1})
function fn(){
obj.num+=1
obj2.num2+=2
}
// 语法
// watch(监听对象,函数,对象[{deep,immediate}])
watch(obj,()=>{
console.log(111)
},{})
return { obj,fn}
// 第二种写法
watch(()=>{return obj.num},()=>{
console.log(111)
},{})
return { obj,fn}
// 第三种写法
// 同时监听多个监听对象
watch([obj,obj2],()=>{
console.log(111)
},{})
return { obj,obj2,fn}
// 第四种写法:监听对象中的属性
watch(()=>{ return obj},()=>{
console.log(111)
},{deep:true})
return { obj,obj2,fn}
}
}
</script>
vue3中watchEffect
<template>
<div>
<h3>watchEffect</h3>
<button @click="fn">点我</button>
{{sum}}
</div>
</template>
<script>
import { ref, watchEffect } from "vue";
export default {
setup(){
let sum = ref(1)
let timeId = null
function fn(){
sum.value+=1
}
/*
立即执行传入的一个函数,同时响应式追踪其依赖,
并在其依赖变更时重新运行该函数。
*/
watchEffect(()=>{
let a = sum.value
clearTimeout(timeId)
timeId=setTimeout(()=>{
console.log('你好')
},3000)
})
return {
sum,
fn
}
}
}
</script>
vue3中v-model
在父组件中设置
//在父组件中设置变量
<template>
<div>
<model v-model="summodel"/>
</div>
</template>
<script>
import model from "./components/15-v-model.vue";
import { ref } from "vue";
export default {
name: 'App',
setup(){
const summodel =ref('我是v-model绑定的值')
return {
summodel
}
},
components: {
model
}
}
</script>
在子组件中设置
<template>
<div>
<h2>v-model</h2>{{modelValue}}
<button @click="btn">点我</button>
</div>
</template>
<script>
// v3:v-model 接收数据默认是modelValue
export default {
name:"model",
props:{
modelValue:{
type:String
}
},
setup(props,{emit}){
const a = [...props.modelValue].join('')
function btn(){
emit('update:modelValue','我在子组件修改了v-model传过来的值')
}
return {
btn,
a
}
}
}
</script>
ref获取dom元素必须要在钩子函数onMounted
<template>
<div>
<h3 ref ="tarage"> 我是需要获取到的ref</h3>
</div>
</template>
<script>
import { onMounted, ref } from 'vue'
export default {
setup () {
const tarage = ref(null)
// dom元素必须在onMounted中获取得到
onMounted(() => {
console.log(tarage.value)
})
return { tarage }
}
}
</script>
第二部分:provide和inject是响应式的吗?
// 祖先组件
provide(){
return {
// keyName: { name: this.name }, // value 是对象才能实现响应式,也就是引用类型
keyName: this.changeValue // 通过函数的方式也可以[注意,这里是把函数作为value,而不是this.changeValue()]
// keyName: 'test' value 如果是基本类型,就无法实现响应式
}
},
data(){
return {
name:'张三'
}
},
methods: {
changeValue(){
this.name = '改变后的名字-李四'
}
}
// 后代组件
inject:['keyName']
create(){
console.log(this.keyName) // 改变后的名字-李四
}