vue最新笔记
文章目录
vue特性
数据驱动视图
1、使用了vue页面中,vue会监听数据的变化,从而自动重新渲染画面
2、数据驱动视图是单向
双向数据绑定
开发者不再需要手动操作DOM元素,来获取表单元素最新的值
注意:数据驱动视图和双向数据绑定的底层原理是MVVM(model数据源、View视图、ViewModel就是vue的实例
vue指令
1、内容渲染指令
1、v-text指令缺点:会把原来的内容覆盖
2、{{}}插值表达式:在实际开发中用的最多,只是内容的占位符,不会覆盖掉原来的内容
3、v-html 指令的作用:可以把带有标签的字符串,渲染成真正的html内容
2、属性绑定指令
注意:插值表达式只能用在元素的内容节点中,不能用在元素的属性节点中
在vue中,可以使用v-bind指令,为元素的属性动态绑定值
vue规定 v-bind 指令可以简写成冒号
在使用v-bind属性绑定期间,如果绑定内容需要动态拼接,则字符串的外面应该是包裹单引号,例如:
<div :title="'box'+ index">zheshi</div>
事件绑定
1、v-on:简写为@
2、语法格式为
<button @click="add"></button>
muthods: {
add() {
//如果在方法中要修改data中的数值,可以通过this访问到
this.count += 1
}
}
3、&event的应用场景:如果默认事件e被覆盖了,则可以手动传递一个&event
<button @click="add(3,&event)"></button>
muthods: {
add(n,e) {
//如果在方法中要修改data中的数值,可以通过this访问到
this.count += 1
}
}
5、事件修饰符
例如:
<button @click.stop="btnHandle">按钮</button>
@click.prevent 阻止跳转
@click.stop 组织冒泡
v-model指令
1、input输入框
2、textarea
3、select
v-model指令的修饰符
1、 .number 自动将用户的输入值转换为数值类型
<input type="text" v-model.number="n1">
2、 .trim 自动过滤用户输入的首尾空白字符
<input type="text" v-model.trim="username">
3、 .lazy 在change时更新而非在input时更新
<input type="text" v-model.lazy="username">
条件渲染指令
1、v-show的原理是:动态为元素添加或移除display:none样式来实现元素的显示和隐藏
如果要频繁的切换元素的显示状态,用v-show性能会更好一些
2、v-if的原理是:每次动态创建或移除元素,来实现元素的显示和隐藏
如果刚进入页面的时候,某些元素默认不需要被展示,而且后续这个元素很可能也不需要被展示的元素就用v-if
过滤器
过滤器的注意点
1、要定义在filters的节点下,本质是一个函数
2、在过滤器函数中,要有return值
3、在过滤器的形参中,就可以获取到“管道符”前面待处理的值
4、如果全局过滤器和私有过滤器名字一致,此时按照“就近原则”,调用私有过滤器
watch侦听器
侦听器的格式
1、方法格式的侦听器
缺点1:无法在刚进入页面的时候,自动触发
缺点2:如果侦听的是一个对象,如果对象中的属性发生了变化,不会触发侦听器
2、对象格式的侦听器
好处1:可以通过immediate选项,让侦听器自动触发
好处2:可以通过deep选项,可以让侦听器深度侦听对象中每一个属性变化
计算属性
特点
1、定义的时候,要被定义为方法
2、在使用计算属性的时候,当普通的属性使用即可
好处
1、实现了代码的复用
2、只要计算属性中以来的数据源变化了,则计算属性会重新求值
axios
!!axios是一个专注于网络请求的库
axios的基本使用
1、调用axios的返回值是promise对象
params对应的是get
data对应的是post
解构赋值的时候,使用:进行重命名
//1、调用axios之后,使用async进行重命名
//2、使用解构赋值,从axios封装的大对象中,把data属性结构出来
//3、把解构出来的data属性,使用:进行重命名
发起get请求
document.querySelector('#btnGet').addEventListener('click', async function () {
//解构赋值的时候,使用:进行重命名
//1、调用axios之后,使用async进行重命名
//2、使用解构赋值,从axios封装的大对象中,把data属性结构出来
//3、把解构出来的data属性,使用:进行重命名
const { data: res } = await axios({
method: 'GET',
url: 'http://www.liulongbin.top:3006/api/getbooks',
})
console.log(res.data)
})
使用axios以后,得到的是一个promise,只是一层壳,需要用到解构赋值进行重命名
发起post请求
document.querySelector('#btnPost').addEventListener('click', async function () {
//如果某个方法的返回值是promise实例,则前面可以添加await
//await只能用在被async“修饰”的方法中
const result = await axios({
method: 'POST',
url: 'http://www.liulongbin.top:3006/api/post',
data: {
name: 'zs',
age: 20,
}
})
console.log(result)
})
vue-cli
1、在终端运行如下的命令,创建指定名称的项目:
vue create 项目的名称
2、vue项目中src目录的构成
assets 文件夹:存放项目中用到的静态资源文件,例如css样式表
components文件夹:程序员封装的,可复用的组件,都要放进里面
main.js是项目的入口文件。整个项目的运行,要先执行main.js
app.vue是项目的根组件
vue组件的三大组成部分
1、template 组件的模板结构
2、script 组件的javascript行为
3、style 组件的
私有组件
components之中的组件为私有组件,私有组件不会应用在全局中,每次都需要引用
全局组件
在main.js中注册,可以在任何组件中被引用
//导入需要被全局注册的那个组件
import Count from '@/components/Count.vue'
Vue.component('MyCount', Count)
组件的props
props是组件的自定义属性,在封装通用组件的时候,合理使用props可以极大的提高组件的复用性
//props 是自定义属性,允许使用者通过自定义属性,为当前组件指定初始值
props:['init'],
<MyCount init="9"></MyCount>
props中的值是只读的,不要直接修改props中的值,否则终端会报错
当使用第三方组件库的时候,如果有修改第三方组件默认样式的需求,需要用到/deep/
生命周期
created生命周期函数,在里面调用methods方法,请求服务器数据,并且把请求到的数据,转存到打他中,供template模板渲染时使用
但是created生命周期函数期间不可以操作dom,因为组件的模板结构尚未生成
EventBus的使用步骤
1、创建eventBus.js模块,并且向外共享一个Vue的实例对象
import Vue from 'vue'
export default new Vue()
2、在数据的发送方,调用bus.$emit(‘事件名称’,要发送到数据)方法触发自定义事件
bus.$emit("share", this.str);
3、在数据接收方,调用bus.$on(‘事件名称’,事件处理函数)方法注册一个自定义事件
this.$emit("numchange", this.count);
父向子传值
需要使用自定义属性
第一步:没注册子组件的需要注册子组件
{父组件中导入后在components中声明子组件}
第二步: 引用,例如
<Left :num="count"></Left>
num是子组件接受的 count是父组件传递的数据
第三步:在子组件中的props声明count
子向父传值(需要自己向父组件汇报)
需要使用**自定义事件 **和 $emit
首先定义一个方法
<button @click="add">anniu</button>
点击后在方法中进行事件发射即$emit
add() {
this.count += 2;
this.$emit("countChange", this.count);
},
在父组件中的子组件模块引用事件绑定
<Right @countChange="getCount"></Right>
@子组件发射的事件名="任意起名"
在methods方法中接收值(里面的val就是传过来的值)
getCount(val) {
this.getnewcount = val;
},
动态组件
keep-alive可以把内部的组件经行缓存,而不是进行销毁组件
keep-alive里面包含component 可以保持里面的组件不被销毁
keep-alive里面,利用include属性来指定:只有名称匹配的组件会被缓存;还可以利用exclude属性来指定谁不被缓存
但是:不可以同时使用两个属性
插槽
v-slot简写为#
声明一个插槽,vue官方规定,每一个slot插槽,都需要一个name
如果省略了slot的name属性,则有一个默认的名称叫default
如果需要把内容填充到指定名字的插槽中去,则需要使用v-slot:default
但是这个只能在template中使用,这个template只起包裹作用
自定义函数
私有自定义指令
在directives中定义函数,但是要注意第一次调用和以后多以次调用触发的函数
directives: {
//定义名字为color的指令,指向一个配置对象
color: {
//当指令第一次被绑定到元素上的时候,会立刻触发bind元素
//形参中的el表示当前指令所绑定到的那个DOM对象
//注意是第一次
bind(el, binding) {
el.style.color = binding.value;
},
//每次DOM更新时被调用
update(el, binding) {
el.style.color = binding.value;
},
},
},
路由
概念:hash地址和组件之间对应关系
使用:
1、放链接
2、放占位符
3、创建组件
4、在路径src/router/index.js声明组件,并在
//创建路由的实例对象
const router = new VueRouter({
//routes是一个数组,定义hash地址与组件之间的对应关系
routes:[
{path:'/home',component:Home},
{path:'/movie',component:Movie},
{path:'/about',component:About}
]
})
声明关系
router-link组件,可替代a链接
<!-- 当安装和配置了vue-router以后,就可以使用router-link来代替普通的a链接 不用写#-->
<router-link to="/home">首页</router-link>
<router-link to="/movie">电影</router-link>
<router-link to="/about">关于</router-link>
路由嵌套
通过children属性来声明子路由规则
{path:'/about',component:About,
children:[
{path:'tab1',component:tab1},
{path:'tab2',component:tab2}
]
}
动态路由
{path:'/movie/:id',component:Movie},
<router-link to="/movie/1">洛基</router-link>
<router-link to="/movie/2">雷神</router-link>
<router-link to="/movie/3">复联</router-link>
注意1:在哈希地址中,/后面的参数项叫做“路径参数”
在路由参数对象中,需要使用this.$route.params来访为路径参数
注意2:在hash地址中,?后面的参数项叫做“查询参数”
在路由参数对象中,需要使用this.$route.query来访为路径参数
注意3:在this.$route中,path知识路径部分,fullpath是完整的地址
声明式导航&编程式导航
在浏览器中,点击链接实现导航的方式叫做声明式导航
如链接,链接
调用API方法实现导航的方式,叫做编程式导航
通过导航API跳转到指定页面
1、 this.$router.push(‘/movie/1’)
跳转到指定的hash地址,并增加一条历史记录
2、this.$router.replace(‘/movie/1’)
跳转到指定的hash地址,并替换掉当前的历史纪录
3、//go(-1)表后退一层
//如果后退超过上限则原地不动
this.$router.go(-1)
this.$router.go()的简化
<button @click=“$router.back()”>back
<button @click=“$router.forward()”>forward
导航守卫
可以控制路由的访问权限
//为router实例对象,声明全局前置导航守卫
//只要发生了路由的跳转,必然会触发beforeEach
router.beforeEach((to,from,next)=>{
//to表示将要打印的路由的信息
//from表示将要离开的路由的对象
//next()表示放行的意思
next()
})
控制权限小测试
//为router实例对象,声明全局前置导航守卫
//只要发生了路由的跳转,必然会触发beforeEach
router.beforeEach((to,from,next)=>{
//to表示将要打印的路由的信息
//from表示将要离开的路由的对象
//next()表示放行的意思
//分析
//1、要拿到用户需要访问的hash地址
//2、判断hash地址是否等于/main
//2.1、如果等于,证明需要登录以后才能访问成功
//2.2、如果不等于,则不需要登录,直接放行next()
//3、如果访问的地址是/main,则需要读取localStorage中的token值
//3.1、如果有token,则直接放行
//3.2、如果没有token,则强制跳转到/logom登录页面
if(to.path === '/main') {
//需要访问后台主页,需要判断是否有token
const token = localStorage.getItem('token')
if(token) {
next()
}else {
//没登陆,强行跳转登录页面
next('/login')
}
}else{
next()
}
})
拦截器
导入
import { Loading } from 'element-ui'
后声明一个变量来存储loading实例
let loadingInstance = null
// 配置请求拦截器
let loadingInstance = null // eslint-disable-line no-unused-vars
axios.interceptors.request.use(config => {
loadingInstance = Loading.service({ fullscreen: true })
// 配置一个token
config.headers.Authorization = 'Bearer xxx'
// 这是固定写法
return config
})
// 配置相应拦截器
axios.interceptors.response.use(response => {
// 关闭loading效果
loadingInstance.close()
return response
})