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

简介: Vue2转Vue3快速上手

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>

8c1fbe782d39479ca8ecd7b11190d711.png

三、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>

0fcb9205ed6a417bbe9c403256b8c0db.png

四、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>

714b6fa9b3164437b1b9e0eca760a08a.png

五、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>

7013e821941f4d9b9f5cc37ec595043b.gif

例(二):监听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>

894c78f988b6443380766feaf5bc177c.gif

例(三):监听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>

d60c4f8c26264c309b725561de7ac593.png

例(四):监听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>

32fd6fcdd6134c069848993b788503c8.png

例(五):监听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>

6bd51a82aa3c410a840518910e746473.png

例(六):监听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>

1cb06a0d933a45f6a9bd81dc754af6c7.png

六、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>

81323b2562e64d97a532d18746b2793b.png

七、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>

81110f52313a4f2abc343e5c79c1f345.png

九、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>

ad55f496229d4e39b2d5822c586335fd.png

十、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>

b4c1e071342640c4b55a977a2679730b.gif

十一、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>

8f64bacb87334971a189e406995945c3.gif

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

十二、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>

98bdb95a348b4c7f9b706949cb4e4d26.jpg

这里可以看到使用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>

效果:

97ee3f5e5d474b4589bc1d3bf9bb1b74.gif

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

添加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>

效果:

7a36e15c62d4474f92b2effef2d7bf2e.gif

因为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


相关文章
|
22天前
|
缓存 JavaScript UED
Vue3中v-model在处理自定义组件双向数据绑定时有哪些注意事项?
在使用`v-model`处理自定义组件双向数据绑定时,要仔细考虑各种因素,确保数据的准确传递和更新,同时提供良好的用户体验和代码可维护性。通过合理的设计和注意事项的遵循,能够更好地发挥`v-model`的优势,实现高效的双向数据绑定效果。
126 64
|
22天前
|
JavaScript 前端开发 API
Vue 3 中 v-model 与 Vue 2 中 v-model 的区别是什么?
总的来说,Vue 3 中的 `v-model` 在灵活性、与组合式 API 的结合、对自定义组件的支持等方面都有了明显的提升和改进,使其更适应现代前端开发的需求和趋势。但需要注意的是,在迁移过程中可能需要对一些代码进行调整和适配。
101 60
|
22天前
|
前端开发 JavaScript 测试技术
Vue3中v-model在处理自定义组件双向数据绑定时,如何避免循环引用?
Web 组件化是一种有效的开发方法,可以提高项目的质量、效率和可维护性。在实际项目中,要结合项目的具体情况,合理应用 Web 组件化的理念和技术,实现项目的成功实施和交付。通过不断地探索和实践,将 Web 组件化的优势充分发挥出来,为前端开发领域的发展做出贡献。
28 8
|
21天前
|
存储 JavaScript 数据管理
除了provide/inject,Vue3中还有哪些方式可以避免v-model的循环引用?
需要注意的是,在实际开发中,应根据具体的项目需求和组件结构来选择合适的方式来避免`v-model`的循环引用。同时,要综合考虑代码的可读性、可维护性和性能等因素,以确保系统的稳定和高效运行。
21 1
|
21天前
|
JavaScript
Vue3中使用provide/inject来避免v-model的循环引用
`provide`和`inject`是 Vue 3 中非常有用的特性,在处理一些复杂的组件间通信问题时,可以提供一种灵活的解决方案。通过合理使用它们,可以帮助我们更好地避免`v-model`的循环引用问题,提高代码的质量和可维护性。
32 1
|
22天前
|
JavaScript
在 Vue 3 中,如何使用 v-model 来处理自定义组件的双向数据绑定?
需要注意的是,在实际开发中,根据具体的业务需求和组件设计,可能需要对上述步骤进行适当的调整和优化,以确保双向数据绑定的正确性和稳定性。同时,深入理解 Vue 3 的响应式机制和组件通信原理,将有助于更好地运用 `v-model` 实现自定义组件的双向数据绑定。
|
25天前
|
JavaScript 前端开发 API
从Vue 2到Vue 3的演进
从Vue 2到Vue 3的演进
37 0
|
25天前
|
JavaScript 前端开发 API
Vue.js响应式原理深度解析:从Vue 2到Vue 3的演进
Vue.js响应式原理深度解析:从Vue 2到Vue 3的演进
54 0
|
25天前
|
JavaScript API 开发者
Vue是如何进行组件化的
Vue是如何进行组件化的
|
27天前
|
JavaScript 前端开发 开发者
vue 数据驱动视图
总之,Vue 数据驱动视图是一种先进的理念和技术,它为前端开发带来了巨大的便利和优势。通过理解和应用这一特性,开发者能够构建出更加动态、高效、用户体验良好的前端应用。在不断发展的前端领域中,数据驱动视图将继续发挥重要作用,推动着应用界面的不断创新和进化。

相关实验场景

更多