vue介绍
1vue是一款构建用户界面(基于数据动态渲染页面)的渐进式jsp框架
2两种开发方式:
(1)核心包开发
(2)插件工具化开发(整站开发)
3创建一个vue实例:
(1)准备容器
(2)引包(开发版本和生产版本)
(3)创建vue实例
(4)使用插值表达式渲染数据
vue2
一、指令
带有v-前缀的特殊标签属性
二、常用的指令
1.v-show与v-if
v-show:通过切换css的display:none来控制显示隐藏,可以用来实现频繁切换显示隐藏的效果
v-if:根据判断条件控制元素的创建和溢出(条件渲染),要么显示,要么隐藏,适用于不频繁切换的场景。
2.v-else与v-else-if
(1)作用:辅助v-if进行判断渲染
(2)语法:v-else,v-else-if="表达式“
注意:需要配合v-if一起使用
3.v-on:
(1)作用:注册事件=添加监听+提供处理逻辑
(2)语法:有两种
其一,v-on:事件名=“内联语句”
其二,v-on:事件名=“methods中的函数名”
简写形式,将v-on替换为@,
4.v-bind
(1)作用:实现动态绑定
简写形式,可以去掉v-bind
(2)对样式控制的增强
1)通过操作class,语法为:class="对象/数组",传递的数据有两种情况,
其一,传对象
其二,传数组
2)操作style
5.v-for
(1)作用:基于数据循环,多次渲染整个元素
(2)语法:
v-for = “(item,index) in 数组”
其中,item为每一项,index为下标,key关键字的作用:v-for的默认行为会尝试原地修改元素(就地复用),它的值只能为字符串或者数字类型且必须唯一,通常使用id作为key
可以通过下列代码来体会其用法:
6.v-model
(1)作用:给表单元素使用,实现数据与视图的双向绑定,快速获取和设置表单元素内容。
所谓双向绑定,就是数据变化-视图自动更新,视图变化-数据自动更新
(2)语法:
v-model=”变量“
可以通过以下案例来体会其用法:
(3)应用于其它表单元素的绑定
可以快速获取或设置表单元素的值
(4)原理:
本质上是一个语法糖,例如应用在输入框上面,就是vlaue属性和input事件的合写
作用:提供数据的双向绑定
- 数据变:视图跟着变:value
- 视图变:数据跟着变:@input
案例演示:学习网:
运行结果:
三、指令修饰符
通过“.”指明一些指令后缀,不同后缀封装了不同的处理操作,常见的有以下几个
1按键修饰符
@keyup.enter 键盘回车监听
2v-model修饰符
v-model.trim 去除首尾空格
v-model.number 转换为数字
3事件修饰符
@事件名.stop 阻止冒泡
@事件名.prevent 阻止默认行为
4.sync修饰符:
作用:可以实现子组件与父组件数据的双向绑定,简化代码
5ref和$refs
作用:获取dom元素或组件实例
特点:查找范围:当前组件内:(更精确稳定)
四、计算属性
1作用:基于现有的数据,计算出来的新属性,依赖的数据变化,自动重新计算。
2语法:
声明在computed配置项中,一个计算属性对应一个函数,和普通属性一样使用
{{计算属性名}}
3computed计算属性
作用:封装了一段对于数据的处理,求得一个函数
语法:
(1)写在computed配置项中,
(2)作为属性,直接使用,this.计算属性{{计算属性}}
需要注意的是,computed计算属性会对计算出来的结果进行缓存,如果依赖项变化了,会重新计算并再次缓存
4methods方法
作用:给实例提供一个方法,调用来处理业务逻辑
语法:
(1)写在methods配置项中
(2)作为方法,需要调用,this.方法名(){{方法名()}} @事件名=”方法名“
五、watch监听器
作用:监视数据变化,执行一些业务逻辑或异步操作
应用:实现文档翻译:
也可以通过添加额外配置项来实现更复杂的功能,例如
deep:true:对复杂类型进行深度监视
immediate:true初始化立刻执行一次handler方法
六、生命周期
1四个阶段:
创建:响应式数据,监听,最后发送初始化渲染请求(created)
挂载:渲染模板,最后操作dom(mounted)
更新:点击事件,修改数据,更新视图(循环)
销毁:销毁实例(beforeDestory)释放vue以外的资源,清除定时器,延时器等)
2.8个生命周期函数
七、工程化开发
基于构建工具(webpack)的环境中开发vue
vue CLI
1介绍:
是vue官方提供的全局命令工具
可以帮助我们快速创建一个标准化基础架子
2优点:
(1)开箱即用,零配置
(2)内置label等工具
(3)标准化
3使用步骤:
(1)全局安装:
npm i @vue/cli -g
(2)查看版本:
vue --version
(3)创建项目:
vue create project-name
(4)启动项目:
npm run serve
创建好之后,打开项目文件夹,我们可以看到以下内容:
以下为项目目录结构:
4组件
(1)注册的两种方法:
1)全局注册:
2)局部注册:
(2)组件的三大组成部分
结构(template,在veu2中,只能有一个根元素,在vue3中,可以不只有一个),样式(style,防止样式冲突,加上scoped),逻辑(style,即CSS属性)
scoped原理:
(3)组件之间的通信
组件关系:父子关系(直接包裹)/非父子关系(没有关联)
父子关系:props,$emit,
非父子关系:provide& inject,eventbus
1)父传子:通过prop(组件上注册的一些自定义属性)向子组件传递数据,可以传递任意数量和任意类型
代码演示:
<template>
<div class="UserInfo">
<h3>个人信息组件</h3>
<div>姓名:{{ username }}</div>
<div>年龄:{{ age }}</div>
<div>是否单身:{{ isSingle?'是':'否'}}</div>
<div>座驾:{{ car.brand }}</div>
<div>
兴趣爱好:{{ hobby.join('、') }}
</div>
</div>
</template>
<script>
export default {
props:['username','age','isSingle','car','hobby']
}
</script>
<!-- scoped原理:1给当前组件模板所有元素,都会被添加上自定义属性:data-v-hash值,来区分不同组件 -->
<style scoped>
.UserInfo {
width: 300px;
border: 3px solid black;
padding: 20px
}
</style>
props校验:
作用:为组件的prop指定验证要求,不符合要求,控制台提示错误
语法:类型校验,非空校验,默认值,自定义
prop和data:
相同点:都可以给组件提供数据
区别:data的数据是自己的,随便改
Prop的数据是外部的,不能直接改,要遵循单向数据流(父组件的prop一旦更新,数据会自动地影响到子组件地变化,通过渲染,视图内容进一步变化。)
修改:Mutation
子组件不能直接修改父组件传递过来的数据,如果要修改,必须要通知父组件进行修改
父组件v-model简化代码:
2)非父子通信:
①event-bus事件总线进行简易地消息传递
使用步骤:
首先,创建一个都能访问到的事件总线
const Bus = new Vue()
export default Bus
紧接着,A组件(接收方)创建监听Bus实例的事件
created () {
Bus.$on('sendMsg',(msg) = > {
this,msg = msg
})
}
最后,B组件(发送方)触发Bus实例的事件
Bus.$emit('sendMsg','这是一则消息')
②provide&inject
实现跨层级共享数据:
(4)Vue异步更新:$nextTick
需求:编辑标题,编辑框自动聚焦
1点击编辑:显示编辑框
2让编辑框立刻获取焦点
问题:显示之后,立刻获取焦点是不能成功的!原因:vue是异步更新DOM(提升性能)
怎么知道DOM什么时候更新完?
$nextTick:等DOM更新完后,才会触发执行此方法里的函数体
语法:
this.$nextTick(函数体)
一旦DOM更新完,立刻执行函数体中的函数
补充一点内容:
组件存放目录问题:
组件分类:页面组件(放在views下面,将来要配合路由使用)/复用组件(页面里面的,展示数据,常用于复用)
本质都是.vue组件
分类存在的核心目标:更易维护
(5)自定义指令:
自己定义的指令,可以封装一些dom操作,扩展额外功能。
①内置指令:v-html,v-model,v-for
②自定义指令:v-focus,v-loading,v-lazy
指令可以传值:
通过binding.value可以拿到指令的值,指令值修改会触发.update函数
Inserted钩子函数:提供的是元素被添加到页面中时的逻辑
Update钩子函数:指令的值修改的时候触发,提供值变化后,dom更新的逻辑
指令值的语法:
封装v-loading
场景:发送请求需要时间,在请求的数据未回来时,页面会处于空白状态,用户体验不好
实现:加载中的效果
插槽:
作用:让组件内部的一些结构支持自定义
问题:组件的内容部分,不希望写死,希望能够使用的时候自定义,怎么办?
语法:
1)先在组件内使用slot占位
2)使用组件时,传入具体标签内容插入
代码演示:
后备内容:
(1)封装组件时,可以为预留的<slot>插槽提供后备内容(默认内容)
语法:
在slot标签内,放置内容,作为默认显示内容
效果:
外部使用组件,不传东西,则slot会显示后备内容
<MyDialog></MyDialog>
外部使用组件,传东西了,则slot会整体被换掉
<MyDialog>我是内容</MyDialog>
具名插槽
需求:一个组件内有多处结构,需要外部传入标签,进行定制
默认插槽,一个的定制位置
语法:
1)多个slot使用name属性区分名字:
2)template配合v-slot:名字来分发对应的标签
v-slot:插槽名=#插槽名
作用域插槽
定义slot插槽的同时,是可以传值的,给插槽上可以绑定数据,将来使用组件时可以用
场景:封装表格组件
1父传子,动态渲染表格内容
2利用默认插槽,定制操作列
3删除或查看都需要用到当前项的id,属于组件内部的数据,通过作用域插槽来传值绑定
基本使用步骤:
1给slot标签,以添加属性的方式传值
2所有添加的属性,都会被收集到一个对象中
3在template中,通过 接收,默认插槽名为default
(6)单页面应用程序与多页面应用程序:
单页(所有的功能在一个html上实现):系统类网站,内部网站,文档类网站,移动端站点
优缺点:优点:按需更新性能高,开发效率高,用户体验好(原因:页面按需更新,要明确访问路径和组件的对应关系,如何确定?路由)
缺点:学习成本,首屏加载速度慢,不利于SEO
多页:公司官网,电商类网站(要考虑加载速度)
八、路由
1定义:路径和组件的映射关系(不同路径应该对应渲染哪个组件)
2VueRouter的介绍:
修改地址栏路径时,切换显示匹配的组件
是VUE官方的一个路由组件,是一个第三方包
官网:https://v3.router.vuejs.org/zh/
基本使用步骤:详见官网
3.2个核心步骤:
(1)创建需要的组件(views目录),配置路由规则
(2)配置导航,配置路由出口(路径匹配的组件显示的位置)
4添加高亮效果:
Vue-router提供了一个全局组件router-link(取代a标签)
特点:
1将a标签替换成router-link, href换成to,去掉#(可以跳转)
router-link(声明式导航)怎么用?
router-link的作用:
能跳转,能高亮
5声明式导航
(1)跳转传参
语法:
(2)动态路由传参:
1)配置动态路由:
2)配置导航链接
3)对应页面组件接收传递过来的值
两种传参方式的区别:
6编程式导航-基本跳转
使用js代码进行跳转
(1)path路径跳转
this.$router.push('路由路径')
或者
this.$router.push({
push:'路由路径'
})
(2)name命名路由跳转(适合path路径长):
this.$router.push({
name:'路由名'
})
路由跳转传参:
两种传参:查询参数+动态路由传参
两种跳转方式,对于两种传参方式都支持
1)path路径跳转传参
2)name命名路由跳转传参
3)path路径跳转传参
比较:
路径简单,参数多;用path
路径复杂,参数少:用name
7Vue路由
(1)重定向:
网页打开,url默认是/路径,未匹配到组件时,会出现空白
重定向:匹配path后,强制调整path路径
语法:
{path:匹配路径,redirect:重定向到的路径}
(2)-404:
作用:当路径找不到匹配时,给个提示页面
语法:path:”*“(任意路径)
(3)模式设置
问题:路由的路径看起来不自然,有#,能否切成真正的路径形式?
可以,
hash路由:(默认),有#
history路由:(常用),无#
需要注意的是,一旦采用了history模式,地址栏就没有#了,需要后台配置访问规则
(4)嵌套的路由配置
通过children配置项来配置
九、自定义项目创建
1以下是基于vue2创建的一个自定义项目的整个流程
2.ESlint代码规范:
(1)约定规则:如运算符的左右两侧需要加空格
网址贴在这里:
规则的一部分:
(2)自动修复错误(高亮):
1)安装插件:ESlint
2)vscode左下角设置,右上角打开设置,在settings.json中添加如下代码:
// 当保存的时候,eslint自动修复错误
"editor.tabSize": 2,
"editor.codeActionsOnSave": {
"source.fixAll": true
},
// 保存代码,不自动格式化
"editor.formatOnSave": false
3.vuex
(1)介绍:
是一个vue的状态管理工具,状态就是数据
是一个插件,可以帮我们管理通用的数据(多组件共享的数据)
优势:
共同维护一份数据(数据集中化管理)
响应式变化
操作简洁(提供了一些辅助函数)
管理通用数据的插件
(2)基于脚手架构建vuex的环境:
创建流程:
(3)创建空仓库
安装vuex插件,初始化一个空仓库:
版本安装原则:233,344
安装好包之后,src目录下新建store,新建index,js文件,专门存放vuex相关的核心代码
代码
创建仓库:
在Main.js中挂载:
验证仓库是否创建并导入成功?
在控制台打印this.$store
由于我在安装vuex的过程中也遇到了很多问题,鉴于内容比较丰富,详细的安装流程下期单独介绍
(4)仓库创建好之后,怎么提供数据?
使用state状态
State:所有共享数据都要统一放到Store中的state中,在state对象中可以添加我们要共享的数据
data也提供的是数据,但data里面提供的自己的数据
怎么使用?
仓库里的数据在哪里都能访问得到(所有组件共享数据)
计算属性:如果在computed中创建了计算属性,在页面的哪个位置使用,直接写上对应的计算属性的名称即可。
但是,存在的问题是:如果要想使用该计算属性的话,需要在要使用的页面中都要写,显然是不合理的,怎样解决这个问题呢?可以采用vuex提供的辅助函数mapStete来处理,它可以帮助我们把store中的数据自动的映射到组件的计算属性中。
怎么使用?
先导入:
import { mapState } from 'vuex'
再渲染:
Vuex同样遵循单向数据流,组件中不能直接修改仓库中的数据,如果要修改获取到的数据,需要使用mutations
具体怎么修改?
1定义mutations属性:(store-index.js)
2组件中提交调用mutations(组件,vue)
mutations传参语法:
1提供mutations函数:
2页面中提交调用mutation
注意:mutations只能有一个参数,如果要传多个参数的化,需要封装成对象,调用的时候也是调用对象
(5)辅助函数
mapMutations
与mapState很像,它是把位于mutations中的方法提取出来,映射到组件methods中,它俩的区别在于,mapState映射状态,Mapmutations映射方法
mapActions
由于mutations必须是同步的,(便于监测数据变化,记录调试),如果要处理异步操作,需要使用actions
怎么使用?
首先,提供actions方法
actions : {
setAsyncCount (context num) {
setTimeout(()=> {
context.commit('changeCount',num)
},1000)
}
}
context相当于store
num相当于传递的参数
然后,在页面中调用
this.$store.dispatch('setAsyncCount',200)
actions函数的辅助函数mapActions
同理,它是把位于actions中的方法提取出来,映射到组件methods中
定义与调用
getters:
从state中派生出的一些状态,是依赖state的,此时就需要用到getters
例如,在state中定义了list,,为1-10的数组,在组件中,需要显示所有>5的数据
可以这样写:
state :{
list:[1,2,3,4,5,6,7,8,9,10]
}
首先,定义getters,
getters:{
filterList(state) {
return state.list.filter(item = >item > 5)
}
}
其次,访问getters
(1)通过store访问getters:
{{$store.getters.filterList}}
(2)通过辅助函数mapGetters映射
MapMutations和mapActions都是在映射方法,调用时需要写在methods中
而mapState和mapGetters都是在映射属性,调用时需要写在computed中
(6)modules模块
使用场景:
由于vuex使用单一状态树,应用的所有状态会集中到一个比较大的对象,当应用变得非常复杂时,store对象就有可能变得很臃肿,项目越来越大的时候,vuex会变得难以维护,此时就需要使用Modules进行模块拆分。
使用:先导入,后挂载
1)怎么访问模块中的state
直接通过模块名访问;
$store.state.模块名.xxx
通过mapState访问
默认跟级别的映射:
mapState([‘xxx])
子模块的映射:(需要开启命名空间)
mapState(‘模块名’,[‘xxx])
2)怎么访问模块中的getters:
3)怎么访问模块中的mutations
3)怎么访问模块中的actions
vue3
一、引入
1Vue3是vue2的延伸与优化
2与vue2相比,具有四大优势
更容易维护:组合式API,更好的TypeScript支持
更快的速度:重写diff算法,模板编译优化,更高效的组件初始化
更小的体积:良好的TreeShaking,按需引入
更优的数据响应式:proxy
3vue2:提供选项式api
vue3:提供组合式api,将某个属性计算的方法和数据全部提供,可维护性强,集中式管理,代码可复用性强
二、创建vue3项目
1环境条件:
已安装16.0或更高版本的node.js(查看node.js版本:node -v)
以下是我的node版本
2然后,根据提示操作即可(以下是我创建整个项目的流程,部分配置项可以根据自己的需求选择)
3启动项目:
4浏览器界面显示:
5生成的项目目录结构如下:
其中,Vite.config.js放置项目配置文件,Index.html:提供挂载
与vue2的不同之处:
从此前所学的vue2相关的知识对比上述代码,我们不难发现,
(1)整个页面的script挪到了template的上面,结构和样式放到一起更易于维护,与此同时,script加上了set up 允许在script中直接编写组合式API
(2)组件不需要注册了,导入之后直接就可以使用
(3)template中允许有多个根元素了
6组合式API-set up选项
写法和执行时机:
执行时机:
app.vue代码:
<script setup>
import HelloWorld from './components/HelloWorld.vue'
import TheWelcome from './components/TheWelcome.vue'
</script>
<template>
<header>
<img alt="Vue logo" class="logo" src="./assets/logo.svg" width="125" height="125" />
<div class="wrapper">
<HelloWorld msg="You did it!" />
</div>
</header>
<main>
<TheWelcome />
</main>
</template>
<style scoped>
header {
line-height: 1.5;
}
.logo {
display: block;
margin: 0 auto 2rem;
}
@media (min-width: 1024px) {
header {
display: flex;
place-items: center;
padding-right: calc(var(--section-gap) / 2);
}
.logo {
margin: 0 2rem 0 0;
}
header .wrapper {
display: flex;
place-items: flex-start;
flex-wrap: wrap;
}
}
</style>
7比较vue2和vue3的写法:
(1)vue2
(2)vue3
8set up 底层原理:
封装了一个函数,return出结果:
set up写代码的特点:定义数据+函数,以对象方式return
执行时机在beforeCreate之前,自动执行
9常用的函数:
(1)reactive函数:
接受对象类型的参数传入,并返回一个响应式的对象
核心步骤:
(2)ref()函数:
接收简单类型或复杂类型,返回响应式的对象
核心步骤:
(3)computed计算属性函数
核心步骤:
需要注意的是,其一,计算属性中不应该有副作用,比如异步请求,修改dom等;其二,避免直接修改计算属性的值
9组合式api-watch
作用:监听一个或多个数据的变化,数据变化时执行回调函数
单个数据:
多个数据:
10deep:深度监视
默认情况下,watch实现的是浅层监视,如果传入的是复杂类型,是监视不到的,此时,就需要添加额外的属性。
在不开启deep的前提下,侦听age的变化,只有age变化时才执行回调
11生命周期函数
12父子组件之间的通信:
基本思想:父组件给子组件绑定属性
子组件内部通过props选项接收
父传子:
父亲:
儿子:
子传父:
通过emit实现监听
13模板引用:
通过ref标识获取真实的dom对象或者组件实例对象
在vue3中如何使用?
1调用ref函数生成一个ref对象
2通过ref标识绑定ref对象到标签
默认情况下,在script setup 语法糖下组件内部的属性和方法式不开放给父组件的。需要通过defineExpose编译宏指定哪些属性和方法允许使用
14provide和inject
作用:顶层组件向任意的底层组件传递数据和方法,实现跨层组件通信
语法:
顶层组件:
底层组件:
15.defineOptions
16defineModel
在vue2中,v-model是value和input的组合
在vue3中,v-model:Modelvlaue和@update:Modelvaluei的简写
17pinia
是vue最新的状态管理工具,是vuex的替代品(vue3官网,生态系统)
与vuex相比的优势:
使用:
先安装,后挂载
action异步实现:
接口地址:
步骤:
1安装axios
2导入‘
3使用
pinia持久化插件
至此,vue2和vue3的基础知识全部分享完毕,从下期文章开始,将以实战项目为出发点,通过从项目搭建到实现的整个流程来对所学的知识进行应用和实践(预计春节前后会更新完毕),敬请期待吧~另外,本文如有不足之处,欢迎各位大佬批评指正,下期见!