Vue\Vue3 计算属性computed watch

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 

vue3下watch的使用_笑道三千的博客-CSDN博客

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>

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

林中明月间。

分享共赢。

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值