Vue3、Vue2都有哪些区别
Vue3、Vue2都有哪些区别
vue3和vue2版本对比:
vue2中绝大多数的API与特性,在vue3中同样支持。同时,vue3中还新增了所特有的功能,并废弃了vue2中的某些旧功能。
新增的功能如:组合式API、多根节点组件、更好的TypeScript支持等。
废弃的功能如:过滤器、不在支持$on,$off,$once等实例方法。
详细变更信息可参考官方文档的迁徙指南:https://v3.vuejs.org/guide/migration/introduction.html
vue3和vue2中过滤器:
过滤器仅在vue2和vue1中支持,在vue3中剔除了过滤器的使用,在vue3中官方建议使用计算属性或方法代替剔除的过滤器功能。
SPA(单页面应用程序)优点:
1.良好的交互体验
①单页面应用内容的改变不需要重新加载整个页面
②获取数据也是通过Ajsx异步获取
③没有页面之间的跳转,不会出现白屏现象
2.良好的前后端工作分离模式
①后端专注于提供API接口,更易于实现API接口复用
②前端专注于页面的渲染,更利于前端的工程化发展
3.减轻服务器的压力
①服务器只提供数据,不负责页面的合成与逻辑的处理,吞吐能力会提高数倍
SPA(单页面应用程序)缺点与解决办法:
1.首屏加载慢
①路由懒加载
②代码压缩
③CDN加速
④网络传输压缩
2.不利于SEO
①SSR服务器端渲染
如何快速创建vue中的SPA(单页面应用程序)项目:
1.基于vite创建
2.基于vue-cli创建
vite创建的四部曲:
1.npm init vite-app 项目名称
2.cd 项目名称
3.npm i
4.npm run dev
vue2、vue3 <template>中的节点数不同:
vue2中,<template>节点内仅支持单个根节点
<template>
<div>
<h1>根组件</h1>
<p>p标签</p>
</div>
</template>
vue3中,<template>节点内支持多个根节点
<template>
<div>
<h1>根组件</h1>
</div>
<p>p标签</p>
<div>div标签</div>
</template>
vue3中组件的注册分为两种:
1.全局组件,可以在全局任何一个组件内使用
main.js全局注册,可以在任何其他组件内使用
// 导入createApp函数
import { createApp } from 'vue'
// 导入待渲染的根组件
import App from './App.vue'
import './index.css'
// 导入需要被全局注册的组件
import Left from "./components/left1.vue"
// console.log(Left.name);Left1
// 调用createApp函数,创建spa应用的实例
const app=createApp(App)
// 调用app.component方法全局注册组件
app.component("My-Left",Left)
// 此处注册的全局注册组件,也可替换为
// app.component("Left.name",Left)
app.mount('#app')
2.局部组件,只能在当前注册的范围内使用
<template>
<div>
<My-Left></My-Left>
<h1>根组件</h1>
<My-Search></My-Search>
</div>
</template>
<script>
import Seach from "./components/seach.vue";
export default {
name: "App",
components: {
// 注册私有组件
"My-Search": Seach,
},
};
</script>
定义组件名称的两种方式:
1.使用kebab-case命名法(俗称短横线命名法,如:my-left)
特点:严格按照短横线名称进行使用
2.使用PascalCase命名法(俗称帕斯卡命名法或大驼峰命名法,如:MyLeft)
特点:既可以按照帕斯卡使用,又可以转化为短横线使用(适用性强,推荐使用)
样式穿透/deep/:
如果给当前组件的style节点添加了scoped属性,则当前组件的样式对子组件是不生效的。如果想让某些样式对子组件生效,可以使用/deep/深度选择器。
注:/deep/是在vue2中的写法,vue3推荐使用:deep()
<style lang="less" scoped>
/* vue2写法 */
/deep/.change {
color: red;
}
</style>
<style lang="less" scoped>
/* vue3写法 */
:deep(.change ){
color: red;
}
</style>
class与style绑定的几种方式:
<template>
<div>
<!-- 数组形式的绑定 -->
<!-- <h1 :class="[fontIs ? 'ac' : '', del ? 'delete' : '']">根组件</h1>
<button @click="fontIs = !fontIs">缩放</button>
<button @click="del = !del">删除切换</button>
-->
<!-- 对象形式的绑定,简化数组形式的臃肿问题 -->
<!-- <h1 :class="obj">根组件</h1>
<button @click="obj.ac = !obj.ac">缩放</button>
<button @click="obj.delete = !obj.delete">删除切换</button> -->
<hr />
<!-- 以对象的语法绑定内联style样式,注:fontSize不以驼峰的方式引用,就要采用字符串的方式使用 -->
<div
:style="{ color: active, fontSize: size + 'px', 'background-color': bgc }"
>
相信光
</div>
<button @click="size++">字体变大</button>
</div>
</template>
<script>
export default {
name: "App",
data() {
return {
// fontIs: true,
// del: true,
obj: {
ac: true,
delete: true,
},
active: "red",
size: 30,
bgc: "pink",
};
},
};
</script>
<style scoped>
.ac {
font-size: 40px;
}
.delete {
text-decoration: line-through;
}
</style>
props的自定义验证函数:
props: {
type: {
// 通过 validator函数对属性值进项校验,参数通过value进行接收
// 如果没有下面的值,控制台会警告
validator(value) {
return ["sucess", "reject", "resolve"].indexOf(value) != -1;
},
},
},
computed和methods细节区别:
<h1>{{ blus }}</h1>
<h1>{{ plus() }}</h1>
computed: {
// 调用不用加()
blus() {
return this.count * 3;
},
},
methods: {
// 调用要加()
plus() {
return this.count * 3;
},
},
vue3中组件的自定义事件:
为了让组件的使用者可以监听到组件内状态的变化,此时需要用到组件的自定义事件。
自定义事件的三个使用步骤
封装组件时:
①声明自定义事件(必须在emits节点中声明)
②触发自定义事件(通过this.$emit(“自定义事件名称”)进行触发)
使用组件时:(v-on或@进行监听)
③监听自定义事件
例:
子组件child.vue
<template>
<div>
child组件的count值是:{{ count }}
<button @click="add">+1</button>
</div>
</template>
<script>
export default {
name: "MyChild",
// 1.声明自定义事件
emits: ["countChange"],
data() {
return {
count: 0,
};
},
methods: {
add() {
this.count++;
//2. 触发自定义事件,可以传递第二个参数为自定义事件传参
this.$emit("countChange", this.count);
},
},
};
</script>
根组件App.vue
<template>
<div>
根组件
<hr />
<MyChild @countChange="getCount"></MyChild>
</div>
</template>
<script>
import MyChild from "./components/props/child.vue";
export default {
name: "App",
components: {
MyChild,
},
methods: {
getCount(value) {
console.log("触发了自定义事件" + value);
},
},
};
</script>
vue3的组件中v-model(实现组件的内外同步)子向父传值的不同之处:
根组件:
<template>
<div>
<h1>根组件---{{ count }}</h1>
<button @click="count++">+1</button>
<!-- 1.在v-bind之前添加v-model指令 -->
<MyChild v-model:num="count"></MyChild>
</div>
</template>
<script>
import MyChild from "./components/props/child.vue";
export default {
name: "App",
data() {
return {
count: 0,
};
},
components: {
MyChild,
},
};
</script>
子组件:
<template>
<div>
child组件 {{ num }}
<button @click="add">+1</button>
</div>
</template>
<script>
export default {
name: "MyChild",
props: ["num"],
// 2.子组件声明emits自定义事件,格式为update:
emits: ["update:num"],
methods: {
add() {
// 3.调用$emit触发自定义事件,更新父组件中的数据
// 旧值+1后通过"update:num"更新到父组件中
this.$emit("update:num", this.num + 1);
},
},
};
</script>
组件的生命周期:
指的是组件从创建->运行->销毁的整个过程,强调的是一个时间段。
vue框架为组件内置了不同时刻的生命周期函数,生命周期函数会随着组件的运行而自动调用。如:①当组件在内存中被创建完毕之后,会自动调用created函数
②当组件被成功的渲染到页面上之后,会自动调用mounted函数
③当组件被销毁完毕之后,会自动调用unmounted函数
vue3中主要的生命周期函数:
vue3中全部的生命周期函数:
vue3中的数据共享:
vue3中子向父传值要使用$emits声明一个自定义事件
兄弟之间传值eventBus:
安装mitt依赖包,执行如下命令
npm install mitt@2.1 -S
eventBus.js文件
// 导入mitt包
import mitt from "mitt"
// 创建实例对象
const bus=mitt()
// 共享出去
export default bus
<template>
<div>
数据发送方count的值为{{ count }}
<button @click="add">+1</button>
</div>
</template>
<script>
import bus from "../eventBus.js";
export default {
name: "MyLeft",
data() {
return {
count: 0,
};
},
methods: {
add() {
this.count++;
bus.emit("countChange", this.count);
},
},
};
</script>
<template>
<div>数据接收方num的值为{{ num }}</div>
</template>
<script>
import bus from "../eventBus.js";
export default {
name: "MyRight",
data() {
return {
num: 0,
};
},
created() {
bus.on("countChange", (count) => {
this.num = count;
});
},
};
</script>
<template>
<div>
根组件
<Right></Right>
<Left></Left>
</div>
</template>
<script>
import Right from "./components/props/right.vue";
import Left from "./components/props/left.vue";
export default {
name: "App",
data() {
return {};
},
components: {
Right,
Left,
},
};
</script>
后代关系组件之间的数据共享:
后代关系组件之间的数据共享数据,指的是父节点组件向其子孙组件共享数据。此时组件之间的嵌套关系比较复杂,可以使用provide(共享时使用)和inject(接受时使用)实现后代关系组件之间的数据共享。(注:没有直接或间接关系是无法使用的)
<template>
<div>
根组件{{ color }}
<button @click="color = 'red'">切换</button>
<Left></Left>
</div>
</template>
<script>
import Left from "./components/left.vue";
// 按需导入计算属性
import { computed } from "vue";
export default {
// name: "App",
data() {
return {
color: "orange",
};
},
components: {
Left,
},
provide() {
// 返回共享出去的数据对象,非响应式的
// return { color: this.color };
// 利用computed函数向下共享响应式的数据。
return {
color: computed(() => this.color),
};
},
};
</script>
<template>
<div>
二级组件{{ color.value }}
<Right></Right>
</div>
</template>
<script>
import Right from "./right.vue";
export default {
inject: ["color"],
components: {
Right,
},
};
</script>
<template>
<!-- 如果父级共享的是响应式数据,则子孙节点需要以.value的形式使用 -->
<div>三级组件{{ color.value }}</div>
</template>
<script>
export default {
inject: ["color"],
};
</script>
数据共享的六种方法:
1.父子关系
①父->子 属性绑定
②子->父 事件绑定
③父<->子 组件上的v-model
2.兄弟关系
①eventBus
3.后代关系
①provide&&inject
4.全局数据共享
①vuex
vue3中全局配置axios
自定义指令:
vue2中使用的是{bind,update},vue3中使用的是{mounted,updated}
路由:
Vue-router目前有3.x和4.x版本的,vue3使用4.x版本的,vue2使用3.x版本的。
版本3和版本4路由的最主要的区别:创建路由模块的方式不同。
vue3中路由的基本使用步骤:
①在项目中安装vue-router(npm install vue-router@next -S)
②定义路由组件
③声明路由链接(<router-link></router-link>)和占位符(<router-view></router-view>)
<div>
<router-link to="/left">左导航</router-link>
<router-link to="/right">右导航</router-link>
<router-view></router-view>
</div>
④创建路由模块
// 按需导入两个方法 分别是创建路由的实例对象和指定路由工作模式
import {createRouter,createWebHashHistory} from "vue-router"
import Left from "./left.vue"
import Right from "./right.vue"
const router=createRouter({
// 指定路由工作模式,以哈希进行组件的切换
history:createWebHashHistory(),
routes: [
{path:"/left", component:Left},
{path:"/right", component:Right},
]
})
export default router
⑤导入并挂载路由模块
//在main.js导入路由
import router from "./components/router.js"
// 挂载路由模块
app.use(router)
激活路由链接高亮的两种方式:
①使用默认的高亮class类
/* 被激活的路由链接中,默认会有一个叫做router-link-active的类名,可用此类名为路由链接设置高亮模式 */
.router-link-active {
background-color: aqua;
color: white;
font-weight: bolder;
}
②自定义路由高亮的class类
//在router.js里面修改
const router=createRouter({
// 指定路由工作模式,以哈希进行组件的切换
history:createWebHashHistory(),
// 默认的router-link-active类名会被覆盖掉
linkActiveClass:"change",
routes: [
{path:"/left", component:Left},
{path:"/right", component:Right},
]
})
命名路由:
通过name属性为路由规则定义名称的方式,叫做命名路由。命名路由的name值不能重复,必须保证唯一性。
//命名路由
{ name:"move",path:"/left", component:Left},
使用命名路由实现声明式导航
为<router-link>标签动态绑定to属性的值,并通过name属性指定要跳转到的路由规则。期间还可以用params属性指定跳转期间要携带的路由参数。
<router-link :to="{name:'move',params:{id:3} }">go to</router-link>
使用命名路由实现编程式导航
调用push函数期间指定一个配置对象,name是要跳转到的路由规则,params是携带的路由参数
<template>
<button @click="goto(3)">go to</button>
</template>
<script>
export default {
methods:{
goto(id){
this.$router.puah({name:"move",params:{mid:id}})
}
}
}
</script>
导航守卫:
其中next参数调用的三种方式
①next()直接调用,直接放行
②next(false)强制停留在当前页面
③next(“/login”)强制跳转到登录页面
vue-cli:
安装vue-cli
npm install -g @vue/cli
或
yarn global add @vue/cli
创建项目的两种方式
1.基于命令行的方式创建vue项目
vue create 项目名称
2.基于可视化面板创建vue项目
vue ui
基于vue ui 创建项目的步骤
1.在vue ui文件下打开PowerShell 输入vue ui命令并回车,此时会跳到创建项目的面板(注:不要关闭PowerShell)
2.点击创建,并点击下面的在此创建新项目
3.输入项目名称(如:vue-ui-number1)
4.点击下一步进入到预设面板,选择手动,进入功能面板
5.功能面板只勾选Babel、CSS Pre-processors和使用配置文件,并点击下一步
6.根据自己的需求选择vue版本和预处理器(在这:我们选择2x和less预处理器),然后点击创建项目
7.需要保存 输入预设名并点击保存预设名创建项目(在.vuerc下可以清除预设)
vue组件库:
在实际开发中,前端开发者可以把自己封装的.vue组件整理打包,并发布为npm的包,从而供其他人下载和使用。这种可以直接下载并在项目中使用的组件,就叫vue组件库。
vue组件库和bootstrap的区别
bootstrap只提供了纯粹的原材料(css样式,html结构以及js特效),需要由开发者做进一步的组装和改造
vue组件库是遵循vue语法,高度定制的现成组件,开箱即用
最常用组件库:
1.pc端
①Element UI(支持vue2(使用旧版)和vue3(使用新版)使用)
②View UI
2.移动端
Mint UI和Vant
axios拦截器在vue2和vue3中的配置有所不同
拦截器会在每次发起ajax请求和得到响应的时候会自动被触发,主要应用如:token身份认证,loading效果等。
配置请求拦截器:
通过axios.interceptors.request.use(成功的回调,失败的回调)可以配置请求拦截器,失败的回调可以被省略。
proxy跨域代理:
通过vue-cli创建的项目在遇到接口跨域问题时,可以通过代理的方式来解决。
1.在main.js文件中,把axios的请求根路径改为当前vue项目运行地址(请求接口不在跨域)
2.在项目根目录下创建vue.config.js的配置文件,并声明如下配置后重新运行项目。
module.export={
devServer:{
//仅在开发阶段的项目生效,会将任何未知请求(没有匹配到静态资源文件的请求)代理到
相应的地址
//项目上线发布时,依旧需要API接口服务器开启CROS跨域资源共享
proxy:"后台地址路径"
}
}
更多其他内容,请参考官方文档!
更多推荐
所有评论(0)