Vue3入门

标签: 无 分类: 未分类 创建时间:2021-01-04 03:07:00 更新时间:2023-10-20 11:23:26

前言

Vue3.0.0已经发布了,是时候迎头赶上了,视频教程也已经有了。 关于Vue3.0的重大的改进,反正我觉得和Vue2.0还是有不小的变动的,特别的就是这个setup函数。我自己感觉水平不够,看不出来有什么好的地方,写法不同了,思想不同了,性能不同了。

(1) 主要就是computed计算属性我觉得有点不好用了,进行计算属性就必须写.value,不好用,而且配合vuex的时候,可能不需要响应式数据,但是最后还是会变成响应式的
(2) 好用的地方,就是单文件组件不需要必须有一个根div了
(3) 还有就是代码组织我感觉容易乱吧,vuex我觉得也有点控制不住了,特别是对于对象的引用,比如本来只是作为数据存储的一个对象,不需要进行响应式,但是放到vuex中,就变成了响应式了,需要使用shallow这种语法吧。

参考文章:
1.不要再用 Vue 2 的思维写 Vue 3 了
2.Vue3.2 setup语法糖、Composition API归纳总结 这个其实也挺好的,其中常用到的一些操作都有说明
3.vue3 watch不生效_让你30分钟了解vue 3 一个完成的vue 3.x 完整组件模版结构包含了:组件名称、 props、components、setup(hooks、computed、watch、methods 等)
4.Vue 中的 defineComponent 介绍了为什么在写组件的时候,不用 export default {},而变成了 export default defineComponent({}),主要就是为了方便编译器进行类型推导用的。

1.创建项目

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
## 安装
npm install -g @vue/cli
# OR
yarn global add @vue/cli

## 升级
npm update -g @vue/cli

# 或者
yarn global upgrade --latest @vue/cli

## 创建项目
vue create hello-world

## 使用vite创建项目
pnpm create vite

创建项目的时候,最新的vue-cli有一个选项就是选择vue的版本。

2.vue-router

(1) 安装

1
yarn add vue-router@next --save

(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
30
import {
createRouter,
createWebHashHistory//hash模式
} from 'vue-router'

const router = new createRouter({
history:createWebHashHistory(),
routes:[
{
path:'/',
redirect:'/home'
},

{
path:'/home',
component:() => import('@/views/Home.vue')
},
]
})

/**
* 权限控制,动态路由添加等
*/
router.beforeEach((to,from,next) => {
console.log(to,from,111);
next();
})

export default router;

(3) 引用 router-view
这里可以直接使用 router-view 了,不需要外层再包裹一层 div

1
2
3
4
5
6
7
8
9
10
11
<template>
<router-view/>
</template>

<script>
export default {
name: 'App',
}
</script>


(4) 注入

1
2
3
4
5
6
7
8
import { createApp } from 'vue'
import App from './App.vue'
import Router from './router'

createApp(App)
.use(Router)
.mount('#app')

(5) 获取父路由

1
2
3
4
5
6
7
8
// 获取路由记录
const MATCHED = route.matched

// 获取该记录的路由个数
const LEN = MATCHED.length

// 获取倒数第二个路由(也就是当前路由的父级路由)
const ROUTE_PARENT = MATCHED[LEN - 2]
参考文章:
1.vue3.0 集成vue-router、vuex
2.Vue3.0迁移(Vue Router篇)
3.vue3.0配置路由导航守卫和路由元信息 一个进行页面登陆和授权的导航路由实例,加一个元信息,然后我们在router.beforeEach上读取这个信息
4.vue获取父路由 在钩子函数中获取路由
5.vue3.0路由route/router的使用
6.路由的使用

4.vuex

(1) 安装

1
2
3
4
## yarn
yarn add vuex@next --save
## pnpm
pnpm add vuex@next -D

5.配置路径别名

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
const path = require('path')

function resolve (dir) {
return path.join(__dirname, dir)
}
// 项目的主要配置文件
module.exports = {
// webpack 配置进行更细粒度的修改 https://cli.vuejs.org/zh/config/#chainwebpack
chainWebpack: (config) => {
// 修改文件引入自定义路径
config.resolve.alias
.set('@', resolve('src'))
.set('style', resolve('src/assets/style'))
}
}

6.动态组件

在使用3.0的使用,如果引入动态组件,像下面这样,就会报错

1
2
3
4
5
6
7
export default {
components:{
rfdwd:()=>import("./Rfdwd.vue"),
},
setup(){
}
}

【解决方法】
使用新的 defineAsyncComponent 定义组件。

1
2
3
4
5
import { defineAsyncComponent } from 'vue'
...
components: {
LatestBox: defineAsyncComponent(() => import('@/components/LatestBox.vue'))
}

7.响应式数组

响应式数据有一个问题,如果你将一个对象变成了响应式的,如果改变了整个对象的指向,那么这个还是响应式的吗?这个问题留着我去问别人。

如果你生命了一个数组,不能通过改变对象的值进行响应,错误的示例

1
2
3
4
5
6
7
8
9
10
11
let legend=reactive([
{
color:"#4caf50",
title:"100",
}
]);

// 错误的示例
legend=[];
// 或者是
legend.value=[];

正确的示例:

【方法一】

1
2
3
4
5
6
7
8
// 直接使用ref
const rf_data = ref([]); // 人防数据
/**
* 初始化数据
*/
const init_data=()=>{
rf_data.value=[1,2,3];
}

【方法二】

1
2
3
4
5
6
// 直接使用reactive
const state = reactive({
arr: []
});

state.arr = [1, 2, 3]
参考文章:
1.Vue3.0(四)ref源码分析与toRefs
2.vue3使用reactive包裹数组如何正确赋值
3.vue3使用reactive包裹数组如何正确赋值
4.Vue3 Composition API: 对比ref和reactive ref 的作用就是将一个原始数据类型(primitive data type)转换成一个带有响应式特性;reactive (等价于Vue2中的Vue.observable() )来赋予对象(Object) 响应式的特性;响应型对象(reactive object) 转化为普通对象(plain object),同时又把该对象中的每一个属性转化成对应的响应式属性(ref);
5.vue3获取原始对象方法,禁止响应式toRaw
6.vue3.0的toRaw和markRaw toRaw 返回 reactive 或 readonly 代理的原始对象。这是一个转义口,可用于临时读取而不会引起代理访问/跟踪开销,也可用于写入而不会触发更改
7.vue3学习–readonly与shallowReadonly、toRaw与markRaw、toRef的特点与作用
8.vue3.0数组清空与重新赋值 数组用ref([])来声明,然后用list.value = []来修改
9.Vue3实践指南:使用reactive函数声明数组如何正确赋值响应式、script setup语法糖中toRefs如何优雅呈现、Options API 与 Composition API 如何选择及混用是否对性能有影响、关于 setup 中没有 this 的问题及 setup 的执行时机

8.props

【方法一】
使用 props 属性进行内容的传递

  • 父组件

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    <template>
    <child :attr="curr">
    </template>


    <script>
    import child from './child';
    import {reactive} from "vue";

    export default {
    setup(){
    const curr=reactive({
    value:{}
    }); // 当前选中对象

    return {
    curr
    }
    }
    }

  • 子组件
    在使用的时候,我发现如果不单独的定义这个 props ,在 setup 里面就会得到一个 undifined 的值。

    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
    import {toRefs,computed} from "vue";
    export default {
    props: {
    attrs: {
    require:true,
    type:Object,
    }
    },
    setup(props){
    /**
    * 数据部分
    */

    const currFeature=toRefs(props.attrs.value);

    /** 计算属性 */
    const currInfo = computed(() => {
    return currFeature?currFeature.properties:{};
    });

    return {
    currInfo
    }
    }
    }
参考文章:
1.vue3组合式api中的ref、toRef、toRefs三个函数的简单使用示例
2.vue3 setup使用props
3.Props 这是官方的解释,我发现现在越来越多的就是使用 setup 这种单文件的说明了。

9.watch

(1) 像下面的例子中,watch监听到了props的变化,但是无法更新页面上的currInfo和currProps的值,不知道为什么啊。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
    setup(props){
/**
* 数据部分
*/
let currInfo=reactive({});
let currProps=reactive({});

let currInfoCopy=JSON.parse(JSON.stringify(props.attrs.value)); // 对原始数据进行拷贝
currInfo=reactive(currInfoCopy); // 当前对象
currProps=reactive(currInfo.properties); // 当前属性信息
/** 下面的响应式无效了 */
watch(props.attrs,()=>{
let currInfoCopy=JSON.parse(JSON.stringify(props.attrs.value)); // 对原始数据进行拷贝
console.log(currInfoCopy);
currInfo=reactive(currInfoCopy); // 当前对象
currProps=reactive(currInfo.properties); // 当前属性信息
});
return {
currInfo,
currProps
}
}

(2) 无法进行深度监听
我在vuex中有一个对象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
const store = createStore({
state () {
return {
yujing_info:{
transed:0, // 已转移人员
}, // 预警信息
}
},
mutations: {
setYujingInfo(state,data){
state.yujing_info=data;
},
},
});

当我在一个组件中,改变这个值的时候

1
2
3
4
5
6
7
8
const yujing_info=computed(()=>store.state.yujing_info);

function init(){
let info=toRaw(yujing_info.value);
info.transed=trans_nums;
store.commit("setYujingInfo",info);
}

我期望的在另外的一个组件中的监听函数

1
2
3
4
5
6
7
// setup中的监测
watch(()=>store.state.yujing_info,()=>{
let yujing_info=toRaw(store.state.yujing_info);
console.log(yujing_info)
},{
deep:true,
});

但是监听失败了,当在第二步,改变transed 值当时候,第三步的监听函数并不会执行

【解决方法】
后来去掉了computed的监听,直接修改了store.state上的属性,这个时候,即便是注释掉了 commit, 也能实现响应式监听。

1
2
3
4
// 更新转移人数
let info=store.state.yujing_info;
info.transed=trans_nums;
// store.commit("setYujingInfo",info);

10.事件监听

使用事件的时候,出现了问题:Extraneous non-emits event listeners (update, canel) were passed to component but could not be automatically inherited because component renders fragment or text root nodes. If the listener is intended to be a component custom event listener only, declare it using the “emits” option.

【解决方法】
就是在子组件中声明需要跑出的事件列表

1
2
3
4
5
export default {
emits:["update","canel"],
setup(props,context){
}
}

11.异步组件相互依赖

两个都是异步组件,但是一个组件依赖于另外一个组件,这个时候怎么办呢?

小额赞助
本人提供免费与付费咨询服务,感谢您的支持!赞助请发邮件通知,方便公布您的善意!
**光 3.01 元
Sun 3.00 元
bibichuan 3.00 元
微信公众号
广告位
诚心邀请广大金主爸爸洽谈合作
每日一省
isNaN 和 Number.isNaN 函数的区别?

1.函数 isNaN 接收参数后,会尝试将这个参数转换为数值,任何不能被转换为数值的的值都会返回 true,因此非数字值传入也会返回 true ,会影响 NaN 的判断。

2.函数 Number.isNaN 会首先判断传入参数是否为数字,如果是数字再继续判断是否为 NaN ,不会进行数据类型的转换,这种方法对于 NaN 的判断更为准确。

每日二省
为什么0.1+0.2 ! == 0.3,如何让其相等?

一个直接的解决方法就是设置一个误差范围,通常称为“机器精度”。对JavaScript来说,这个值通常为2-52,在ES6中,提供了Number.EPSILON属性,而它的值就是2-52,只要判断0.1+0.2-0.3是否小于Number.EPSILON,如果小于,就可以判断为0.1+0.2 ===0.3。

每日三省
== 操作符的强制类型转换规则?

1.首先会判断两者类型是否**相同,**相同的话就比较两者的大小。

2.类型不相同的话,就会进行类型转换。

3.会先判断是否在对比 null 和 undefined,是的话就会返回 true。

4.判断两者类型是否为 string 和 number,是的话就会将字符串转换为 number。

5.判断其中一方是否为 boolean,是的话就会把 boolean 转为 number 再进行判断。

6.判断其中一方是否为 object 且另一方为 string、number 或者 symbol,是的话就会把 object 转为原始类型再进行判断。

每日英语
Happiness is time precipitation, smile is the lonely sad.
幸福是年华的沉淀,微笑是寂寞的悲伤。