一、指令
1、内容渲染指令
V-text :会覆盖元素原有内容
V-html:把带标签的字符串渲染成html内容
插值表达式{{}}
2、属性绑定指令
v-bind(简写 :)
3、事件绑定指令
v-on(简写 @)
事件修饰符:
-
.prevent阻止默认行为
-
.stop阻止事件冒泡
* .capture以捕获模式触发当前的事件处理函数 * .once绑定的事件只触发一次 * .self只有在event.target是当前元素自身是触发事件处理函数
vue提供了内置变量 $event:原生DOM的事件对象e
<button @click="add(n,$event)">+{{n}}</button>
4、双向数据绑定
v-model
适用于表单元素,例如:input/textarea/select
修饰符:
- .number自动将用户输入值转为数值类型
- .trim自动过滤用户输入的首尾空白字符
- .lazy在‘change’时而非‘input’时更新
5、条件渲染指令
v-if:动态创建或删除元素,如果初始状态为false不需要被显示,且后期很可能也不需要显示用v-if性能更好。
v-show:动态改变display属性的属性值来隐藏或显示元素,如果要频繁改变元素显示状态用v-show性能更好
6、列表渲染指令
v-for
v-for循环要绑定:key,key的值是字符串或数字且不能重复
二、过滤器
<p>{{message | firstUp}}</p>
过滤器的本质是一个函数,需要渲染的内容作为参数传入过滤器函数,并返回新内容
局部过滤器:
filters: {
firstUp(str) {
const first = str.charAt(0).toUpperCase();
const other = str.slice(1);
return first + other
}
}
全局过滤器:
Vue.filter('dateformat', function (time) {
const y = time.getFullYear();
const m = time.getMonth();
const d = time.getDate();
const h = time.getHours();
const mi = time.getMinutes();
const s = time.getSeconds()
return y + '-' + m + '-' + d + ' ' + h + ':' + mi + ':' + s
})
三、侦听器
watch侦听器:监视数据的变化,从而针对数据的变化做出特定的操作
侦听器的格式:
-
方法格式的侦听器:
缺点1:无法在刚进入页面的时候自动触发
缺点2:如果侦听的是一个对象,如果对象的属性发生了变化不会触发侦听器
-
2、对象格式的侦听器
好处1:可通过immediate选项让侦听器自动触发
好处2:可以通过deep侦听器深度监听对象中每个属性的变化
四、计算属性
const vm = new Vue({
el: '#app',
data: {
r: '0',
g: '0',
b: '0'
},
// 计算属性:计算属性在定义的时候要定义成方法格式
computed: {
rgb() {
return `rgb(${this.r},${this.g},${this.b})`
}
},
methods: {
show() {
console.log(this.rgb)
}
},
})
console.log(vm)
五、axios
axios 是一个专注于网络请求的库
调用axios得到的返回值是promise对象
axios({
//请求方式
method: '',
// 请求地址
url: '',
// url中的查询参数
params:{},
// 请求体参数
data:{}
}).then((result) => {
//.then用来指定请求成功后的回调函数
//形参中的result是请求成功后的结果
})
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LpPJSjL6-1669307327542)(/Users/mac/Desktop/tt.jpg)]
解构赋值
Axios 在请求在请求到数据之后会在真正的数据之外套一层壳
使用解构赋值,从 axios 封装的大对象中,把 data 属性解构出来
把解构出来的 data 属性,使用 冒号 进行重命名,一般都重命名为 { data: res }
const { data: res } = await axios({
})
如果调用某个方法的返回值是 Promise 实例,则前面可以添加 await!
await 只能用在被 async “修饰”的方法中
const { data } = await axios({
})
Axios的请求方式
get请求
获取数据
axios.get('url地址', {
// GET 参数
params: {}
})
post请求
向指定资源提交数据(例如:表单提交或文件上传)
axios.post('url', { /* POST 请求体数据 */ })
//1、formData请求
let data = {}
let formData = new formData()
for(let key in data){
fromData.append(key,data[key])
}
axios.post('url', fromData}).then((res) => {
}
//2、applicition/json请求
let data = {}
axios.post('url', data}).then((res) => {
}
put请求
更新数据
axios.put('url',{
/* put 请求体数据 */
})
patch请求
更新数据,用来对已知资源进行局部更新
axios.patch('url',{
/* patch 请求体数据 */
})
delete请求
请求服务器删除指定的数据
axios.delete('url地址', {
// delete 参数
params: {}
})
axios二次封装
import axios from 'axios'
const http = axios.create({
// `baseURL` 将自动加在 `url` 前面,除非 `url` 是一个绝对 URL。
// 它可以通过设置一个 `baseURL` 便于为 axios 实例的方法传递相对 URL
baseURL:'',
timeout:10000,
})
// 添加请求拦截器
http.interceptors.request.use(function (config) {
// 在发送请求之前做些什么
return config;
}, function (error) {
// 对请求错误做些什么
return Promise.reject(error);
});
// 添加响应拦截器
http.interceptors.response.use(function (response) {
// 2xx 范围内的状态码都会触发该函数。
// 对响应数据做点什么
return response;
}, function (error) {
// 超出 2xx 范围的状态码都会触发该函数。
// 对响应错误做点什么
return Promise.reject(error);
});
export default http
六、生命周期
生命周期
:是指一个组件从创建 -> 运行 -> 销毁的整个阶段,强调的是一个时间段。
生命周期函数
:是由 vue 框架提供的内置函数,会伴随着组件的生命周期,自动按次序执行。
注意:生命周期强调的是时间段,生命周期函数强调的是时间点。
组件生命周期函数的分类
- 组件创建阶段
- beforeCreate
- created
- beforeMount
- mounted
- 组件运行阶段
- beforeUpdate
- updated
- 组件销毁阶段
- beforeDestroy
- destroyed
数据共享
组件之间的关系
父子关系
兄弟关系
子->父共享数据
父组件向子组件共享数据需要使用自定义属性
//父组件
<Son :msg="message"></Son>
data(){
return{
message:''
}
}
//子组件
props:['msg']
子->父共享数据
子组件向父组件共享数据使用自定义事件
//子组件
data() {
return {
// 子组件自己的数据,将来希望把 count 值传给父组件
count: 0,
}
},
methods: {
add() {
// 让子组件的 count 值自增 +1
this.count += 1
// 把自增的结果,传给父组件
this.$emit('numchange', this.count)
}
}
//父组件
<Father @numchange="getNewCount"></Father>
data(){
return{
countFromSon:0
}
},
methods: {
// 获取子组件传递过来的数据
getNewCount(val) {
console.log('numchange 事件被触发了!', val)
this.countFromSon = val
}
},
兄弟组件之间的数据共享EventBus
EventBus 的使用步骤
- 创建 eventBus.js 模块,并向外共享一个 Vue 的实例对象
- 在数据发送方,调用 bus.$emit(‘事件名称’, 要发送的数据) 方法触发自定义事件
- 在数据接收方,调用 bus.$on(‘事件名称’, 事件处理函数) 方法注册一个自定义事件
ref 引用
给元素或组件添加 ref=“xxx” 的引用名称
通过 this.$refs.xxx 获取元素或组件的实例
1、 ref 引用DOM元素
通过this.$refs.引用的名称
可以获取到DOM元素的引用
2、 ref 引用组件实例
通过this.$refs.引用的名称
可以引用组件实例
引用到组件实例后,可以调用组件上的 methods 的方法
3、文本框与按钮的按需切换:
通过布尔值inputVisible
来控制组件中的文本框与按钮的按需切换
4、让文本框自动获得焦点:
当文本框展示出来之后,如果希望它立即获得焦点,则可以为其添加 ref 引用,并调用原生 DOM 对象的.focus() 方法即可
this. n e x t T i c k ( c b ) 组 件 的 ‘ nextTick(cb) 组件的 ` nextTick(cb)组件的‘nextTick(cb) `方法,会把 cb 回调推迟到下一个 DOM 更新周期之后执行
等组件的DOM 更新完成之后,再执行 cb 回调函数。从而能保证 cb 回调函数可以操作到最新的 DOM 元素
动态组件
动态组件指的是动态切换组件的显示与隐藏
组件,专门用来实现动态组件的渲染
组件保持动态组件的状态。
当组件被缓存时,会自动触发组件的 deactivated
生命周期函数。
当组件被激活时,会自动触发组件的 activated
生命周期函数。
keep-alive 的 include 属性
include 属性用来指定:只有名称匹配的组件会被缓存
<keep-alive include="com1,com2">
<component :is="comName"></component>
</keep-alive>
插槽
插槽(Slot)是 vue 为组件的封装者提供的能力。允许开发者在封装组件时,把不确定的、希望由用户指定的部分定义为插槽。
在封装组件时,可以通过 元素定义插槽,从而为用户预留内容占位符
如果在封装组件时没有预留任何 插槽,则用户提供的任何自定义内容都会被丢弃
封装组件时,可以为预留的 插槽提供后备内容(默认内容)。如果组件的使用者没有为插槽提供任何内容,则后备内容会生效。
具名插槽:
如果在封装组件时需要预留多个插槽节点,则需要为每个 插槽指定具体的 name
名称。这种带有具体名称的插槽叫做“具名插槽”。
在向具名插槽提供内容的时候,我们可以在一个 template
元素上使用 v-slot (#)
指令,并以 v-slot 的参数的形式提供其名称。
<slot name="default">
<h6>这是 default 插槽的后备内容</h6>
</slot>
<Left>
<!-- 默认情况下,在使用组件的时候,提供的内容都会被填充到名字为 default 的插槽之中 -->
<template #default>
<p>这是在 Left 组件的内容区域,声明的 p 标签</p>
</template>
<Left>
作用域插槽
在封装组件的过程中,可以为预留的 插槽绑定 props
数据,这种带有 props 数据的 叫做“作用域插槽”
可以使用 v-slot: 的形式,接收作用域插槽对外提供的数据
解构插槽 Prop
作用域插槽对外提供的数据对象,可以使用解构赋值简化数据的接收过程
自定义指令
私有自定义指令 directives: { }
全局自定义指令 Vue.directive()
前端路由
前端路由:Hash 地址
与组件
之间的对应关系
vue-router 的基本使用:
1.创建路由模块
在 src 源代码目录下,新建 router/index.js 路由模块
2、 导入并挂载路由模块
在 src/main.js 入口文件中,导入并挂载路由模块。
import Vue from 'vue'
import App from './App.vue'
// 导入路由模块
import router from '@/router'
Vue.config.productionTip = false
new Vue({
render: h => h(App),
router
}).$mount('#app')
3、 声明路由链接和占位符
在 src/App.vue 组件中,使用 vue-router 提供的 和 声明路由链接和占位符:
4、 声明路由的匹配规则
import Vue from 'vue'
import VueRouter from 'vue-router'
import pathArr from '@/router/pathArr.js'
// 导入需要的组件
import Login from '@/components/MyLogin.vue'
import Home from '@/components/MyHome.vue'
import Users from '@/components/menus/MyUsers.vue'
import Rights from '@/components/menus/MyRights.vue'
import Goods from '@/components/menus/MyGoods.vue'
import Orders from '@/components/menus/MyOrders.vue'
import Settings from '@/components/menus/MySettings.vue'
import UserDetail from '@/components/user/MyUserDetail.vue'
Vue.use(VueRouter)
const router = new VueRouter({
routes: [
{ path: '/', redirect: '/login' },
// 登录的路由规则
{ path: '/login', component: Login },
// 后台主页的路由规则
{
path: '/home',
component: Home,
redirect: '/home/users',
children: [
{ path: 'users', component: Users },
{ path: 'rights', component: Rights },
{ path: 'goods', component: Goods },
{ path: 'orders', component: Orders },
{ path: 'settings', component: Settings },
// 用户详情页的路由规则
{ path: 'userinfo/:id', component: UserDetail, props: true }
]
}
]
})
export default router
vue-router 的常见用法
1. 路由重定向
路由重定向指的是:用户在访问地址 A 的时候,强制用户跳转到地址 C ,从而展示特定的组件页面。
通过路由规则的 redirect
属性,指定一个新的路由地址,可以很方便地设置路由的重定向
2. 嵌套路由
通过路由实现组件的嵌套展示,叫做嵌套路由。
3. 声明子路由链接和子路由占位符
- 通过 children 属性声明子路由规则
4. 动态路由匹配
把 Hash 地址中可变的部分
定义为参数项
,从而提高路由规则的复用性
- 在 vue-router 中使用英文的冒号(
:
)来定义路由的参数项 - 在动态路由渲染出来的组件中,可以使用 this.$route.params 对象访问到动态匹配的参数值
- 使用
props
接收路由参数
{ path: 'userinfo/:id', component: UserDetail, props: true }
5. 声明式导航 & 编程式导航
r o u t e r . p u s h 调 用 ‘ t h i s . router.push 调用` this. router.push调用‘this.router.push() `方法,可以跳转到指定的 hash 地址,从而展示对应的组件页面。
r o u t e r . r e p l a c e 调 用 ‘ t h i s . router.replace 调用 `this. router.replace调用‘this.router.replace() `方法,可以跳转到指定的 hash 地址,从而展示对应的组件页面
push 和 replace 的区别:
- push 会增加一条历史记录
- eplace 不会增加历史记录,而是
替换掉当前的历史记录
$router.go
调用this.$router.go()
方法,可以在浏览历史中前进和后退
$router.back()
在历史记录中,后退到上一个页面$router.forward()
在历史记录中,前进到下一个页面
6. 导航守卫
导航守卫可以控制路由的访问权限
。
全局前置守卫
每次发生路由的导航跳转
时,都会触发全局前置守卫
。因此,在全局前置守卫中,程序员可以对每个路由进行访问权限的控制
:
// 全局前置守卫
router.beforeEach(function(to, from, next) {
// to是将要访问的路由的信息对象
// form 将要离开的路由的信息对象
// next 是一个函数,调用next(),表示放行,允许这次路由导航
if (pathArr.indexOf(to.path) !== -1) {
const token = localStorage.getItem('token')
if (token) {
next()
} else {
next('/login')
}
} else {
next()
}
})