-
• 使用setup语法糖
-
• computed
-
• watch监听
-
• watchEffect
-
• readyonly
-
• 自定义组件
-
• uni-app 创建自定义组件
-
• defineProps() 和 defineEmits()
-
• 使用类型声明时的默认 props 值
-
• defineExpose
更多详细内容,请微信搜索“前端爱好者
“, 戳我 查看 。
使用setup语法糖
<template>
<view class="container">
</view>
</template>
<script setup>
import { ref } from 'vue'
</script>
<style lang="less" scoped>
</style>
ref
reactive
computed
vue3地址:https://cn.vuejs.org/api/reactivity-core.html#computed
在Vue 3中,计算属性的使用方式与Vue 2相比有一些变化。在Vue 3中,你可以使用computed
函数来创建计算属性。
直接获取
以下是一个示例:
import { computed, reactive } from 'vue';
const app = {
setup() {
const state = reactive({
firstName: 'John',
lastName: 'Doe'
});
const fullName = computed(() => {
return state.firstName + ' ' + state.lastName;
});
return {
state,
fullName
};
}
}
在上面的例子中,我们使用reactive
函数将一个普通的JavaScript对象转化为响应式对象。然后,我们使用computed
函数创建了一个计算属性fullName
,它根据state
中的firstName
和lastName
计算出完整的姓名。
在模板中使用计算属性也很简单,只需在对应的位置使用{{ fullName }}
即可:
<template>
<div>
<p>{{ state.firstName }}</p>
<p>{{ state.lastName }}</p>
<p>{{ fullName }}</p>
</div>
</template>
每当state.firstName
或state.lastName
发生变化时,fullName
计算属性都会被重新计算,并更新视图中的内容。
需要注意的是,在Vue 3中,computed
函数返回的是一个ref
对象,而不是像Vue 2中直接返回一个普通值。
因此,在组件中使用计算属性时,需要使用.value
来获取计算属性的值,例如:{{ fullName.value }}
。
h更加复杂应用
在Vue 3中,计算属性仍然支持使用get
和set
来定义可读写的计算属性。
你可以使用computed
函数的get
和set
选项来实现这一点。
以下是一个示例:
import { computed, reactive } from 'vue';
const app = {
setup() {
const state = reactive({
firstName: 'John',
lastName: 'Doe'
});
const fullName = computed({
get() {
return state.firstName + ' ' + state.lastName;
},
set(value) {
const parts = value.split(' ');
state.firstName = parts[0];
state.lastName = parts[1];
}
});
return {
state,
fullName
};
}
}
在上面的例子中,我们使用computed
函数的对象形式来创建计算属性fullName
。我们使用get
函数来定义计算属性的读取操作,返回完整的姓名。我们还使用set
函数来定义计算属性的写入操作,根据新提供的值更新state
中的firstName
和lastName
。
在模板中使用可读写的计算属性时,只需像访问普通的响应式对象一样进行操作即可:
<template>
<div>
<!-- 读取计算属性 -->
<p>{{ fullName }}</p>
<!-- 写入计算属性 -->
<input v-model="fullName" />
</div>
</template>
在上面的例子中,我们可以直接将fullName
绑定到输入框的v-model
指令中,从而实现对计算属性的写入操作。当输入框的值发生变化时,set
函数会被调用,并更新state
中的数据。
uni-app 使用计算属性
在uni-app中,你可以使用setup
函数来定义计算属性。
setup
函数是Vue 3中的新特性,它可以在组件中使用,并且提供了类似于Vue Composition API的功能。
以下是一个示例:
<template>
<view>
<!-- 使用计算属性 -->
<text>{{ fullName }}</text>
</view>
</template>
<script setup>
import { ref, computed } from 'vue';
const firstName = ref('John');
const lastName = ref('Doe');
const fullName = computed(() => {
return firstName.value + ' ' + lastName.value;
});
</script>
在上面的例子中,我们使用ref
函数将firstName
和lastName
声明为响应式的引用对象。然后,我们使用computed
函数创建一个计算属性fullName
,它根据firstName.value
和lastName.value
计算出完整的姓名。
需要注意的是,由于setup
函数是在Vue 3的<script setup>
语法中使用的,在uni-app中需要使用<script setup>
标签包裹setup
代码块。
在模板中使用计算属性时,只需在对应的位置使用插值表达式即可。
watch监听
在 Vue 3 中,你可以使用 watch
函数来监听数据的变化。
watch
函数接收两个参数:
-
• 要监听的数据或表达式
-
• 回调函数。当数据发生变化时,回调函数将被触发。
下面是一个示例,演示如何使用 watch
监听数据的变化:
import { ref, watch } from 'vue';
// 创建一个响应式数据
const myData = ref('');
// 使用 watch 监听数据的变化
watch(myData, (newVal, oldVal) => {
console.log('数据发生了变化!');
console.log('新值:', newVal);
console.log('旧值:', oldVal);
});
在上面的示例中,我们创建了一个名为 myData
的响应式数据,并使用 watch
监听它的变化。当 myData
的值发生变化时,回调函数将被触发,并打印出新值和旧值。
除了监听单个数据之外,你还可以使用 watch
监听多个数据的变化。只需将要监听的数据作为一个数组传递给 watch
函数即可。例如:
watch([myData, anotherData], ([newVal1, newVal2], [oldVal1, oldVal2]) => {
// 数据发生变化时的处理逻辑
});
uni-app watch 监听
在 uni-app
中,你可以使用 setup
函数和 watch
函数来监听数据的变化。
首先,在 setup
函数中创建响应式数据并返回它们。
然后,使用 watch
函数来监听数据的变化。
下面是一个示例,演示如何在 uni-app
中使用 setup
和 watch
监听数据的变化:
import { ref, watch } from 'vue';
export default {
setup() {
const myData = ref('');
watch(myData, (newVal, oldVal) => {
console.log('数据发生了变化!');
console.log('新值:', newVal);
console.log('旧值:', oldVal);
});
return {
myData,
};
},
}
在上面的示例中,我们使用 ref
函数创建了一个名为 myData
的响应式数据,并使用 watch
函数监听它的变化。当 myData
的值发生变化时,回调函数将被触发,并打印出新值和旧值。
在 setup
函数中,我们将 myData
添加到返回的对象中,以便在模板中访问该数据。
watchEffect
在Vue 3中,watchEffect是一个用于监听响应式数据变化的函数。与以前版本的Vue中的watch不同,watchEffect更简洁且易于使用。
watchEffec t接受一个函数作为参数,并立即执行
该函数。
在函数内部,你可以访问和操作任何响应式数据,当这些数据发生变化时,函数将会被重新执行。
下面是使用watchEffect的示例:
import { watchEffect, reactive } from 'vue';
const state = reactive({
count: 0,
});
watchEffect(() => {
console.log('Count changed:', state.count);
});
// 在其他地方修改count的值
state.count++; // 这将触发watchEffect的执行
在上面的例子中,我们创建了一个响应式对象state,并在watchEffect中监听了count属性的变化。每当count发生变化时,watchEffect的回调函数就会被调用,并打印出count的新值。
总结,watchEffect是Vue 3中一种简洁而强大的监听数据变化的方式,它能够自动追踪响应式数据的依赖并在数据变化时触发回调函数的执行。
深度监听
在Vue 3中,使用watchEffect
函数来监听响应式数据的变化,并在变化时执行相应的操作。默认情况下,watchEffect
只会监听响应式数据的第一层属性的变化,而不会深入到对象的嵌套属性或数组的元素中。
如果你需要深度监听响应式数据的变化,可以通过在watchEffect
内部使用deep
选项来实现。将deep
选项设置为true
,就可以让watchEffect
深度监听对象和数组的变化。
以下是一个示例:
import { reactive, watchEffect } from 'vue';
const data = reactive({
name: 'Alice',
age: 25,
nestedObj: {
prop: 'value'
},
array: [1, 2, 3]
});
watchEffect(() => {
console.log('data changed');
}, { deep: true });
// 修改响应式数据
data.name = 'Bob'; // 输出: data changed
data.nestedObj.prop = 'new value'; // 输出: data changed
data.array.push(4); // 输出: data changed
在上面的示例中,我们使用reactive
函数创建了一个响应式对象data
,并使用watchEffect
监听了它的变化。由于指定了deep: true
选项,所以当data
对象的任意属性发生变化时,watchEffect
都会被触发。
需要注意的是,深度监听可能会对性能产生一些影响,因为它需要递归地遍历对象或数组的所有属性。因此,在使用deep
选项时,要谨慎使用,以免导致性能问题。
uni-app watchEffect
readyonly
地址:https://cn.vuejs.org/api/reactivity-core.html#readonly
在Vue 3中,你可以使用readonly
修饰符来创建只读的响应式数据。这意味着一旦数据被初始化后,你将无法修改它。
readonly
接受一个对象 (不论是响应式还是普通的) 或是一个 ref,返回一个原值的只读代理。
类型
function readonly<T extends object>(
target: T
): DeepReadonly<UnwrapNestedRefs<T>>
详细信息
只读代理是深层的:对任何嵌套属性的访问都将是只读的。它的 ref 解包行为与 reactive() 相同,但解包得到的值是只读的。
要避免深层级的转换行为,请使用 shallowReadonly() 作替代。
示例
const original = reactive({ count: 0 })
const copy = readonly(original)
watchEffect(() => {
// 用来做响应性追踪
console.log(copy.count)
})
// 更改源属性会触发其依赖的侦听器
original.count++
// 更改该只读副本将会失败,并会得到一个警告
copy.count++ // warning!
uni-app readyonly
自定义组件
uni-app 创建自定义组件
鼠标邮件点击需要创建组件的文件夹,即可出现如下界面"
填写模板信息
defineProps() 和 defineEmits()
为了在声明 props 和 emits 选项时获得完整的类型推导支持,我们可以使用 defineProps 和 defineEmits API,它们将自动地在 <script setup>
中可用:
<script setup>
const props = defineProps({
foo: String
})
const emit = defineEmits(['change', 'delete'])
// setup 代码
</script>
-
• defineProps 和 defineEmits 都是只能在
<script setup>
中使用的编译器宏。他们不需要导入,且会随着<script setup>
的处理过程一同被编译掉。 -
• defineProps 接收与 props 选项相同的值,defineEmits 接收与 emits 选项相同的值。
-
• defineProps 和 defineEmits 在选项传入后,会提供恰当的类型推导。
-
• 传入到 defineProps 和 defineEmits 的选项会从 setup 中提升到模块的作用域。因此,传入的选项不能引用在 setup 作用域中声明的局部变量。这样做会引起编译错误。但是,它可以引用导入的绑定,因为它们也在模块作用域内。
使用类型声明时的默认 props 值
定义/获取props 值
<template>
<view class="container">
zInput -- {{maxLength}} -- {{value}}
<input type="text" :value="content" style="background: #ebebeb;"/>
</view>
</template>
<script setup>
import { ref } from 'vue'
const {maxLength,value} = defineProps({
maxLength: {
type: [Number],
require:false
},
// 默认值
value: {
type: [Number,String],
require:false
},
})
const content = ref(value)
</script>
<style lang="less" scoped>
</style>
赋值props 值
<template>
<view class="container">
<u-input :maxLength="10" value="dssddsdsdsd"></u-input>
</view>
</template>
<script setup>
import { ref } from 'vue'
import uInput from '../../components/u-input/u-input'
</script>
<style lang="less" scoped>
</style>
显示效果
defineExpose
vue地址:https://cn.vuejs.org/api/sfc-script-setup.html#defineprops-defineemits
使用 <script setup>
的组件是默认关闭的——即通过模板引用或者 $parent 链获取到的组件的公开实例,不会暴露任何在 <script setup>
中声明的绑定。
可以通过 defineExpose 编译器宏来显式指定在 <script setup>
组件中要暴露出去的属性:
<script setup>
import { ref } from 'vue'
const a = 1
const b = ref(2)
defineExpose({
a,
b
})
</script>
当父组件通过模板引用的方式获取到当前组件的实例,获取到的实例会像这样 { a: number, b: number } (ref 会和在普通实例中一样被自动解包)
使用示例
在 Vue 3 中,你可以使用 <script setup>
语法来编写组件,并使用 defineExpose
来暴露组件的内部方法和状态。以下是一个示例:
父组件
<template>
<h2>defineExpose 使用 父组件</h2>
<child ref="getChildData"></child>
</template>
<script setup>
import Child from "@/components/exposeChildren.vue"
import { ref,onMounted,toRaw} from 'vue'
// 文档说setup写在script上组件是关闭的
// 也就是说父组件使用getChildData.xxx访问不到子组件的数据
// 此时我们需要用defineExpose把需要传递的数据暴露出去,这样外部才能访问到
// 同理也可以接收外部传来的值
const getChildData = ref(null)
const obj = {
name: 'alan',
desc: '大笨蛋',
age: 18
}
const cc= getChildData.value?.['num']
console.log(cc) //undefined,此时还未找到子组件暴露的数据
onMounted(()=>{
//获取子组件的data数据,什么时候获取根据自己业务来
const bb:any= getChildData.value.['updata']
console.log(bb()) // 123,这时候得到的是子组件的初始值,因为还未给子组件传递数据
const a:any= getChildData.value.['getData']
a(obj) ////给子组件传递数据
const b:any= getChildData.value.['updata']
const c= getChildData.value.['num']
console.log(toRaw(b())) // {name: 'alan', desc: '大笨蛋', age: 18} ,这里得到的是个proxy,所以需要toRaw()方法转成对象
console.log(c) // 666
})
</script>
子组件
// components/exposeChildren.vue
<template>
<h2>defineExpose 使用 子组件</h2>
<div>{{ data }}</div>
</template>
<script setup>
import { ref, defineExpose } from 'vue'
const data = ref(123)
const num = ref(666)
defineExpose({
updata(){
return data.value //暴露出去父组件可以拿到data的数据.此时值为123
},
getData(res:any){
data.value = res //父组件传递来的值赋值给data
// 此时的data变成了 Proxy
// {
// name: 'alan',
// desc: '大笨蛋',
// age: 18
// }
},
num
})
</script>
参考文档
-
• https://cn.vuejs.org/api/reactivity-core.html#computed
-
• https://cn.vuejs.org/api/reactivity-core.html#readonly
-
• https://cn.vuejs.org/api/sfc-script-setup.html#defineprops-defineemits
发表评论