目录
(4) 函数式组件: functional + render + JSX
新建项目
安装vue npm install -g @vue/cli
新建项目 vue create 项目名
项目配置
(1)运行项目自动浏览器打开
package.json
"scripts": {
"serve": "vue-cli-service serve --open",//自动打开
"build": "vue-cli-service build",
"lint": "vue-cli-service lint"
},
(2)关闭eslint校验
vue.config.js
const { defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({
transpileDependencies: true,
lintOnSave:false,//关闭校验
})
项目结构
node_modules(项目依赖)
public(静态资源)
src(源代码)
|---assets(静态资源)
|---components(全局组件)
|---views/pages(路由组件)
|---router(路由)
|---app.vue(单页面/首页)
|---main.js(入口文件)
main.js
app.vue
组件
组件: 具有特定功能效果的集合(html,css,js)
普通组件: .vue文件定义的组件
全局公共组件: Vue.component('组件的名字',组件对象)
路由组件:首先是一个组件,在路由中和路径一起进行注册.
异步组件:通过import动态引入的组件,页面中使用该组件的时候按需引入
函数组件:无状态,是通过函数的方式来定义的一个组件
递归组件:组件中必须有name属性,组件内部调用组件自己
动态组件:动态产生的组件(做tab栏切换效果)
缓存组件:使用keep-alive包裹的组件
路由:是一种映射关系(路径---组件) {path:'路径',component:组件对象}---路由对象
(1) 动态组件
- 通过<component>动态确定要显示的组件, is指定要显示组件的组件名
<component :is="currentComp" />
- 问题: 当从A组件切换到B组件时, A组件就会销毁
(2) 缓存组件
// 使用<keep-alive>缓存动态组件, 可以通过include或exclude指定只缓存特定组件
<keep-alive :exclude="['Home']">
<component :is="currentComp"/>
</keep-alive>
// 使用<keep-alive>也可以缓存路由组件
<keep-alive include="Life1">
<router-view></router-view>
</keep-alive>
- 路由组件对象什么时候创建?
- 默认: 每次跳转/访问对应的路由路径时
- 有缓存: 第一次访问时
- 路由组件对象什么时候死亡?
- 默认: 离开时
- 有缓存: 离开时不死亡, 只有当destroy/父组件死亡/刷新页面
(3) 异步组件
- 好处: 能更快的看到当前需要展现的组件界面(异步组件的代码开始没有加载)
- 无论是**路由组件**还是**非路由组件**都可以实现异步组件效果
- 拆分单独打包
- 需要时才请求加载组件对应的打包文件
- 配置组件: component: () => import(modulePath)
- import(modulePath): 被引入的模块会被单独打包(code split) --ES8的新语法
- () => import(modulePath): 函数开始不调用, 当第一次需要显示对应的界面时才会执行, 请求加载打包文件
- 细节
- import()返回promise, promise成功的结果就是整体模块对象
- 本质上: 可以利用import()实现对任意模块的懒加载
(4) 函数式组件: functional + render + JSX
- 函数组件的特点
- 无状态
- 无法实例化
- 内部没有任何生命周期处理函数
- 轻量,渲染性能高,适合只依赖于外部数据传递而变化的组件(展示组件,无逻辑和状态修改)
- 可以没有根标签
- 编码
export default {
functional: true, // 当前是函数组件
render (createElement, context) {
return 要显示界面的虚拟DOM
}
}
(5) 递归组件
- 递归组件: 组件内部有自己的子组件标签
- 应用场景: 用于显示树状态结构的界面
- 注意: 递归组件必须有name
- 编码: 实现一个简单的可开关的树状结构界面的 Tree 组件
生命周期
(1) beforeCreate(){}: 在实例初始化之后调用, data和methods都还没有初始化完成, 通过this不能访问
初始化data与methods/computed
(2) created(){}: 此时data和methods都已初始化完成, 可以通过this去操作, 可以在此发ajax请求
编译模板
(3) beforeMount(){}: 模板已经在内存中编译, 但还没有挂载到页面上, 不能通过ref找到对应的标签对象
插入到界面上显示
(4) mounted(){}: 页面已经初始显示, 可以通过ref找到对应的标签, 也可以选择此时发ajax请求
n次更新数据
(5) beforeUpdate(){}: 在数据更新之后, 界面更新前调用, 只能访问到原有的界面
更新界面
(6) updated(){}: 在界面更新之后调用, 此时可以访问最新的界面
销毁组件/ v-if隐藏/离开不缓存的路由组件
(7) beforeDestroy(){}: 实例销毁之前调用, 此时实例仍然可以正常工作
(8) destroyed(){}: Vue 实例销毁后调用, 实例已经无法正常工作了
(9) deactivated(){}:组件失活, 但没有死亡
(10) activated(){}: 组件激活, 被复用
(11) errorCaptured(){}: 用于捕获子组件的错误,return false可以阻止错误向上冒泡(传递)
路由
(1)Vue框架实现路由的跳转有几种手段?
第一种:声明式导航链接.router-link全局组件(务必书写to)
第二种:编程式导航【VC.$router.push|replace】方法实现
区别:
router-link ->HTML
push|replace -> JS 编程式导航可以额外的进行业务逻辑判断!!!!
(2)vue-router进行路由跳转传递参数,有几种形式?
params参数:算路径当中一部分,query参数不算路径当中一部分
query参数: http://localhost:8080/#/home?a=1&b=2
params参数:http://localhost:8080/#/home/1/2
(3)路由文件配置
// 1.引入vue-router插件
import VueRouter from 'vue-router'
import Vue from 'vue'
// 2.安装插件
Vue.use(VueRouter);
// 3.配置路由并暴露
export default new VueRouter({
// 路由
routes:[
{
// 设置路由路径
path:'/home',
// 匹配路由组件
component:()=>import("@/views/Home.vue"),//路由懒加载
},
{...},
{
// 默认路径
path:'/',
// 重定向的目标路径
redirect:'/home'
}
]
})
(4)引入路由
// 在入口文件(main)内引入路由并注册
import router from '@/router'
new Vue({
// 注册路由,kv一致可简写
// 注册后VC实例上会添加$router/$route属性
router
})
(5)路由模式
hash:
hash模式,路径中带#
history:
历史模式,路径不带#
打包上线时需要后台紧密配合[nginx]
(6)使用路由
声明式导航链接和展示区域都是vue-router提供的
声明式导航链接组件:<router-link to='/home'></router-link>
可以修改k(url路径)
必须要有to属性,设置要跳转的路径
展示区域组件:<router-view></router-view>
路由组件展示的地方,会展示对应路径的路由组件
<div>
<!-- 声明式导航链接 -->
<router-link to='/home'></router-link>
</div>
<!-- 展示区域 -->
<router-view></router-view>
(7)路由嵌套
1.在组件父级路由的<router-view>内创建次级路由的导航链接和展示区域
2.配置路由嵌套
routes:[
{
// 设置路由路径
path:'/home',
// 匹配路由组件
component:()=>import("@/views/Home.vue"),
// 配置子路由
children:[
{
// 全写
// path:'/home/news',
// 简写,直接写子路由路径即可,不用加/
path:'news'
component:()=>import("@/views/Home/News.vue")
}
]
}
]
(8)路由传参
发送数据路由:
导航链接里的to传递query参数
<router-link to='/home?a=1&b=2'></router-link>
导航链接里的to传递params参数
<router-link to='/home/10/张三'></router-link>
params参数需要在配置路由文件内设置动态路由
routes:[
{
// 设置路由路径
path:'/home',
// 匹配路由组件
component:()=>import("@/views/Home.vue"),
// 配置子路由
children:[
{
// 命名路由
name:'news',
// 子路由传递params参数
// 设置后路由跳转时必须要传递params参数
path:'news/:id/:name',
component:()=>import("@/views/Home/News.vue")
}
]
}
]
接收数据路由:
query参数:接收路由组件内通过$route.query获取传递的参数
query:{a=1,b=2}
params参数:接收路由组件内通过$route.params获取传递的参数
params:{id:10,name:'张三'}
(9)编程式导航
编程式导航可以写逻辑
编程式导航任意标签设置事件即可
可以通过VC的$router(路由器),实现路由跳转
VueRouter.prototype原型对象上有push/replace方法,用来实现路由跳转
push:可以记录历史记录
replace:不会记录历史记录
methods:{
add(){
// 事件回调函数内通过VC.$router.push实现query参数的路由跳转
// 模板字符串写法
this.$router.push(`/home/news?id=${item.id}&name=${item.name}`)
// 对象写法[※常用※]
this.$router.push({
// 路由name
name:'news',
// 跳转路径
path:'/home/news',
// 传递query参数
query:{id:item.id,name:item.name},
// 传递params参数
// 使用时不能设置path,要用路由name,否则会报错
params:{id:item.id,name:item.name}
})
}
}
(10)路由元信息
说明:
定义路由时可以配置meta字段,相当于添加的额外数据
meta内可以放多个数据
数据可以在VC的$routes.meta获取
组件内获取:$routes.meta.show
跳转不同的路由可以获取不同的路由数据
routes:[
{
path:'/aaa',
component:Aaa,
meta:{show:true,a:1}
},
{
path:'/bbb',
component:Bbb,
meta:{show:false,a:2}
}
]
(11)keep-alive全局组件/缓存组件
作用:
缓存路由组件,切换路由时不会销毁组件
组件内的数据都会保存住
include:
设定某几个路由缓存,其他路由不缓存
数组内元素为路由组件内的的name
//设定某几个路由缓存,其他路由不缓存,数组内元素为路由组件内的的name
<keep-alive :include='["Home"]'>
<router-view></router-view>
</keep-alive>
(12)切换路由组件
切换时会触发组件的mounted(组件挂载生命周期)
切换路由会销毁旧路由,重新挂载新路由