第六节 自定义指令、过滤器

6.0什么是全局API?

全局API不在构造器里面的,先声明全局变量或直接在Vue上定义的一些新功能,内置了一些全局API,之后会给大家讲Vue.directive

6.1directive自定义指令

除了核心功能默认内置的指令v-model和v-show,vue也允许注册自定义指令。

全局自定义指令:​ Vue.directive ​局部自定义指令:​ directives

6.1.1完成下面需求

需求: 自定义两个指令
1、类似于v-text,但是要转换为大写字母(全局自定义指令)
2、类似于v-text,但是要转换为小写字母(局部自定义指令)
<div id="app">
<h1>{{msg}}</h1>
<h2 v-upper-text="u"></h2>
<h2 v-lower-text="i"></h2>
</div>
<script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.12/vue.js"></script>
<script type="text/javascript">
/*
输入的两个参数 id就是指的id(v-if,v-for),definition是指的定义对象,
其中定义对象可以提供一些钩子函数 Vue.directive('id',{})
*/
//定义全局指令[公有的]
Vue.directive('upper-text',function(el,binding){
console.log(el,binding);
el.innerHTML=binding.value.toUpperCase();
})
var vm = new Vue({
el:'#app',
data: {
msg:'我在上海学vue',
u:'i like you',
i:'ABCDEFGHI'
},
//局部自定义指令[私有的]
directives:{
'lower-text':function(el,binding){
el.innerHTML = binding.value.toLowerCase();
}
}
});
</script>

6.1.2js表达式

<div id="app">
<h3 v-my-text="{name:'肖雅涵',color:'blue'}"></h3>
<h3 v-my-text="{name:'Terrors',color:'red'}"></h3>
</div>
<script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.12/vue.js"></script>
<script type="text/javascript">
new Vue({
el:'#app',
data: {
msg:'在上海学习'
},
directives:{
/*
el:指令属性所在的标签元素
binding:包含指令相关的数据的对象
*/
'my-text' (el,binding){
console.log(el,binding);
//设置文本 和颜色
el.innerHTML=binding.value.name;
el.style.backgroundColor=binding.value.color;
}
}
})
</script>

6.1.3钩子函数

一个指令定义对象可以提供如下几个钩子函数(均为可选)

Vue2渐进式框架(二)_自定义指令

指令钩子函数会被传入以下参数:

Vue2渐进式框架(二)_vue.js_02

6.2过滤器

Vue.js允许你自定义过滤器,可被用于一些常见的文本格式化,过滤器可以用在两个地方:双花括号插值和v-bind表达式,过滤器应该被添加在JavaScript表达式的尾部,由管道符:|指示,表达式的值将作为形参传入到filter中。

全局过滤器:​ Vue.filter ​局部自定义指令:​ filters

<body>
<div id="app">
<p>============日常操作==================</p>
<p>苹果价格 :{{price1/100}} 元/斤</p>
<p>香蕉价格 :{{price2/100}} 元/斤</p>
<p>梨子价格 :{{price3/100}} 元/斤</p>
<p>草莓价格 :{{price4/100}} 元/斤</p>
<p>=============使用方法操作=================</p>
<!-- 使用方法实现 -->
<p>苹果价格 :{{pricemethod(price1)}} 元/斤</p>
<p>香蕉价格 :{{pricemethod(price2)}} 元/斤</p>
<p>梨子价格 :{{pricemethod(price3)}} 元/斤</p>
<p>草莓价格 :{{pricemethod(price4)}} 元/斤</p>
<p>=============使用过滤器操作[全局和局部的差异]=================</p>
<p>苹果价格 :{{price1 | format("元/斤")}} 元/斤</p>
<p>香蕉价格 :{{price2 | formatPrice}} 元/斤</p>
<p>梨子价格 :{{price3 | format("元/斤")}} 元/斤</p>
<p>草莓价格 :{{price4 | formatPrice}} 元/斤</p>
</div>
<script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.12/vue.js"></script>
<script type="text/javascript">
//全局过滤器
Vue.filter('formatPrice',function(p){
//console.log(p);
return (p/100).toFixed(2);
})
new Vue({
el:'#app',
data:{
price1:1888,
price2:1668,
price3:1778,
price4:1998,
},
methods:{
pricemethod(p){
//toFixed(2)保留两位小数
return (p/100).toFixed(2);
}
},
//局部过滤器
filters: {
format(p,m){
return '$'+(p/100).toFixed(2)+m;
}
}
})
</script>
</body>

第七节

7.1计算属性

计算属性​ 实际上也是一个方法,它可以完成各种复杂的逻辑、包括运算,函数调用,最终返回一个值

​计算属性是有缓存的,当值发生变化的时才会再次计算​

<div id="app">
<h1>{{num}}{{price}}</h1>
<!-- 使用方法得到 -->
<div style="border: 1px solid green;">
<h2>{{priceNum()}}</h2>
<h2>{{priceNum()}}</h2>
<h2>{{priceNum()}}</h2>
<h2>{{priceNum()}}</h2>
</div>
<!-- 使用计算属性 -->
<div style="border: 1px solid red;">
<h3>{{priceN}}</h3>
<h3>{{priceN}}</h3>
<h3>{{priceN}}</h3>
<h3>{{priceN}}</h3>
</div>
</div>
<script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.12/vue.js"></script>
<script type="text/javascript">
var vm = new Vue({
el:'#app',
data: {
num:10,
price:20
},
methods:{
priceNum(){
console.log(1);
return this.num * this.price;
}
},
/* 计算属性 */
computed:{
priceN(){
console.log("计算属性触发");
return this.num * this.price;
}
}

});
</script>

结果:

Vue2渐进式框架(二)_vue.js_03

7.2计算属性setter和getter[不常用]方法

<div id="app">
<div style="border: 1px solid red;">
姓: <input type="text" v-model="firstNum"><br/>
名: <input type="text" v-model="endNum"><br/>
姓名:{{firstNo}}
</div>
<div style="border: 1px solid red">
<p>setter和getter</p>
姓名:<input type="text" v-model="firstMo" /><br>
<h1>{{firstMo}}</h1>
</div>
</div>
<script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.12/vue.js"></script>
<script type="text/javascript">
var vm = new Vue({
el:'#app',
data:{
firstNum:'',
endNum:''
},
computed:{
firstNo(){
return this.firstNum + '-' + this.endNum;
},
firstMo:{
get(){
return this.firstNum + ' ' + this.endNum;
},
set(v){
//v是input输入的值
console.log(v);
var name = v.split(' ');
console.log(name);
this.firstNum = name[0];
this.endNum = name[1];
}
}
}
});
</script>

7.3侦听器

侦听器watch是Vue提供的一种用来观察和响应Vue实例上的数据变化的属性,当被侦听的数据发生变化时,会触发相应的侦听函数

侦听器可以监听data对象属性或者计算属性的变化,watch是观察属性的变化,所以watch的属性名必须要与观察人的名字保持一致;这样观察的值发生了变化才会触发;

案例解析:

<div id="app">
<!-- 加的数字不能大于10 减的数 不能小于0 -->
<button type="button" @click="add">+</button>
<h3>{{num}}</h3>
<button type="button" @click="reduce">-</button>
</div>
<script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.12/vue.js"></script>
<script type="text/javascript">
var vm = new Vue({
el:'#app',
data:{
num:10,
glab:false
},
methods: {
add(){
if(this.glab === true){
return
}
this.num++;
},
reduce(){
this.num--;
}
},
/* 侦听器 */
watch:{
/* 监听num属性的数据变化 一但属性发生变化 就触发 newVal是新的值 oldVal是旧的值*/
num(newVal,oldVal){
console.log(newVal,oldVal);
if(newVal<0){
this.num = 0;
}
if(newVal>10){
this.glab = true;
this.num = 10;
alert("库存不足!!!")
}
}
}
});
</script>

常用属性:

handler​ 就是原来的监听函数 当数据变化的时候 使用它

immediate:true:​ 代表watch里面申明的一次 理解为进入页面 就执行监听函数handler

deep:true:​ 属性代表是否深度监听 属性默认为false 当值为true的时候 会对对象的每个属性进行监听

案例:

<div id="app">
请输入你的名字:<input type="text" v-model="users.name">
<h1>{{users}}</h1>
</div>
<script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.12/vue.js"></script>
<script type="text/javascript">
var vm = new Vue({
el:'#app',
data:{
users:{
name:''
}
},
methods: {

},
/* 监听器 */
watch:{
/* 第一种方式 监听整个对象 每个属性值变化 都会执行handler*/
// users:{
// /* handler就是原来的监听函数 当数据变化的时候 使用它 */
// handler(news,old){
// // console.log(news.name,old.name);
// console.log(news.name,old);
// },
// /* 代表watch里面申明的一次 理解为进入页面 就执行监听函数handler */
// immediate:true,
// /* 属性代表是否深度监听 属性默认为false 当值为true的时候 会对对象的每个属性进行监听 */
// deep:true
// }

/* 第二种方式 监听对象的的某一个属性*/
'users.name' (news,old) {
console.log(news,old);
}

}
});
</script>

Vue2渐进式框架(二)_vue_04

第八节

8.1什么是组件化开发?

如果将一个页面所有的逻辑代码全部放在一起,当我们想要改变一些内容或者样式,处理起来会非常复杂,而且也不利于后续管理以及拓展。

我们可以将一个页面拆分成一个个小的功能模块,每个功能块完全属于自己这部分的独立功能,那么后面整个页面和维护就变得比较容易.

8.2使用组件的好处:

组件是由HTML+Css+Js组成
1、减少代码量,提高开发效率
2、代码可以重复使用
3、更容易被管理和维护
4、便于协同开发

8.3什么是组件?

组件是Vue.js最强大的功能之一,组件可以用扩展HTML元素,封装可重用的代码。

组件系统让我们可以用独立可复用的小组件来构建大型应用,几乎任意类型的应用的界面都可以抽象为一个组件树。

8.4注册组件的方式

注册组件的基本步骤:​(一)创建组件构造器;(二)注册组件;(三)使用组件

<div id="app">
<!-- 第三步 使用组件 -->
<my-coponent></my-coponent>
</div>
<script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.12/vue.js"></script>
<script type="text/javascript">
/* 第一步创建组件构造器 */
var myCoponent = Vue.extend({
template: `
<div>
<h2>Vue组件基本使用</h2>
</div>
`
});
/* 第二步 注册组件 */
Vue.component('my-coponent',myCoponent);
var vm = new Vue({
el:'#app',
});
</script>

​上述步骤解析:​

1.Vue.extend():

调用Vue.extend()创建的是一个组件构造器。

通常在创建组件构造器时,传入template代表我们自定义组件的模板。

该模板就是在使用到组件的地方,要显示的HTML代码。

事实上,这种写法在Vue2.x的文档中几乎已经看不到了,它会直接使用下面我们会讲到的语法糖,但是在很多资料还是会提到这种方式,而且这种方式是学习后面方式的基础。

2.Vue.component():

调用Vue.component()是将刚才的组件构造器注册为一个组件,并且给它起一个组件的标签名称。

所以需要传递两个参数:1、注册组件的标签名 2、组件构造器

3.组件必须挂载在某个Vue实例下,否则它不会生效。

Vue2渐进式框架(二)_vue_05

8.5组件嵌套使用

组件它是可以在,任意组件中使用的,但是局部组件之间不可以直接相互使用,如果需要相互使用就得进行嵌套使用的方式。

案例瞅瞅

<script>
var child = {
template:`
<div style="float: left;border:1px solid red;">
<h1>孩子</h1>
</div>
`
}
var parent = {
template:`
<div style="float: left;border:1px solid green;">
<h1>父亲</h1>
<my-child></my-child>
</div>
`,
components:{
"my-child":child
}
}
new Vue({
el:'#app',
components:{
"my-child":child
}
})
new Vue({
el:'#app2',
components:{
"my-parent":parent
}
})
</script>