Vue3基础知识总结
标签: Vue3基础知识总结 Vue.js博客 51CTO博客
2023-07-19 18:24:33 99浏览
Vue3基础知识总结,一、To系列1、toRef如果原始对象是非响应式的就不会更新视图,但是数据是会变的<scriptsetuplang="ts">import{reactive,toRef}from'vue'//普通对象constobj={name:'java',age:18}//将name属性变为响应式constname=toRef(obj,
一、To系列
1、toRef
如果原始对象是非响应式的就不会更新视图,但是数据是会变的
<script setup lang="ts">
import { reactive, toRef } from 'vue'
// 普通对象
const obj = {
name: 'java',
age: 18
}
// 将name属性变为响应式
const name = toRef(obj, 'name')
const change = () => {
obj.name = 'javascript'
}
</script>
<template>
<p>{{ obj }}</p>
<p>{{ name }}</p>
<button @click="change">change</button>
</template>
点击按钮前
点击按钮后
如果原始对象是响应式的,会更新视图并且改变数据
<script setup lang="ts">
import { reactive, toRef } from 'vue'
// 原始对象是响应式的
const obj = reactive({
name: 'java',
age: 18
})
const name = toRef(obj, 'name')
const change = () => {
obj.name = 'javascript'
}
</script>
<template>
<p>{{ obj }}</p>
<p>{{ name }}</p>
<button @click="change">change</button>
</template>
点击按钮后
2、toRefs
批量创建ref对象,主要是方便我们解构使用
<script setup lang="ts">
import { reactive, toRefs } from 'vue'
// 原始对象是响应式的
const obj = reactive({
name: 'java',
age: 18
})
const { name, age } = toRefs(obj)
const change = () => {
obj.name = 'javascript'
obj.age = 20
}
</script>
<template>
<p>{{ obj }}</p>
<p>{{ name }}--{{ age }}</p>
<button @click="change">change</button>
</template>
3、toRaw
将响应式对象转化为普通对象,即解除响应式
<script setup lang="ts">
import { reactive, toRaw } from 'vue'
// 原始对象是响应式的
const obj = reactive({
name: 'java',
age: 18
})
const obj1 = toRaw(obj)
const change = () => {
console.log(obj, obj1)
}
</script>
可以看到,obj还是响应式对象,但是obj1变为了普通对象
二、computed计算属性
对象形式写法,可以对值进行修改和获取
<script setup lang="ts">
import { computed, reactive } from 'vue'
const person = reactive({
firstName: 'John',
lastName: 'Doe',
})
// 对象形式写法,有get(获取值)和set(设置值)两个属性
// 这种写法可以在模板中使用v-model,但是需要注意的是,v-model绑定的是fullName的值,而不是person.firstName和person.lastName
// 可以对值进行获取和设置
const fullName = computed({
get: () => person.firstName + '-' + person.lastName,
// 传入的参数是新值
set: (newVal) => {
[ person.firstName, person.lastName ] = newVal.split('-')
}
})
</script>
<template>
<div>
<input v-model="person.firstName" /><br>
<input v-model="person.lastName" /><br>
<p>full name: {{ fullName }}</p>
</div>
</template>
函数形式写法,只能获取值,不能修改值
<script setup lang="ts">
import { computed, reactive } from 'vue'
const person = reactive({
firstName: 'John',
lastName: 'Doe',
})
const fullName = computed(() => {
return `${person.firstName} ${person.lastName}`
})
</script>
<template>
<div>
<input v-model="person.firstName" /><br>
<input v-model="person.lastName" /><br>
<p>full name: {{ fullName }}</p>
</div>
</template>
购物车案例
<script setup lang="ts">
import {computed, reactive, ref} from 'vue'
// 定义商品接口
interface Product {
name: string,
price: number,
count: number
}
// 搜索关键字
const keyword = ref('')
// 商品列表,是一个响应式对象,实现了Product接口,并且是一个数组
const data = reactive<Product[]>([
{ name: 'apple', price: 10, count: 1 },
{ name: 'banana', price: 20, count: 2 },
{ name: 'orange', price: 30, count: 3 },
])
// 按条件搜索商品
const searchData = computed(() => {
return data.filter(item => item.name.includes(keyword.value))
})
const total = computed(() => {
// 需要注意的是,这里的searchData是一个响应式对象,所以需要使用.value来获取它的值
return searchData.value.reduce((prev: number, next: Product) => prev + next.price * next.count, 0)
})
const del = (index: number) => {
data.splice(index, 1)
}
</script>
<template>
<div>
<input v-model="keyword" placeholder="请输入商品名称进行模糊查询" style="width:300px"/><br>
<table border cellpadding="0" cellspacing="0" style="margin-top:10px;" width="500">
<thead>
<tr>
<th>商品名称</th>
<th>商品单价</th>
<th>商品数量</th>
<th>商品总价</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<tr v-for="(item,index) in searchData">
<td>{{ item.name }}</td>
<td>{{ item.price }}</td>
<td>
<button @click="item.count > 0 ? item.count-- : null" >-</button>
{{ item.count }}
<button @click="item.count < 100 ? item.count++ : null" >+</button>
</td>
<td>{{ item.price * item.count }}</td>
<td><button @click="del(index)">删除</button></td>
</tr>
</tbody>
<tfoot>
<tr>
<td colspan="5" align="right">总价:{{ total }}</td>
</tr>
</tfoot>
</table>
</div>
</template>
<style scoped>
.read-the-docs {
color: blue;
}
</style>
三、watch监视属性
监视一个变量
<script setup lang="ts">
import { ref, watch } from "vue"
// 设置成响应式数据
const name1 = ref<string>('java')
watch(name1, (newVal, oldVal) => {
console.log('name1', newVal, oldVal)
})
</script>
<template>
<div>
<input v-model="name1" />
<p>{{ name1 }}</p>
</div>
</template>
监视多个变量,变量放在数组中
<script setup lang="ts">
import { ref, watch } from "vue"
const name1 = ref<string>('java')
const name2 = ref<string>('python')
// 使用数组包裹
watch([name1, name2], (newVal, oldVal) => {
console.log('新值', newVal)
console.log('旧值', oldVal)
})
</script>
<template>
<div>
<input v-model="name1" />
<p>{{ name1 }}</p>
</div>
<div>
<input v-model="name2" />
<p>{{ name2 }}</p>
</div>
</template>
<style scoped>
</style>
监听对象的例子
<script setup lang="ts">
import { reactive, ref, watch } from "vue"
// 使用ref设置响应式数据
const person1 = ref({
name: "John",
age: 30,
})
// 使用reactive设置响应式数据
const person2 = reactive({
name: "Jane",
age: 20,
})
// watch监听响应式数据的变化
watch(person1, (newVal, oldVal) => {
console.log("person1", newVal, oldVal)
})
watch(person2, (newVal, oldVal) => {
console.log("person2", newVal, oldVal)
})
</script>
<template>
<div>
<input v-model="person1.name" />
<p>{{ person1.name }}</p>
</div>
<div>
<input v-model="person2.name" />
<p>{{ person2.name }}</p>
</div>
</template>
<style scoped>
</style>
此外,还有深度监视deep,立即监视immediate
如果对象使用reactive设置成响应式数据,则不需要开启deep深度监视,就能监视到嵌套对象中的属性
<script setup lang="ts">
import { reactive, ref, watch } from "vue"
// 使用reactive设置响应式数据
const person2 = reactive({
name: "Jane",
age: 20,
// 嵌套对象
hobbies: {
sports: "basketball",
music: "piano"
}
})
// watch监听响应式数据的变化
// person2.hobbies.music是一个字符串,需要转换成函数,才能监听到
watch(() => person2.hobbies.music, (newVal, oldVal) => {
console.log("person2.hobbies.music", newVal, oldVal)
},{
immediate: true // 立即执行
})
</script>
<template>
<div>
<input v-model="person2.hobbies.music" />
<p>{{ person2.hobbies.music }}</p>
</div>
</template>
<style scoped>
</style>
好博客就要一起分享哦!分享海报
此处可发布评论
评论(0)展开评论
暂无评论,快来写一下吧
展开评论