vue3.0创建项目学习记录

一、vue3.0已经发布啦~

记录一下自己创建vue3.0项目的体验过程。

此刻就想放张图:
在这里插入图片描述

二、更新的一些东西

  1. Object.defineProperty => Proxy
  2. vdom 静态标记更加强大
  3. Composition API
  4. vite

三、初始项目

一改vue2.x使用vue-cli, vue3.0基于vite去创建项目:

npm init vite-app <project-name>
cd <project-name>
npm install
npm run dev

四、项目结构

├── index.html
├── package.json
├── public
│   └── favicon.ico
└── src
    ├── App.vue
    ├── assets
    │   └── logo.png
    ├── components
    │   └── HelloWorld.vue
    ├── index.css
    └── main.js
index.html/main.js

可以看到 main.js的引用写了type="module",利用浏览器的自带的import机制;

index.html

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <link rel="icon" href="/favicon.ico" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Vite App</title>
</head>

<body>
  <div id="app"></div>
  <script type="module" src="/src/main.js"></script>
</body>

</html>
  • main.js 初始实例不再是 new vue(option),改为了createApp(App)
  • Vue.prototype扩展方法改为了app.config.globalProperties
  • 还有一个需要注意的地方,vue3.0 setup内部不支持this,像vue2.x里可以 Vue.prototype扩展一些全局方法,在页面使用直接this就可以访问,在Composition API里面已经不能这么玩了😂。

main.js

import { createApp } from 'vue'
import App from './App.vue'
import './assets/index.css'
import * as config from './utils/config_globalProperties.ts'

const app = createApp(App);

// app.config: 全局配置的对象 
// app.config.globalProperties代替Vue 2.x Vue.prototype 扩展
// vue3.0 setup内部不支持this, 一些公共方法挂载vue也是访问不到的
Object.keys(config).forEach(ele => {
  app.config.globalProperties[ele] = config[ele]
});

// 应用挂载
app.mount('#app');


五、Composition API

1.setup

组件选项创建后在组件创建之前执行的组件选项,它用作组合API的入口点,相当于beforCreated()created()
vue2.x 在写页面的时候,script里面,是写的option Api导出一个对象,对象里面就是datamethodsmounted
现在直接一个setup函数,在setup里面把数据return给template;
下面是官网的例子,非常清晰:

<!-- MyBook.vue -->
<template>
  <div>{{ readersNumber }} {{ book.title }}</div>
</template>

<script>
  import { ref, reactive } from 'vue'

  export default {
    setup() {
      const readersNumber = ref(0)
      const book = reactive({ title: 'Vue 3 Guide' })

      // expose to template
      return {
        readersNumber,
        book
      }
    }
  }
</script>
2.ref

是对基本数据类型数据进行双向绑定的Api,经过ref过的数据,需要通过value属性拿到值;

import { ref } from "vue";

...

const a = ref(0);
console.log(a.value) // 0

...
3.reactive

引用数据类型的数据使用reactive,使用reactive有一个要注意的点,最好不要对reactive过的对象做解构操作,会使reactive过的对象里面的基本数据类型失去双向绑定,对解构的数据做更改是不会再去更新reactive的这个对象了。建议对reactive的数据慎用解构,直接操作reactive的对象,免得导致一些不必要的坑;

import { reactive } from "vue";

...

  let obj = reactive({
    a: "a",
    b: "b",
    c: {
      c1: "c1",
    },
  });
  
  // 数据更新
  obj.a = "我是a呀";
  obj.b = "我是b呀";
  obj.c.c1 = "我是c1呀";

  // 注意:对reactive的数据解构会导致 基础数据类型 失去reactive
  let { a, c } = obj;
  a = "我是被解构的a";     // 已经脱离reactive
  c.c1 = "我是被解构的c1"; // 还是可以更改到obj

  console.log(obj); // {a: "我是a呀",b: "我是b呀",c: {c1: "我是被解构的c1"}}
  console.log(a);   // 我是被解构的a
  console.log(c);   // {c1: "我是被解构的c1"}

...

4.Lifecycle Hooks 生命周期

composition Api里面生命周期也有所变化,beforeCreatecreated被setup替代,其他生命周期均多了on:

  • beforeCreate -> use setup()
  • created -> use setup()
  • beforeMount -> onBeforeMount
  • mounted -> onMounted
  • beforeUpdate -> onBeforeUpdate
  • updated -> onUpdated
  • beforeUnmount -> onBeforeUnmount
  • unmounted -> onUnmounted
  • errorCaptured -> onErrorCaptured
  • renderTracked -> onRenderTracked
  • renderTriggered -> onRenderTriggered
import { onMounted, onUpdated, onUnmounted } from 'vue'

const MyComponent = {
  setup() {
    onMounted(() => {
      console.log('mounted!')
    })
    onUpdated(() => {
      console.log('updated!')
    })
    onUnmounted(() => {
      console.log('unmounted!')
    })
  }
}
5.Provide / Inject

其实这个跟React.context很类似,都是为了解决组件嵌套多层props传值的问题(避免数据多层传递的繁琐性),在父级把需要传递的数据通过Provide包裹,在需要用到数据的子组件使用Inject注入即可使用,在子级修改Inject后的值父级的值是动态改变的。

app.vue 父级

<template>
  <img alt="Vue logo" src="./assets/logo.png" />
  <HelloWorld />
</template>

<script>
import HelloWorld from "./components/HelloWorld.vue";
import { provide, ref } from "vue";
export default {
  components: {
    HelloWorld,
  },
  setup() {
    let msg = ref("Hello Vue 3.0 + Vite");

    // 提供数据 provide inject
    // vue3.0 一改组件
    // 类似于 React.context(), myContext.provider myCcontent.consumer
    provide("msg", msg);

    return { msg };
  },
};
</script>

helloworld.vue 子级中使用

setup() {
  // 接收 父组件传来的数据
  const msg = inject("msg");

  return { msg }
},
6.自己搭建的小项目里暂时只使用到了:
  • ref
  • reactive
  • provide inject

helloword.vue

<template>
  <h1>{{ msg }}</h1>
  <p>{{ obj.a }}</p>
  <p>{{ obj.b }}</p>
  <p>{{ obj.c && obj.c.c1 }}、{{ obj.c && obj.c.c2 }}</p>
  <button @click="addCount">count is: {{ count }}</button>
</template>

<script>
import helloworld from "./helloworld";
export default {
  setup() {
    // helloworld() 为逻辑代码,可以单独拎出去,这也是composition Api的一大好处,逻辑代码可以高度解耦,可复用性更强!
    return Object.assign({}, helloworld());
  },
};
</script>

helloworld.ts

import { ref, reactive, inject } from "vue";
import { $log, $info, $test } from "../modules-index";

const helloworld = ():object => {
  // 接收 父组件传来的数据
  const msg = inject("msg");

  // 1. ref
  const count = ref(0);
  const addCount = function () {
    count.value++;
    $log(count.value, "count:");
  };

  // 2. reactive
  const obj = reactive({
    a: "a",
    b: "b",
    c: {
      c1: "c1",
      c2: "c2",
    },
  });

  obj.a = "我是a呀";
  obj.b = "我是b呀";
  obj.c.c1 = "我是c1呀";

  // 注意:对reactive的数据解构会导致 基础数据类型 失去reactive
  let { a, c } = obj;
  a = "我是被解构的a";
  c.c1 = "我是被解构的c1";

  $log(obj);     // {a: "我是a呀",b: "我是b呀",c: {c1: "我是被解构的c1",c2: "c2",},}
  $log(a, 'a:'); // 我是被解构的a 
  $log(c, 'c:'); // {c1: "我是被解构的c1", c2: "c2"}

  // 测试引用
  $log($info, "测试引用:");
  $test();

  // 通过return把数据暴露给template
  return { msg, count, addCount, obj }
};

export default helloworld;

六、代码

以上示例的代码放在了GitHub上: https://github.com/LLDLLY/vue3.0-init.git

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值