computed计算属性跟watch监听属性详解

一、computed计算属性(vue2.0)

  1. 例1:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    const fullName1 = computed(() => {
    return user.firstName + '-' + user.lastName
    })

    // 或者在data里直接使用
    cachedList: computed(() => store.state.cachedList)


    const fullName2 = computed({
    get: function () {
    console.log('fullName2 get')
    return user.firstName + '-' + user.lastName
    },

    set: function (value: string) {
    console.log('fullName2 set')
    const names = value.split('-')
    user.firstName = names[0]
    user.lastName = names[1]
    }
    })
  2. 例2:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    <input type="text" v-model="oneName">
    <br>
    <input type="text" v-model="lastName">
    <p>{{fullName}}</p>
    <p>{{testName}}</p>
    <input type="text" v-model="testName">

    computed:{
    // 简写
    fullName(){
    return this.oneName + '-' + this.lastName;
    },
    // 全写
    testName:{
    get(){
    return this.oneName + '-' + this.lastName;
    },
    set(value){
    const nameArr = value.split('-');
    this.oneName = nameArr[0];
    this.lastName = nameArr[1];
    }
    }
    },
    data(){
    oneName:"张",
    lastName:"三",
    }

二、computed计算属性(vue3.0)

  1. 例:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    <template>
    <div class="hello">
    <h1>计算属性</h1>
    姓:<input type="text" v-model="obj.firstName">
    <br>
    名:<input type="text" v-model="obj.lateName">

    <h2>合计:{{obj.fullNum}}</h2>

    合计:<input type="text" v-model="obj.fullNum">
    </div>
    </template>

    <script>
    import {reactive,computed} from 'vue'
    export default {
    name: 'Home',
    setup() {
    let obj = reactive({
    firstName:'1',
    lateName:'2',
    })

    //计算属性简写方式(计算属性不可被修改)
    obj.fullNum = computed(()=>{
    return obj.firstName + '-' +obj.lateName
    });

    //计算属性完整写法(可读写)
    obj.fullNum = computed({
    get(){
    return obj.firstName + '-' + obj.lateName
    },
    set(value){
    const nameArr = value.split('-')
    obj.firstName = nameArr[0]
    obj.lateName = nameArr[1]
    }
    });

    return {
    obj,
    }
    },
    props: {
    msg: String
    }
    }
    </script>

    <!-- Add "scoped" attribute to limit CSS to this component only -->
    <style scoped>

    </style>

三、watch监听属性(vue2.0)

  1. 普通方式
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    data: {
    firstName: 'Dawei',
    lastName: 'Lou',
    fullName: ''
    },
    watch: {
       //普通的watch监听
    firstName(newName, oldName) {
    this.fullName = newName + ' ' + this.lastName;
    }
    }
    // 现在我们对于firstName监听了。在进行input框输入的时候,就会触发到watch,改变data中的fullName
  2. 使用handler&immediate以及deep进行深度监听
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    watch: {
       firstName: {
    handler(newName, oldName) {
    this.fullName = newName + ' ' + this.lastName;
    },
    // 代表watch会在初始化时立即执行回调函数
    immediate: true
    // 一般监听时是不能监听到对象属性值的变化的,数组的值变化可以监听到
    deep: true,
    }
    }

  3. 监听props里的属性值(开启immediate)
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    watch: {
    waitValue: {
    handler (newValue) {
    this.contentValue = newValue
    },
    immediate: true
    },
    contentValue(newValue) {
    this.$emit('newInput', newValue)
    }
    }

四、watch监听属性(vue3)

  1. ref数据类型
    1
    2
    3
    4
    5
    6
    7
    8
    9
    setup() {
    let msg = ref("abc");
    watch(msg, (newVal, oldVal) => {
    console.log(newVal, oldVal);
    });
    return {
    msg,
    };
    }
  2. reactive 数据类型、props属性值(通过函数来指定)
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    setup() {
    let user = reactive({
    firstName: "zhang",
    lastName: "san",
    });
    watch(() => user.firstName,(newVal,oldVal) => {
    console.log(newVal,oldVal);
    })
    return {
    user,
    };
    }
  3. 监听多个数据需要数组来指定,watch返回的也是一个数组
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    setup() {
    let user = reactive({
    firstName: "zhang",
    lastName: "san",
    });
    // 这里以reactive数据为例,ref数据不用使用函数
    watch(
    [() => user.firstName,() => user.lastName],
    (newVal, oldVal) => {
    console.log(newVal, oldVal);
    }
    );
    return {
    user
    };
    }
  4. 立即执行(immediate )跟 immediate(深度监听)
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    // data1里有一个name属性:

    // 如果deep为false,那么name变化时候,监听data1,监听不到变化

    // 如果deep为false,immediate为true,那么name变化时候,监听data1,可以监听到一次,后续变化监听不到

    // 如果deep为true,那么name变化时候,监听data1,可以监听到变化

    setup() {
    let user = reactive({
    firstName: "zhang",
    lastName: "san",
    });
    let fullName = ref(""); //在声明的时候是一个空,如果初始化不执行他还是一个空
    watch([() => user.firstName, () => user.lastName], (newVal, oldVal) => {
    fullName.value = newVal[0] +' '+ newVal[1]
    },{
    immediate:true,
    //deep:true
    });
    return {
    user,
    fullName
    };
    }
  5. watchEffect (初始化执行一次,监视所有回调中使用的数据)
    1
    2
    3
    4
    5
    6
    // 不用指定监听的普通数据类型(ref)或者是复杂数据类型(reactive),像下面这个案例就是默认监听了 user.firstName和user.lastName,个人感觉watchEffect比watch好用点吧

    watchEffect(() => {
    console.log('watchEffect')
    fullName3.value = user.firstName + '-' + user.lastName
    })