Vue3:
vue3中watch函数 - baifangzi - 博客园
vue3:computed
Vue 3 第七章:computed计算属性_vue3的computed-CSDN博客
//Vue3完整写法
//computed 必须写返回值
import { ref, reactive, computed} from 'vue';
//只读写法 (简写)
//使用computed函数形式用法的例子:
const doublenum = computed(()=>{
return data.num*2
})
return {
...toRefs(data),
doublenum,
}
下面是一个使用computed对象形式用法的例子:
const state = reactive({
count: 0
})
const doubleCount = computed({
get() {
return state.count * 2
},
set(value) {
state.count = value / 2
}
})
console.log(doubleCount.value) // 输出:0
doubleCount.value = 6
console.log(state.count) // 输出:3
console.log(doubleCount.value) // 输出:6
过滤和排序
当我们需要根据其他响应式数据进行数据过滤和排序时,可以使用computed属性来计算得出过滤和排序后的结果。例如:
import { computed, reactive } from 'vue'
const state = reactive({
todos: [
{ id: 1, text: '学习Vue3', done: false },
{ id: 2, text: '学习React', done: false },
{ id: 3, text: '学习Angular', done: true }
],
filter: 'all'
})
const filteredTodos = computed(() => {
if (state.filter === 'all') {
return state.todos
} else if (state.filter === 'active') {
return state.todos.filter(todo => !todo.done)
} else if (state.filter === 'completed') {
return state.todos.filter(todo => todo.done)
}
})
console.log(filteredTodos.value) // 输出:[{ id: 1, text: '学习Vue3', done: false }, { id: 2, text: '学习React', done: false }, { id: 3, text: '学习Angular', done: true }]
state.filter = 'active'
console.log(filteredTodos.value) // 输出:[{ id: 1, text: '学习Vue3', done: false }, { id: 2, text: '学习React', done: false }]
数组计算
当我们需要对一个数组进行计算时,可以使用computed属性来计算得出数组的值。例如:
import { computed, reactive } from 'vue'
const state = reactive({
todos: [
{ id: 1, text: '学习Vue3', done: false },
{ id: 2, text: '学习React', done: false },
{ id: 3, text: '学习Angular', done: true }
]
})
const totalTodos = computed(() => {
return state.todos.length
})
const completedTodos = computed(() => {
return state.todos.filter(todo => todo.done).length
})
console.log(totalTodos.value) // 输出:3
console.log(completedTodos.value) // 输出:1
vue3:watch
watch(Vue3中可以写多个watch)
//一般只操作 newVal 要有数据改变watch才有变化
watch(WatcherSource, Callback, [WatchOptions])
参数:
WatcherSource:想要监听的响应式数据。
Callback:执行的回调函数,入参(newValue,oldValue)。
[WatchOptions]:deep、immediate、flush可选。
import { ref, reactive, watch } from 'vue';
一,监听单个数据ref
const count = ref(1);
watch(count, (newValue, oldValue) => {
console.log('值发生了变更', newValue, oldValue);//可以获取到新值和旧值。
});
二,监听引用类型数据ref:深度监听
const count = ref({
a: 1,
b: 2
});
const handleClick = function () {
count.value.a = 5;
};
watch(
count,
(newValue, oldValue) => {
console.log('值发生了变更', newValue, oldValue);
},
{ deep: true }
);
三,监听单个数据:reactive
const single = reactive({ count: 1, test: 2 });
const handleClick = function () {
single.count++;
};
watch(
() => single.count,
(newValue, oldValue) => {
console.log('值发生了变更', newValue, oldValue);
},
{ immediate: true }
);
四,监听引用类型数据:reactive
const single = reactive({ count: 1, test: { a: 1, b: 2 } });
const handleClick = function () {
single.test.a++;
};
watch(
single,
(newValue, oldValue) => {
console.log('值发生了变更', newValue, oldValue);
},
{ immediate: true }
);
//reactive的数据,用不用deep:true是没有影响的,single中的一个属性发生了变化,都能被监听到,继而执行回调函数。
六,监听多个数据源
const count = ref(1);
const double = ref(2);
const handleClick = function () {
count.value++;
double.value++;
};
watch(
[count, double],
(newValue, oldValue) => {
console.log('值发生了变更', newValue, oldValue);
},
{ deep: true, immediate: true }
);
//有一个值发生了变更,则会触发watch,如果两个值同时发生变更,同样只是触发一次watch的回调函数。
const state = reactive({ count: 0 })
let sum = ref(0)
let msg = ref('你好')
let person = reactive({
name:'zs',
age:18
})
//ref定义的基本数据类型 监视的时候不用.value 定义对象时要.value
watch(sum, (newValue, oldValue) => {
console.log('值发生了变更', newValue, oldValue);//可以获取到新值和旧值。
});
//引用类型ref直接深度监听此时,就需要使用深度监听:deep:true
watch(person.value,(newVal,oldVal)=>{
console.log(newVal)
})
//或者深度监视 不用.value
watch(person,(newVal,oldVal)=>{
console.log(newVal)
},{deep:true})
watch(
()=>state.count, //通过一个函数返回要监听的属性
(count, prevCount) => {
/* ... */
}
)
//1.监视ref定义的一个响应式数据
// watch(()=>sum,(newVal,oldVal)=>{
// console.log(newVal,oldVal)
// },{immediate:true,deep:true})
//2.监视多个ref定义响应式函数
watch([sum,msg],(newVal,oldVal)=>{
console.log(newVal,oldVal) //为数组
})
//监视reactive定义的响应式数据
let book = reactive({
name: "js编程",
price: 50,
text:{
t1:'1';
t2:'2'
}
});
//监视reactive定义的响应式数据的全部属性
//1.注意:此处无法正确的获取oldVal
//2.强制开启了深度监听(deep无效)
//一次监视reactive定义的响应式数据的全部属性
watch(book,(newVal,oldVal)=>{
console.log(newVal,oldVal)
})
const changeBookName = () => {
book.name = "c#";
};
//监视reactive定义的响应式数据的某一个属性 一般项目推荐!!!
watch(()=>book.name,(newVal,oldVal)=>{
console.log('书名改变了')
})
//监视reactive定义的响应式数据的多个属性 一般项目推荐!!!
watch([() => book.name, () => book.price], (newVal,oldVal) => {
console.log(newVal,oldVal);
});
//特殊 当监听的reactive定义的数据里面的属性值依然是一个对象的话 deep:true生效 !!!
watch(()=>book.text,(newVal,oldVal)=>{
console.log('书名改变了')
},{deep:true})
//不知
watch([() => book.name, count], ([name, count], [preName, preCount]) => {
console.log("count或book.name改变了");
});
watchEffect:不用指明监视那个属性,监视的回调中用到那个属性,就监视那个属性
watchEffect(()=>{
//函数里面使用了那个变量就自动监视那个变量
const x1 = sum.value
console.log('watchEffect!,你用谁我就监视谁')
})
Vue2 :
Vue使用watch监听一个对象中的属性 - 暗恋桃埖源 - 博客园
vue中watch不触发、不生效的解决办法及原理_王一诺Eno-CSDN博客
<div class="watch-demo-item">
<input type="text" v-model="val1" />
<div>{{ value1 }}</div>
</div>
data() {
return {
val1: "",
value1: "2",
};
},
//一般只操作 newVal 要有数据改变watch才有变化
watch:{
//简写↓
val1(newVal, oldVal) {
this.value1 = val1;
console.log("newVal:", newVal, "oldVal", oldVal);//1
},
//原始写法
val1: {
handler: function (newVal, oldVal) {
if (newVal == 3) {
this.value1 = 5;
}
console.log("newVal:", newVal, "oldVal", oldVal);
},
},
//完整写法↓
// val1:{
// immediate:true,//立即监听
// deep:true,//深度监听
// handler(newVal,oldVal){
// console.log(newVal,oldVal)
// }
// }
},
'obj.name' (newVal, oldVal) { // 可以监听对象的单个属性
console.lov(newVal)
}
computed:{ //简写
dobule (){
return this.list.map(item=>item*2).filter(item => item<10)
}
},
完整:
computed:{
fullName:{
get:function(){
return person.firstName +'-'+person.lastName;
},
set:function(value){
console.log(value)
const arr = value.split('');
person.firstName = arr[0];
person.lastName = arr[1]
}
}
}
<style>
.box {
margin: 100px auto 0;
width: 80%;
}
.clear:after {
content: '';
display: block;
clear: both;
}
.checkbox {
margin: 0;
padding: 0;
display: inline-block;
list-style: none;
}
.checkbox .item {
float: left;
position: relative;
padding: 12px 20px 12px 30px;
cursor: pointer;
transition: .2s all;
}
.checkbox .item:before {
position: absolute;
left: 10px;
top: 16px;
display: inline-block;
border: 1px solid #333;
width: 12px;
height: 12px;
content: '';
transition: .2s all;
}
.checkbox .item.checked, .checkbox .item:hover {
color: #409eff;
}
.checkbox .item.checked:before {
border-color: #409eff;
background: #409eff;
content: '√';
color: #fff;
font-size: 12px;
text-align: center;
line-height: 12px;
font-weight: bold;
}
</style>
</head>
<body>
<div class="box">
<div>
<div class="checkbox clear">
<div
:class="{'checked':Checked}"
class="item"
@click="isCheckedall"
>
全选
</div>
</div>
</div>
<ul class="checkbox clear">
<li
v-for="city,index of cities"
class="item"
:class="{'checked': city.checked}"
@click="choose(city)"
>
{{city.name}}
</li>
</ul>
<div>
当前选中了<strong>{{checkedlength}}</strong>个
</div>
</div>
<script src="js/vue.js"></script>
<script>
let app = new Vue({
el: '.box',
data: {
cities: [
{name: '北京', checked: false},
{name: '上海', checked: false},
{name: '广州', checked: false},
{name: '深圳', checked: false},
{name: '武汉', checked: false}
],
Checked:false, //下面的watch方法名字
// checkedlength:0
},
methods: {
choose(city) {
city.checked = !city.checked;
},
isCheckedall(){
this.Checked = !this.Checked
}
},
watch: { //关注数据的变化(一个数据变化需要影响多个数据时候使用)
Checked(){ //方法名等于上面data中的数据名
this.cities.forEach(city=>{
city.checked = this.Checked
})
}
sum(newVal,oldVal){ //里面包含两个参数
console.log(newVal,oldVal)
}
},
computed: {
checkedlength:{
get() { //多个数据影响一个
return this.cities.filter(city=> city.checked).length;
}
}
},
});
</script>
</body>
<body>
<div id="app">
<input type="text" v-model="message">
<p>{{message}}</p> <!--xu-->
<!-- <p>{{message.split('').reverse().join('')}}</p> ux
<p>{{list.map(item=>item*2).filter(item => item<10)}}</p> -->
<!--[ 2, 4, 6, 8 ]-->
<p @click="fn">click</p> <!--调用methods-->
<p>{{reverseText}}</p> <!--ux 调用computed-->
<p>{{dobule}}</p> <!--[ 2, 4, 6, 8 ]-->
<p>vm.lastName="xy"
计算属性.html:30 计算了一次
"xy" watch</p>
</div>
<script type="text/javascript">
/*
计算属性的作用:
把对处理数据的逻辑抽离在计算属性中,使得模板更加轻量易读,有缓存(只有计算属性中的数据改变时再次触发)
定义计算属性:
computed 对象 里面放计算属性处理函数
v-for 也能循环计算属性中定义的函数 v-for="(dobule, index) of dobule"
*/
let vm = new Vue({
el:'#app',
data:{
message:'xu',
list:[1,2,3,4,5],
firstName:'Tom',
lastName:'Mike',
fullName:''
},
methods:{
fn(){
alert(1)
}
},
computed:{ //挂载实例
//计算属性中依赖data的数据,data数据发生变化,计算属性会随着改变
reverseText (){ //方法后面加个空格
return this.message.split('').reverse().join('')
//return (this.datas.vod_addtime || '').split('-').join('')
},
dobule (){
return this.list.map(item=>item*2).filter(item => item<10)
}
},
watch:{ //侦听器
firstName(){
this.fullName = this.firstName+''+this.lastName
},
lastName(){
this.fullName = this.firstName+''+this.lastName
}
}
})
</script>
</body>