Vue2转Vue3快速上手第一篇(共两篇)

发布于:2023-01-22 ⋅ 阅读:(335) ⋅ 点赞:(0)

Vue3

v2-v3的学习成本不高,只要有v2基础,基本可以上手vue3

一、setup语法

setup中不能访问v2的配置比如data,methods等

二、ref响应数据

使用ref可以创建一个对象,可以是基本类型,也可以是对象
例如:

<template>
  <div class="home">
    <!-- 渲染 -->
	{{a}}
  </div>
</template>

<script>
import { ref} from 'vue'
export default {
  name: 'Home',
  setup(){
    // 创建
	const a = ref('')
    // 使用方法  xxx.value
	a.value = 'NanChen'
	return{
		a,
	}
  },
}
</script>

请添加图片描述

三、reactive创建响应式数据

这是一个对象类型的响应数据,例:

<template>
  <div class="home">
    {{a.sex}}
    {{a.name}}
  </div>
</template>

<script>
import { reactive } from "vue";
export default {
  name: "Home",
  setup() {
    const a = reactive({
      sex: "",
      name: "",
    });
    a.sex = "男";
    a.name = "NanChen";
    return {
      a,
    };
  },
};
</script>

请添加图片描述

四、computed 计算属性

例:

<template>
  <div>
    <div>
      姓:{{per.firstName}}
    </div>
    <div>
      名:{{per.lastName}}
    </div>
    <div>
      加起来:{{per.fullName}}
    </div>
  </div>
</template>
 
<script>
import { reactive, computed } from "vue";

export default {
  setup() {
    let per = reactive({
      firstName: "Nan",
      lastName: "Chen",
    });
    per.fullName = computed(() => {
      return per.firstName + "++" + per.lastName;
    });
    return {
      per,
    };
  },
};
</script>
 
<style>
</style>

请添加图片描述

五、watch 监听器

例(一):监听单个ref的响应式数据

<template>
  <div>
	监听<button @click="num++">+1查看监听器变化</button>
	<div>{{num}}</div>
  </div>
</template>
 
<script>
import { ref, watch } from "vue";

export default {
  setup() {
	let num = ref(0);
	watch(num,(newValue,oldValue)=>{
		console.log('newValue: '+newValue,' oldValue: '+oldValue);
	})
	return{
		num
	}
  },
};
</script>

请添加图片描述

例(二):监听ref定义的多个响应式数据

<template>
  <div>
    <div>
      <button @click="num++">+1查看监听器变化</button>
      <div>num:{{num}}</div>
    </div>

    <div>
      <button @click="num2+='改动了'">改变</button>
      <div>num2:{{num2}}</div>
    </div>
  </div>
</template>
 
<script>
import { ref, watch } from "vue";

export default {
  setup() {
    let num = ref(0);
    let num2 = ref("监听多个ref响应式的使用");
    watch(
      [num, num2],
      (newValue, oldValue) => {
        console.log("num and num2 ", newValue, oldValue);
      },
      /* immediate:第一次就监听 */
      { immediate: true }
    );
    return {
      num,
      num2,
    };
  },
};
</script>

请添加图片描述

例(三):监听reactive所定义的一个响应式数据

<template>
  <div>
    <div>
      <button @click="a.name+='XX'">更改姓名</button>
      <div>{{a.name}}</div>
    </div>
    <div>
      <button @click="a.age++">更改年龄</button>
      <div>{{a.age}}</div>
    </div>
  </div>
</template>
 
<script>
import { reactive, watch } from "vue";

export default {
  setup() {
    let a = reactive({
      name: "NanChen",
      age: 20,
    });
     watch(a,(newValue, oldValue) => {
        console.log(newValue, oldValue);
      },{immediate:true,deep:false}//deep无效
    );
    return {
      a,
    };
  },
};
</script>

请添加图片描述

例(四):监听reactive定义的一个响应式数据中的某一个属性

<template>
  <div>
    <div>
      <button @click="a.name+='XX'">更改姓名</button>
      <div>{{a.name}}</div>
    </div>
    <div>
      <button @click="a.age++">更改年龄</button>
      <div>{{a.age}}</div>
    </div>
  </div>
</template>
 
<script>
import { reactive, watch } from "vue";

export default {
  setup() {
    let a = reactive({
      name: "NanChen",
      age: 20,
    });
    watch(() => a.name,(newValue, oldValue) => {
        console.log(newValue, oldValue);
      }
    );
    return {
      a,
    };
  },
};
</script>

请添加图片描述

例(五):监听reactive定义的一个响应式数据中的某些属性

<template>
  <div>
    <div>
      <button @click="a.name+='XX'">更改姓名</button>
      <div>{{a.name}}</div>
    </div>
    <div>
      <button @click="a.age++">更改年龄</button>
      <div>{{a.age}}</div>
    </div>
  </div>
</template>
 
<script>
import { reactive, watch } from "vue";

export default {
  setup() {
    let a = reactive({
      name: "NanChen",
      age: 20,
    });
    watch([() => a.name, () => a.age],(newValue, oldValue) => {
        console.log(newValue, oldValue);
      }
    );
    return {
      a,
    };
  },
};
</script>

请添加图片描述

例(六):监听reactive定义的嵌套对象

<template>
  <div>
    <div>
      <button @click="a.name+='XX'">更改姓名</button>
      <div>{{a.name}}</div>
    </div>
    <div>
      <button @click="a.age++">更改年龄</button>
      <div>{{a.age}}</div>
    </div>
    <div>
      <button @click="a.obj.objList.num++">更改数字</button>
      <div>{{a.obj.objList.num}}</div>
    </div>
  </div>
</template>
 
<str>
import { reactive, watch } from "vue";

export default {
  setup() {
    let a = reactive({
      name: "NanChen",
      age: 20,
      obj: {
        objList: {
          num: 100,
        },
      },
    });
    watch(() => a.obj,(newValue, oldValue) => {
        console.log(newValue, oldValue);
      },{ deep: true }); // 这里是坚挺的reactive对象中的某个属性,因此deep生效
    // deep:其值是true或false;确认是否深入监听。(一般监听时是不能监听到对象属性值的变化的,数组的值变化可以听到。
    return {
      a,
    };
  },
};
</script>

请添加图片描述

六、watchEffect 监听器

特性,也可以说成和watch的区别

  • 不需要手动传入依赖
  • 每次初始化时会执行一次回调函数来自动获取依赖
  • 无法获取到原值,只能得到变化后的值
<template>
  <div>
    <div>
      <button @click="a.name+=' hello'">更改姓名</button>
      <div>{{a.name}}</div>
    </div>
    <div>
      <button @click="a.age++">更改年龄</button>
      <div>{{a.age}}</div>
    </div>
  </div>
</template>
 
<script>
import { reactive, watchEffect } from "vue";

export default {
  setup() {
    let a = reactive({
      name: "NanChen",
      age: 20,
    });
    watchEffect(() => {
      console.log(a.name);
      console.log(a.age);
    });
    setTimeout(() => {
      a.name += " hi";
      a.age++;
    }, 1000);
    return {
      a,
    };
  },
};
</script>

请添加图片描述


七、Vue3生命周期

所有的声明周期要放在setup中
Vue3的生命周期如下:
1、beforeCreate -> 使用 setup()

2、created -> 使用 setup()

3、beforeMount -> onBeforeMount

4、mounted -> onMounted

5、beforeUpdate -> onBeforeUpdate

6、updated -> onUpdated

7、beforeDestroy -> onBeforeUnmount

8、destroyed -> onUnmounted

9、errorCaptured -> onErrorCaptured

语法

setup() {
    onMounted(() => {
      console.log('mounted')
    })
}

八、toRef

说白话文就是不用写前面的对象名称直接渲染里面的属性即可

<template>
  <div>
    <div>{{name}}</div>
    <div>{{age}}</div>
    <div>{{num}}</div>
  </div>
</template>
 
<script>
import { reactive, toRef } from "vue";

export default {
  setup() {
    let a = reactive({
      name: "NanChen",
      age: 20,
      list: {
        num: 0,
        num1: 1,
        num2: 2,
        num3: 3,
        num4: 4,
      },
    });
    return {
      name: toRef(a, "name"),
      age: toRef(a, "age"),
      num: toRef(a.list, "num"),
    };
  },
};
</script>

请添加图片描述

九、toRefs 响应式转换

一键给对象中的多个属性全部响应转换

<template>
  <div>
    <div>{{name}}</div>
    <div>{{age}}</div>
    <div>{{num}}</div>
    <div>{{num1}}</div>
    <div>{{num2}}</div>
    <div>{{num3}}</div>
    <div>{{num4}}</div>
  </div>
</template>
 
<script>
import { reactive, toRefs } from "vue";

export default {
  setup() {
    let a = reactive({
      name: "NanChen",
      age: 20,
      list: {
        num: 0,
        num1: 1,
        num2: 2,
        num3: 3,
        num4: 4,
      },
    });
    return {
      ...toRefs(a),
      ...toRefs(a.list),
    };
  },
};
</script>

请添加图片描述


十、shallowReactive (浅响应式)

只处理对象最外面一层的响应式数据(浅响应式)

<template>
  <div>
    <h1>姓:{{name}}</h1>
    <h2>岁数:{{age}}</h2>
    <h3>对象{{obj.objList.name}}</h3>
    <button @click="name += '+'">修改姓名</button>
    <button @click="age++">修改年龄</button>
    <button @click="obj.objList.name += ''">修改对象</button>
  </div>
</template>
 
<script>
import { reactive, toRefs, shallowReactive } from "vue";
export default {
  name: "App",
  setup() {
    // 定义了一段数据
    let a = shallowReactive({
      // 只将第一层数据做了响应式处理
      name: "NanChen",
      age: 20,
      obj: {
        objList: {
          name: "Jia", // 深层次的数据将会是一个普通的对象
        },
      },
    });
    // 将数据返回出去
    return {
      ...toRefs(a),
    };
  },
};
</script>

请添加图片描述

十一、shallowRef 不进行对象响应式

只处理基础数据类型的响应式,不进行对象类型的响应式。

<template>
  <div>
    <h1>姓:{{a}}</h1>
    <button @click="a += '+'">修改姓名</button>
    <h2>{{b.num}}</h2>
    <button @click="b++">修改num</button>
  </div>
</template>
 
<script>
import { shallowRef } from "vue";
export default {
  name: "App",
  setup() {
    // 定义了一段数据
    let a = shallowRef("NanChen");
    let b = shallowRef({
      num: 1,
    });
    console.log(b.value.num);
    // 将数据返回出去
    return {
      a,
      b,
    };
  },
};
</script>

请添加图片描述

这里可以看到,修改数据后将不会在触发页面的更新 因为监测不到了


十二、readonly(深只读)

const a = shallowRef({
  name: 'NanChen', // 只读
  obj: {
    objList: 2 // 也是只读
  }
})

十三、shallowReadonly(浅只读)

const a = shallowReadonly({
  name: 'NanChen', // 只读
  obj: {
    objList: 2 // 不是只读
  }
})

十四、toRaw 将响应式对象转换成普通对象

例:

<template>
  <h2>姓名:{{a.name}}</h2>
  <h2>年龄:{{a.age}}</h2>
  <button @click="showRawA">点我显示原始a</button>
</template>

<script>
import { reactive, toRaw } from "vue";
export default {
  name: "Demo",
  setup() {
    let a = reactive({
      name: "NanChen",
      age: 20,
    });
    function showRawA() {
      console.log("a=", a);
      let p = toRaw(a);
      console.log("raw a = ", p);
    }
    return {
      a,
      showRawA,
    };
  },
};
</script>

请添加图片描述

这里可以看到使用toRaw后,响应式对象变成了一个普通的对象

十五、markRaw 永久不响应

这里看一下使用markRaw和不使用markRaw的区别

不使用markRaw

看这个例子:

<template>
  <h2>姓:{{a.name}}</h2>
  <div v-if="a.other" style="border: 1px solid #000;width: 200px;padding: 10px;margin-bottom: 10px;">
    <h3>开发岗位:{{a.other.kaifa}}</h3>
    <h3>待遇:{{a.other.money}}K</h3>
    <button @click="changeOne">更换工程师</button>&nbsp;
    <button @click="changeTwo">加薪资</button>
  </div>
  <button @click="addOther">添加信息</button>
</template>

<script>
import { reactive } from "vue";
export default {
  name: "Demo",
  setup() {
    let a = reactive({
      name: "NanChen",
      age: 20,
    });
    function addOther() {
      a.other = {
        kaifa: "web开发",
        money: 1,
      };
    }
    function changeOne() {
      a.other.kaifa = "java开发";
    }
    function changeTwo() {
      a.other.money++;
    }
    return {
      a,
      addOther,
      changeOne,
      changeTwo,
    };
  },
};
</script>

效果:
请添加图片描述


可以看到这里的数据是可以进行响应

添加markRaw

<template>
  <h2>姓名:{{a.name}}</h2>
  <div v-if="a.other" style="border: 1px solid #000;width: 200px;padding: 10px;margin-bottom: 10px;">
    <h3>开发岗位:{{a.other.kaifa}}</h3>
    <h3>待遇:{{a.other.money}}K</h3>
    <button @click="changeOne">更换工程师</button>&nbsp;
    <button @click="changeTwo">加薪资</button>
  </div>
  <button @click="addOther">添加信息</button>
</template>

<script>
import { reactive, markRaw } from "vue";
export default {
  name: "Demo",
  setup() {
    let a = reactive({
      name: "NanChen",
      age: 20,
    });
    function addOther() {
      a.other = markRaw({
        kaifa: "web开发",
        money: 1,
      });
    }
    function changeOne() {
      a.other.kaifa = "java开发";
    }
    function changeTwo() {
      a.other.money++;
    }
    return {
      a,
      addOther,
      changeOne,
      changeTwo,
    };
  },
};
</script>

效果:
请添加图片描述

因为markRaw将{kaifa: “web开发”,money: 1,}变成了一个非响应式对象。因此,当修改 a.other.kaifa 或 a.other.money时,界面不会更新

十六、provide / inject

在组合式 API 中使用 provide/inject,两个只能在 setup 期间调用
provide 函数是有两个接受参数,是用来提供和发送数据

provide(name,value)

祖先组件:

import { provide,reactive } from "vue"
export default {
  setup(){
    let obj = reactive({
        name:'NanChen',
        age:20
    }
    provide('obj',obj)
  }
}

inject则是用来接受数据
后代组件:

import { inject } from "vue"
export default {
  setup(){
    const obj = inject('car')
    return{obj}
  }
}

十七、isRef

判断值是否为ref对象

let name = ref('NanChen')
console.log(isRef(name)); // true

十八、isReactive

判断值是否为isReactive对象

let num = isReactive({})
console.log(isRef(val)); // true

十九、inReadonly

检查对象是否是由readonly创建的只读代理

const state = reactive({
  name: 'NanChen'
})
console.log(isReactive(state)) // true

二十、isProxy

检查对象是否是由reactive或者readonly创建的proxy

const state = reactive({
  name: 'NanChen'
})
console.log(isProxy(state)) // true

本文含有隐藏内容,请 开通VIP 后查看