初识vue3

1. 新建项目

vue create vue-study

2. 运行

yarn serve

语法

1. setup函数

可以取代data和method,相较于vue2,如果需要在template中使用的话,setup函数需要return。不需要再界面上暴露的变量就不需要return,精确控制导出的变量和方法

```javaScript
setup() {
    const girls = ref(["大脚", "刘英", "晓红"]);
    const selectGirl = ref("");
    // 使用ref,在script中使用/获取变量值需要加上value
    const selectGirlFun = (index: number) => {
        selectGirl.value = girls.value[index];
    };
    //因为在模板中这些变量和方法都需要调用,所以需要return出去。
    return {
        girls,
        selectGirl,
        selectGirlFun,
    };
}
```

2. ref函数

使用的话,需要引入`import { ref } from "vue";`,然后`ref(["大脚", "刘英", "晓红"])`

ref函数接收一个内部值,返回一个可响应且可变的对象,**在setup中,使用ref,要改变和读取一个值的时候,还要加上value**

3. reactive函数

是一个接收Object(对象)参数的函数,用于优化上述使用ref函数之后,改变和读取变量需要加上value的情况

和ref()函数一样,都是生成响应式对象的方法
```HTML


你选择了【{{ data.selectGirl }}】为你服务
``` ```JavaScript // 记得加上类型注解 interface DataProps { girls: string[]; selectGirl: string; selectGirlFun: (index: number) => void; } const data: DataProps = reactive({ girls: ["大脚", "刘英", "晓红"], selectGirl: '', selectGirlFun: (index: number) => { // 修改值不需要加value了 data.selectGirl = data.girls[index] } }); // 只需要返回一个data return { data, }; ```

4. toRefs()函数

使用reactive函数后,现在template中,每次输出变量前面都要加一个data,可以使用toRefs来优化

Vue3 的一个新函数toRefs(),引入后就可以对data进行包装,把 data 变成refData,这样就可以使用扩展运算符的方式了,否则直接使用扩展运算符会导致变量不可响应
```HTML

你选择了【{{ selectGirl }}】为你服务
``` ```JavaScript setup() { // const girls = ref(["大脚", "刘英", "晓红"]); // const selectGirl = ref(""); // const selectGirlFun = (index: number) => { // selectGirl.value = girls.value[index]; // }; const data: DataProps = reactive({ girls: ["大脚", "刘英", "晓红"], selectGirl: "", selectGirlFun: (index: number) => { data.selectGirl = data.girls[index]; }, }); const refData = toRefs(data); return { ...refData, }; }, ```

5. 生命周期

1. setup函数 -> 开始创建组件之前,在`beforeCreate`和`created`之前,创建的是data和method。

可以使用setup函数来代替beforeCreatecreated
2. onBeforeMount -> 组件挂载到节点之前
3. onMounted -> 组件挂载到节点之后
4. onBeforeUpdate => 组件更新之前
5. onUpdated -> 组件更新之后
6. onBeforeUnmount -> 组件卸载之前
7. onUnmounted -> 组件卸载之后
8. onActivated -> 激活组件时
9. onDeactivated -> 离开组件时
10. onErrorCaptured -> 当捕获一个来自子孙组件的异常时激活钩子函数

在使用钩子函数之前,需要引入
```JavaScript
import {
    reactive,
    toRefs,
    onMounted,
    onBeforeMount,
    onBeforeUpdate,
    onUpdated,
} from "vue";

// 注意:vue3的这些钩子函数写在setup函数里面
setup() {
    console.log("1-开始创建组件-----setup()");
    const data: DataProps = reactive({
    girls: ["大脚", "刘英", "晓红"],
    selectGirl: "",
    selectGirlFun: (index: number) => {
        data.selectGirl = data.girls[index];
    },
    });
    onBeforeMount(() => {
        console.log("2-组件挂载到页面之前执行-----onBeforeMount()");
    });

    onMounted(() => {
        console.log("3-组件挂载到页面之后执行-----onMounted()");
    });
    onBeforeUpdate(() => {
        console.log("4-组件更新之前-----onBeforeUpdate()");
    });

    onUpdated(() => {
    c   onsole.log("5-组件更新之后-----onUpdated()");
    });

    const refData = toRefs(data);

    return {
    ...refData,
    };
},
```

Vue2的生命周期函数依然可以使用,可以写在setup函数后面
```JavaScript
setup() {
    ...
}
beforeCreate() {
    console.log("1-组件创建之前-----beforeCreate()");
},
beforeMount() {
    console.log("2-组件挂载到页面之前执行-----BeforeMount()");
},
mounted() {
    console.log("3-组件挂载到页面之后执行-----Mounted()");
},
beforeUpdate() {
    console.log("4-组件更新之前-----BeforeUpdate()");
},
updated() {
    console.log("5-组件更新之后-----Updated()");
},


// 以下是两个版本生命周期的对比
// 除了beforeDestroy -> onBeforeUnmount、destroyed -> onUnmounted,其他只是加了on
Vue2--------------vue3
beforeCreate  -> setup()
created       -> setup()
beforeMount   -> onBeforeMount
mounted       -> onMounted
beforeUpdate  -> onBeforeUpdate
updated       -> onUpdated
beforeDestroy -> onBeforeUnmount
destroyed     -> onUnmounted
activated     -> onActivated
deactivated   -> onDeactivated
errorCaptured -> onErrorCaptured
````

6. onRenderTracked()和onRenderTrigger()函数

用来调试使用的两个钩子函数。使用前需要引入
`import { onRenderTriggered ,onRenderTracked,} from "vue";`

onRenderTracked函数——状态追踪

它会追踪页面上**所有**响应式变量和方法的状态,即我们在setup中return出去的值,一旦页面有更新,他都会进行追踪,然后生成一个event对象,我们通过event对象来查找程序的问题所在

onRenderTriggered函数——状态触发

它不像onRenderTracked函数,这个函数不会跟踪所有值的变化,而是给你变化值的信息,并且新值和旧值都会给你明确的展示出来

```JavaScript
onRenderTracked((event) => {
    console.log("状态跟踪组件----------->");
    console.log(event);
});

onRenderTriggered((event) => {
    console.log("状态跟踪组件----------->");
    console.log(event);
});
```

其中`event`对象属性:
```
- key 那边变量发生了变化
- newValue 更新后变量的值
- oldValue 更新前变量的值
- target 目前页面中的响应变量和函数
```

7. watch函数

使用之前需要先导入 `import {... , watch} from "vue"`

以下是监听一个数和多个数的使用方式
```JavaScript
watch(overText, (newValue, oldValue) => {
    document.title = newValue;
});

// 注意:
// 当我们想监听data.selectGirl这个reactive里边的值时,可以使用一个函数来解决,() => data.selectGirl
// 监听多个数的变化,返回的newValue也是一个数组
watch([overText, () => data.selectGirl], (newValue, oldValue) => {
    console.log(`new--->${newValue}`);
    console.log(`old--->${oldValue}`);
    document.title = newValue[0]; // 返回的newValue也是一个数组
});
```

8. Vue3模块化

如果需要将一个功能进行模块化和复用化,可以在src目录下,新建一个文件夹hooks(所有抽离出来的功能模块都可以放到这个文件夹里),然后再新建一个文件useNowTime.ts,这里使用use开头是一个使用习惯,代表是一个抽离出来的模块。

```JavaScript
// 注意需要引入ref
import { ref } from "vue";

const nowTime = ref("00:00:00");
const getNowTime = () => {
    const now = new Date();
    const hour = now.getHours() < 10 ? "0" + now.getHours() : now.getHours();
    const minu =
        now.getMinutes() < 10 ? "0" + now.getMinutes() : now.getMinutes();
    const sec =
        now.getSeconds() < 10 ? "0" + now.getSeconds() : now.getSeconds();
    nowTime.value = hour + ":" + minu + ":" + sec;

    setTimeout(getNowTime, 1000);
};

// 最后export
export { nowTime, getNowTime }

// 引入和使用
import { nowTime, getNowTime } from "./hooks/useNowTime";
// 注意: 需要在setup中return,才可以在template中使用
setup() {
    return {nowTime,getNowTime};
}

```

远程调用API组件也可以这样子封装

9. Teleport瞬间移动组件的使用

它可以把你写的组件挂载到任何你想挂载的DOM上,在vue2中,所有dom都是挂载在#app下的,如果想改变节点这是非常的困难的。vue3的Teleport组件可以帮助解决这个问题。

Teleport方法,可以把Dialog组件渲染到你任意想渲染的外部Dom上,不必嵌套再#app里了,这样就不会互相干扰了。可以把Teleport看成一个传送门,把你的组件传送到你需要的地方。 teleport组件和其它组件没有任何其它的差异,用起来都是一样的。

使用方法如下:
```JavaScript
// Model.vue,自定义组件
// 将编写的组件用标签进行包裹,在组件上有一个to属性,这个就是要写你需要渲染的DOMID了。


// /public/index.html,在其中增加一个#model节点
// App.vue,正常使用即可 ``` 这时候在浏览器中预览,就会发现,现在组件已经挂载到model节点上了,这就是teleport组件的使用了。

10. 初识Suspense组件

在Vue2.x时代,判断异步请求的状态是一件必须的事情,但是这些状态都要自己处理,根据请求是否完毕展示不同的界面,Vue3提供了Suspense组件来解决异步请求,页面渲染的问题

Suspense提供两个template的位置,一个是没有请求回来时显示的内容,一个是全部请求完毕的内容。这样进行异步内容的渲染就会非常简单。

**注意点:如果你要使用Suspense的话,要返回一个promise对象,而不是原来的那种JSON对象。**

以下为使用办法:
```JavaScript
// AsyncShow.vue,异步请求组件
// 2s之后页面出现JSPang文字



// App.vue
// 可以看到Suspense是有两个template插槽的,第一个default代表异步请求完成后,显示的模板内容。fallback代表在加载中时,显示的模板内容。

```

运行之后,如果一切正常,你可以看到,当我们打开页面时,首先显示的是Loading,然后才会显示JSPang。也就是promise返回的结果


- 在编写异步请求组件的时候,还可以通过 `async...await`的写法,它是`promise`的语法糖
```JavaScript
// AsyncShow.vue,异步请求组件
export default defineComponent({
    async setup() {  //promise 语法糖  返回之后也是promise对象
        const rawData = await  axios.get('https://apiblog.jspang.com/default/getGirl')
        return {result:rawData.data}
    }
})

```

Suspense组件加载多个异步组件的场景:

```JavaScript

    
    


// 解决办法
  
```

11. 处理异步请求错误

在异步请求中必须要作的一件事情,就是要捕获错误,因为我们没办法后端给我们返回的结果,也有可能服务不通,所以一定要进行捕获异常和进行处理。

在vue3.x的版本中,可以使用onErrorCaptured这个钩子函数来捕获异常。在使用这个钩子函数前,需要先进行引入
import { onErrorCaptured} from "vue";

有了onErrorCaptured就可以直接在setup()函数中直接使用了。钩子函数要求我们返回一个布尔值,代表错误是否向上传递,我们这里返回了true。

const app = {
  name: "App",
  components: { AsyncShow, GirlShow },
  setup() {
    onErrorCaptured((error) => {
      console.log(`error====>`,error)
      return true  
    })
    return {};
  },
};

参考

技术胖的vue3教程

你可能感兴趣的:(初识vue3)