作用:帮助我们实现对于一些原生DOM的操作。比如说,页面一进入输入框就获取焦点;比如焦点离开输入框就开始验证。
定义自定义指令:
全局注册
Vue.directive('指令名',{ 配置项 })
// 全局注册要放在Vue实例化之前
局部注册
new Vue({
el:"",
...
directives:{
指令名:{
配置项
}
}
})
指令的生命周期钩子
bind 绑定 只触发一次
inserted 插入 只触发一次
update 更新 可能内部没更新完就触发了 反复触发
componentUpdated 内部的组件更新结束,本身也更新结束才触发 反复触发
unbind 解绑 只触发一次
钩子函数的参数
el 指令所挂载的节点
binding 挂载的信息
vnode 虚拟节点
oldVnode 原来的虚拟节点
<html lang="en">
<head>
<meta charset="UTF-8">
<title>title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js">script>
head>
<body>
<div id="app">
<h3 v-myhtml="'天下第一美男子'">h3>
<input type="text" v-focus>
div>
body>
<script>
// 全局注册、 局部注册
// Vue.directive('指令名',{配置对象})
// v-test
Vue.directive('myhtml',{
bind(el,binding){ // 绑定指令 触发一次
console.log("bind");
},
inserted(el,binding){ // 节点插入的时候触发
console.log('inserted');
console.log(el);
console.log(binding.value);
el.innerHTML = '武哥'+binding.value
},
update(el,binding){ // 所在节点更新的时候触发,可能在子节点更新之前就被触发
console.log('update');
},
componentUpdated(el,binding){ // 所在节点及子节点都更新完成之后才触发
console.log('componentUpdated');
},
unbind(el,binding){
console.log('unbind');
}
})
new Vue({
el:"#app",
data:{
nums:100
},
directives:{ // 局部注册
focus:{
inserted(el,binding){
el.focus();
console.log(el);
}
}
}
})
script>
html>
作用:对于需要展示的数据进行一定的处理;比如: 我们在展示价格数据的,需要保留两位小数,需要的英文单字首字母大写,这个时候我们就可以定义过滤器来进行处理。
如何定义过滤器:
全局注册
Vue.filter('过滤器名',function(参数){
// 一定要有 return
})
局部注册
new Vue({
el:"",
...
filters:{
过滤器名:function(参数){
// 一定要有return
}
}
})
简单实用
{{ 变量 | 过滤器名 }}
多个过滤器一起使用
{{ 变量 | 过滤器名A | 过滤器名B }}
过滤器传参
{{ 变量 | 过滤器名A | 过滤器名B(参数1,参数2) }}
<html lang="en">
<head>
<meta charset="UTF-8">
<title>title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js">script>
head>
<body>
<div id="app">
{{ price.toFixed(2) }}
<br>
{{ price2.toFixed(1) }}
<hr>
{{ nums | toFix }}
<br>
{{ price | toFix }}
<br>
{{ price2 | toFix(1) }}
<br>
{{ price3 | toFix(3) | addstr }}
<br>
{{ price3 | toFix(3) | addstr('过滤的结果是:') }}
div>
body>
<script>
// 希望有一个可以对价格进行过滤的东西 过滤器
// 全局注册,局部注册
// 全局注册
// console.log(Vue.filter);
// 定义:Vue.filter('过滤器名',过滤器函数)
// 过滤器函数一定要有返回值
/*
Vue.filter('过滤器名',functon(变量值,传入的参数){
// 过滤处理
return 处理后的结果
})
*/
// 局部注册:
/*
new Vue({
el:""
...,
filters:{
过滤器名:function(变量值,传入的参数=参数默认值){
// 过滤处理
return 处理后的结果
}
}
})
*/
// 使用: {{ 变量 | 过滤器名 }}
// 使用: {{ 变量 | 过滤器名(参数1,参数2) }}
// 使用: {{ 变量 | 过滤器名1 | 过滤器名2 | 过滤器名3 |... }}
Vue.filter('toFix',function(val,num=2){
if(isNaN(val)){ // isNaN 是true 不是数字
console.log('不是数字');
return '不是数字';
}
return val.toFixed(num)
})
new Vue({
el:"#app",
data:{
price:300.421,
price2:400.246,
price3:10.834539745,
nums:'aaaa'
},
filters:{
addstr:function(val,str='结果是:'){
console.log(val);
return str+val
}
}
})
// 函数的默认参数
// function add(num){
// // var num = num || 20
// if(num){
// var num = num;
// }else{
// num = 20
// }
// console.log(num);
// }
// add();
function add(num=20){
console.log(num);
}
add();
add(100)
script>
html>
插槽是什么: 组件的标签之前放入一些html内容。那这些html内容被称为插槽。这些内容将会被渲染到组件的模板内部。
插槽的作用:提供给了开发者自己去定义插槽内部的一些局部结构。
组件调用时候
<组件名>
html标签内容
组件名>
<组件名>
<template v-slot:default>
html标签内容
template>
组件名>
组件模板内部
//组件的模板内
<template>
<div>
<h3>我是组件模板h3>
<slot>slot> // 就可以将上面的html标签内容放在这里
div>
template>
代码实现:
<html lang="en">
<head>
<meta charset="UTF-8">
<title>title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js">script>
head>
<body>
<div id="app">
<myalert>
<h3>我是h3h3>
<p>2333333333p>
myalert>
div>
<template id="myalert">
<div class="myalert">
<slot>slot>
我是myalert组件
div>
template>
body>
<script>
Vue.component('myalert',{
template:"#myalert"
})
new Vue({
el:"#app"
})
// 插槽的使用:
// 我们在组件运用的时候: 标签内容
// 组件的模板里面: 使用slot标签获取上面的标签内容
script>
html>
定义: 我们希望标签之间的HTML,不同的内容放在组件模板内部的不同地方。
实现:
<组件名>
<template v-slot:插槽名A>
HTML内容
template>
<template v-slot:default> // 默认插槽
HTML内容
template>
<template v-slot:插槽名B>
HTML内容
template>
组件名>
//组件的模板内
<template>
<div>
<h3>我是组件模板h3>
<slot name="default">slot> // 默认插槽
<slot>slot> // 默认插槽 可以省略 name
<slot name="插槽名A">slot>
<slot name="插槽名B">slot>
div>
template>
代码实现
<html lang="en">
<head>
<meta charset="UTF-8">
<title>title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js">script>
head>
<body>
<div id="app">
<myalert>
<h3>我是h3h3>
<p>2333333333p>
<template v-slot:aaa>
<h3>我是aaa的部分内容h3>
template>
<template v-slot:bbb>
<h3>我是bbb的部分内容h3>
template>
myalert>
div>
<template id="myalert">
<div class="myalert">
<slot name="default">slot>
我是myalert组件
<slot name="aaa">slot>
<slot name="bbb">slot>
div>
template>
body>
<script>
Vue.component('myalert',{
template:"#myalert"
})
new Vue({
el:"#app"
})
script>
html>
目的:在插槽的内容html里面可以直接渲染父组件的变量 ,却无法直接渲染该组件自己的变量。作用域插槽就可以帮我们实现 在插槽内部 调用 组件里的数据
实现:
在组件调用的时候
<组件名>
<template v-slot:插槽名A="作用域变量"> // 作用域变量就是该插槽slot标签上面的所有属性
{{ 作用域变量 }} // 渲染出 { 属性名A:变量A,属性名B:变量B, }
HTML内容
template>
<template v-slot:default> // 默认插槽
HTML内容
template>
<template v-slot:插槽名B>
HTML内容
template>
组件名>
组件模板内部
//组件的模板内
<template>
<div>
<h3>我是组件模板h3>
<slot name="default">slot> // 默认插槽
<slot>slot> // 默认插槽 可以省略 name
<slot name="插槽名A" :属性名A="变量A" :属性名B="变量B">slot>
<slot name="插槽名B">slot>
div>
template>
// 组件的JS内部
{
template:"",
data(){
return{
变量A:值A,
变量B:值B
}
}
}
代码实现:
<html lang="en">
<head>
<meta charset="UTF-8">
<title>title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js">script>
<style>
.box{
width: 800px;
background-color: #ccc;
margin: 0 auto;
}
.header{
height: 200px;
background-color: red;
}
.main{
height: 400px;
border: 2px solid blue;
}
.footer{
height: 100px;
background-color: orange;
}
style>
head>
<body>
<div id="app">
<page>
<template v-slot:tou="slotProps">
<h3>我是头部h3>
{{slotProps}}
<p>
<a href="" v-for="(item,index) in slotProps.navdata" :key="index">{{item}}a>
p>
template>
<template v-slot:default="defaultPorps">
<p>我是内容p>
{{defaultPorps}}
<ul>
<li v-for="(item,index) in defaultPorps.list" :key="index">{{item}}li>
ul>
template>
<template v-slot:jiao="slotProps">
<h3>我是脚步h3>
{{slotProps}}
<p>{{slotProps.copy}}p>
template>
page>
div>
<template id="page">
<div class="box">
<div class="header">
<slot name="tou" :navdata="navdata">slot>
div>
<div class="main">
<slot :list="list">slot>
div>
<div class="footer">
<slot name="jiao" :copy="copy">slot>
div>
div>
template>
body>
<script>
Vue.component('page',{
template:"#page",
data(){
return{
navdata:['首页','关于我们','公司新闻','等等'],
list:['新闻1','新闻2','新闻3','新闻4'],
copy:"版权所有@翻版必究"
}
}
})
new Vue({
el:"#app",
data:{}
})
script>
html>
为什么要学习旧语法: 因为很多一些成熟的UI框架,在封装的时候使用的是旧语法。比如element-ui
区别:
组件调用的时候
<组件名>
<template v-slot:插槽名A="作用域变量">
<template slot="插槽名A" slot-scope='作用域变量' >
{{ 作用域变量 }} // 渲染出 { 属性名A:变量A,属性名B:变量B, }
HTML内容
template>
<template v-slot:default> // 默认插槽
HTML内容
template>
<template v-slot:插槽名B>
HTML内容
template>
组件名>
组件内部,和新语法一致。
代码实现:
<html lang="en">
<head>
<meta charset="UTF-8">
<title>title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js">script>
head>
<body>
<div id="app">
<myalert>
<template slot-scope="props">
<h3>我是h3h3>
<p>2333333333p>
{{props}}
template>
<template slot="aaa" slot-scope="myprops">
<h3>我是aaa的部分内容h3>
{{ myprops }}
template>
<template slot="bbb">
<h3>我是bbb的部分内容h3>
template>
myalert>
div>
<template id="myalert">
<div class="myalert">
<slot name="default" yest="3234" yerrf="3333">slot>
我是myalert组件
<slot name="aaa" :tttmsg="msg">slot>
<slot name="bbb">slot>
div>
template>
body>
<script>
Vue.component('myalert',{
template:"#myalert",
data(){
return{
msg:"1111111111"
}
}
})
new Vue({
el:"#app"
})
script>
html>
进入
离开
离开前: v-leave
离开中: v-leave-active
离开后: v-leave-to
定义class
.动画名-enter{ css样式 } /*进入前*/
.动画名-enter-active{ css样式 } /*进入中 过渡。一般是transition */
.动画名-enter-to{ css样式 } /*进入后*/
.动画名-leave{ css样式 } /*离开前*/
.动画名-leave-active{ css样式 } /*离开中 过渡。一般是transition */
.动画名-leave-to{ css样式 } /*离开后*/
/* 动画如果自然: 进入中和离开中是一样的内容 */
使用动画
<transition name="动画名">
<html内容>
</transition>
注意: 动画显示,你得实现html内容 显示 隐藏的切换
代码实现:
<html lang="en">
<head>
<meta charset="UTF-8">
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js">script>
<style>
.over{
width: 304px;
height: 304px;
margin: 0 auto;
border: 4px solid #000000;
overflow: hidden;
}
.box{
width: 300px;
height: 300px;
border: 2px solid orange;
position: relative;
left: 0;
}
.myfade-enter{
/* 进入的开始 */
background-color: red;
opacity: 0;
position: relative;
left: 500px;
}
.myfade-enter-active{
/* 进入过程中 */
transition: all 1s ease-in;
}
/* .myfade-enter-to{ */
/* 进入之后 */
/* background-color: #fff; */
/* opacity: 1; */
/* } */
/* .myfade-leave{
background-color:#000;
} */
.myfade-leave-active{
/* 离开过程中 */
transition: all 1s ease-in;
}
.myfade-leave-to{
/* 离开之后 */
opacity: 0;
background-color: red;
position: relative;
left: -500px;
}
style>
head>
<body>
<div id="app">
<button @clicK="state=!state">切换button>
<div class="over">
<transition name="myfade">
<div class="box" v-if="state">
<h3>你好h3>
<h3>你好h3>
<h3>你好h3>
<h3>你好h3>
<h3>你好h3>
<h3>你好h3>
div>
transition>
div>
div>
body>
<script>
// v-enter 进入的时候
// v-enter-active 进入的过程中
// v-enter-to 进入后 【舍弃】 其实就是v-leave
// v-leave 离开之前
// v-leave-active 离开过程
// v-leave-to 离开后 【舍弃】 其实就是v-enter
new Vue({
el:"#app",
data:{
state:true
}
})
// 动画组件:
script>
html>
认识animate.css : 是一个css库,实现了很多动画效果
传统使用:
第1步:引入animate.css
第2步: 给要用动画的标签 上面添加上 animated 和 动画名称 class
<标签 class="animated bounceInDown">标签>
代码实现:
<html lang="en">
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="https://daneden.github.io/animate.css/animate.min.css">
<style>
.box{
width: 300px;
height: 300px;
background-color: red;
}
style>
head>
<body>
<div class="box animated bounceInDown">div>
body>
html>
如何结合Vue实现效果
第1步:引入animate.css
第2步:给我们的transition标签添加上 enter-active-class 和 leave-active-class 属性。 每个的值就是animate里面的动画class.
<transition enter-active-class="animated bounceInLeft" leave-active-class="animated bounceOutRight" >
html内容
transition>
代码实现:
<html lang="en">
<head>
<meta charset="UTF-8">
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js">script>
<link rel="stylesheet" href="https://daneden.github.io/animate.css/animate.min.css">
<style>
.over{
width: 304px;
height: 304px;
margin: 0 auto;
border: 4px solid #000000;
overflow: hidden;
}
.box{
width: 300px;
height: 300px;
border: 2px solid orange;
position: relative;
left: 0;
}
style>
head>
<body>
<div id="app">
<button @clicK="state=!state">切换button>
<div class="over">
<transition
enter-active-class="animated bounceInLeft"
leave-active-class="animated bounceOutRight"
>
<div class="box" v-if="state">
<h3>你好h3>
<h3>你好h3>
<h3>你好h3>
<h3>你好h3>
<h3>你好h3>
<h3>你好h3>
div>
transition>
div>
div>
body>
<script>
new Vue({
el:"#app",
data:{
state:true
}
})
// 动画组件:
script>
html>