侦听器、计算属性、vue-cli、vue组件
过滤器
处理数据
过滤器的注意点
- 一定要定义在filters下面,它本质上是一个函数。
- 在过滤器函数中,一定要有返回值
- 在过滤器的形参中,val代表管道符的值,可以使用它。
- 如果全局过滤器和私有过滤器名字一致,按照就近原则。
- 过滤器本质上是JavaScript函数,因此可以传参。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>2过滤器的基本使用</title>
<script src="/vue-study/study2/lib/vue-2.6.12.js"></script>
</head>
<body>
<div id="app">
<p>{{ messgae | capi }}</p>
</div>
<script>
const vm = new Vue({
el: "#app",
data: {
messgae: "hello vue",
},
methods: {},
// 过滤器函数必须被定义到filters中
// 过滤器本质上是一个函数
filters:{
// 过滤器函数,形参val永远都是管道符前面的哪个值
capi(val){
// 需要有返回值
// charAt 接受索引值,从字符串中把索引对应的字符获取出来
// toUpperCase()转成大写
const first = val.charAt(0).toUpperCase();
const other = val.slice(1) //slice()索引为一的一直截取到最后
return first+other;
}
}
});
</script>
</body>
</html>
通常情况在filters中定义的是私有过滤器,那么如何定义全局过滤器呢!
// 定义全局过滤器
Vue.filter("capi2", function (str) {
const first = str.charAt(0).toUpperCase();
const second = str.slice(1);
return first + second;
});
格式化时间,使用全局过滤器实现,调用现有的库dayjs。
// 声明格式化时间的全局过滤器
Vue.filter('dateFormat', function(time){
// 对时间处理格式化成 YYYY-MM-DD HH:mm:ss\
// 这里调用的dayjs的库,方便快捷。
timeReturn = dayjs(time).format('YYYY-MM-DD HH:mm:ss');
return timeReturn;
});
watch 侦听器
数据变换,需要监听到。
侦听器的格式
- 方法格式的侦听器
- 缺点1: 无法在刚进入页面的时候,自动触发!
- 缺点2: 如歌侦听的是一个对象,如果对象中的属性发生了变化,不会触发侦听器!
- 对象格式的侦听器
- 好处1:可以通过immediate选项没让侦听器自动触发!
- 好处2:可以通过deep选项,让监听器深度监听对象中每个属性的变化!
代码1:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<script src="/vue-study/study2/lib/vue-2.6.12.js"></script>
<title>3watch监听器</title>
</head>
<body>
<div id="app">
<input type="text" v-model="username">
</div>
<script>
const vm = new Vue({
el: "#app",
data: {
username: "dongdong",
},
methods: {},
filters: {},
// 所有监听器都在watch下面
watch: {
// 判断用户名是否占用可以使用监听器
// 监听器本质上也是一个函数,需要绑定数据名
// newVal, oldVal是固定的选项 。新值和旧值。
// username(newVal, oldVal){
// console.log(newVal, oldVal);
// }
//定义对象格式的侦听器
username:{
handler( newVal, oldVal) {
console.log(newVal+oldVal)
},
immediate: true // true 自动复发
},
},
});
</script>
</body>
</html>
代码2:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<script src="/vue-study/study2/lib/vue-2.6.12.js"></script>
<title>4深度侦听</title>
</head>
<body>
<div id="app">
<input type="text" v-model="info.username" /><hr>
<input type="text" v-model="info.area.city" />
</div>
<script>
const vm = new Vue({
el: "#app",
data() {
return {
// 用户的信息对象
info: {
username: "dongdong ",
area:{
city:"兴化"
}
},
};
},
methods: {},
filters: {},
watch: {
// 监听对象的子属性
'info.area.city'(newVal){
console.log(newVal);
},
//监听整个对象
info: {
handler(newVal) {
console.log(newVal);
},
// 开启深度监听
deep: true,
},
},
});
</script>
</body>
</html>
计算属性
计算属性是通过一系列运算后,最终得到一个属性值。
特点:
- 定义的时候要定义成方法
- 在使用计算属性的时候,当成普通属性去使用。
好处:
3. 实现了代码的复用
4. 只要计算属性中依赖的数据源变化了,计算属性会重新求值。
代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Document</title>
<script src="./lib/vue-2.6.12.js"></script>
<style>
.box {
width: 200px;
height: 200px;
border: 1px solid #ccc;
}
</style>
</head>
<body>
<div id="app">
<div>
<span>R:</span>
<input type="text" v-model.number="r" />
</div>
<div>
<span>G:</span>
<input type="text" v-model.number="g" />
</div>
<div>
<span>B:</span>
<input type="text" v-model.number="b" />
</div>
<hr />
<!-- 专门用户呈现颜色的 div 盒子 -->
<div class="box" :style="{ backgroundColor: rgb }">
{{ rgb }}
</div>
<button @click="show">按钮</button>
</div>
<script>
// 创建 Vue 实例,得到 ViewModel
var vm = new Vue({
el: "#app",
data: {
// 红色
r: 0,
// 绿色
g: 0,
// 蓝色
b: 0,
},
methods: {
// 点击按钮,在终端显示最新的颜色
show() {
console.log(this.rgb);
},
},
// 所有计算属性都要放到computed中 计算属性都要是方法.
computed:{
rgb(){
return `rgb(${this.r},${this.g},${this.b})`
}
}
});
</script>
</body>
</html>
axios
axios是专注于网络请求的一个库。
axios的基本使用
原生
- 发起get请求
axios({
// 请求方法
method: "GET",
// 地址
url: "http://www.liulongbin.top:3006/api/getbooks",
// url查询参数
params:{
id:1
},
// 请求体参数 post
data:{}
}).then(function (result) {
console.log(result);
});
- 发起post请求
如果调用某个方法的返回值是Promise实例,则前面可以添加await
await 只能用在async修饰得到方法中
结构赋值的时候,使用 : 进行重命名
1.调用axios之后使用async和await进行简化
2.使用解构赋值,从axios封装的大对象中,把data属性解构出来
3.把结构出来的data属性,使用冒号进行重命,一般都为{data:res}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<script src="./lib/vue-2.6.12.js"></script>
<script src="./lib/axios.js"></script>
<title>8axios发起post请求</title>
</head>
<body>
<button id="postInfo">发起post请求</button>
<button id="getInfo">发起get请求</button>
<script>
document.querySelector("#postInfo").addEventListener('click', async function () {
// 如果调用某个方法的返回值是Promise实例,则前面可以添加await
// await 只能用在async修饰得到方法中
const {data} = await axios({
method: "POST",
url: "http://www.liulongbin.top:3006/api/post",
data: {
name:'shen',
age:20
},
})
console.log(data);
});
document.querySelector("#getInfo").addEventListener('click', async function(){
// 结构赋值的时候,使用 : 进行重命名
// 1.调用axios之后使用async和await进行简化
// 2.使用解构赋值,从axios封装的大对象中,把data属性解构出来
// 3.把结构出来的data属性,使用冒号进行重命,一般都为{data:res}
const {data:res} = await axios({
method:"GET",
url:"http://www.liulongbin.top:3006/api/getbooks",
params:{
}
});
console.log(res.data)
})
</script>
</body>
</html>
axios的demo使用vue请求GET,并且渲染到列表中:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>9直接发送axios请求</title>
<script src="./lib/axios.js"></script>
<script src="./lib/vue-2.6.12.js"></script>
<link rel="stylesheet" href="./lib/bootstrap.css" />
</head>
<body>
<div id="app">
<table class="table table-bordered table-hover table-striped">
<thead>
<th>id</th>
<th>book name</th>
<th>author</th>
<th>publisher</th>
</thead>
<tbody>
<tr v-for="item in list" :key="item.id">
<td>{{item.id}}</td>
<td>{{item.bookname}}</td>
<td>{{item.author}}</td>
<td>{{item.publisher}}</td>
</tr>
</tbody>
</table>
<input type="text" v-model.trim="inputInfo" placeholder="输入id查找"/>
<button id="getInfo" @click="list1">发送请求获取书籍列表</button>
</div>
<script>
const vm = new Vue({
el: "#app",
data: {
list:[],
inputInfo:""
},
methods: {
async list1() {
const { data: res } = await axios.get(
"http://www.liulongbin.top:3006/api/getbooks",
{
params: {
//id:this.inputInfo
},
}
);
console.log(res.data) ;
//console.log(this.inputInfo)
this.list = res.data;
},
},
});
</script>
</body>
</html>
vue-cli
什么是vue-cli
vue-cli是Vue.js开发的标准工具。简化了程序员基于webpack创建工程化的vue项目的过程。
1.在控制台终端运行命令,创建指定名称的项目
vue create 项目名称
选择第三个程序员可操作性强。
2. vue 项目中src的构成
assets文件夹:存放项目中用到的静态文件夹,例如:css样式表、图片资源等。
components文件夹:程序员封装的,可复用的组件可以放到components下。
main.js是项目的入口文件,执行项目首先执行main.js。
app.vue是项目的根组件。
什么是组件,组件是对ui结构的复用!!!
vue项目的运行流程
在工程化的项目中,vue要做的事情就是:通过main.js把App.vue渲染到index.html的指定区域内。
这句话我的理解为:,main.js是主要的控制器,绑定vue组件,也就是App.vue,将组件渲染到index.html的指定的位置。其实跟之前没有用到组件的原理是一致的。
全局组件和局部组件
组件的生命周期
生命周期是指一个组件创建-----运行----销毁的阶段
组件的声明周期分三个部分:1. 组件创建阶段 2. 组件运行阶段 3. 组件销毁阶段
- 组件创建阶段分为四类:创建之前,创建好,渲染之前,渲染好。(beforeCreate----created----beforeMount----mounted)每次启动都会一个一个去执行这个步骤。
- 组件运行阶段:更新之前, 更新好。(beforeUpdate-----update)
- 组件销毁阶段:销毁之前,销毁好。(beforeDestory—destory)
组件之间传递数据的三种方式
1.子组件传递父组件
使用自定义事件
2.父组件传递子组件
使用自定义属性 props
3. 兄弟组件使用eventbus传递
eventbus使用步骤
1 .在components创建eventbus.js注册vue实例,把它当作中间件去使用。
2 .在发送方的组件中的data创建发送的数据,在接收方的组件同样也创建接送的数据。
4. 在发送方导入eventbus.js,调用bus.¥emit(‘事件名称’, 要发送的数据)方法触发自定义事件,比如放一个按钮去触发。
6. 在接收方导入eventbus.js,调用bus.¥on(’事件名称‘,事件处理函数(这里 可以方一个箭头函数去接受发送方的数据==>(val{})))注册一个自定义的事件。我们可以将它放到生命周期中的created方法中,自动去传递信息。
动态组件
components标签下的is动态绑定子组件。使用keep-alive进行缓存,在切换页面的时候不会执行组件的创建和销毁的声明周期,同时vue也为keep-alive对应的生命周期函数。
当组件被缓存时, 会自动触发组件的deactivated生命周期函数
当组件被激活时, 会自动触发组件的activated生命周期函数
注意!!!!当组件第一次被创建的时候既会执行created生命周期也会执行activated的生命周期
<keep-alive>
<components :is="comName"></components>
</keep-alive>