目录
Vue选项
el 模板
data 数据
methods方法
directives 指令
filters 过滤
watch 监听
computed 计算
props属性
created 创建完毕
template 模板
componets 组件
自定义指令
作用:操作dom;实例化第三方基于dom的插件
<input v-focus="true">
directives:{
"focus":{
update(el,binding){
// el 指令所在节点
// binding.value 指令的值
}
}
}update, 更新就执行
bind 绑定一次
inserted 插入
过滤,管道filters
作用:格式化数据
<body>
<div id="app">
<input type="text" v-model.lazy="day" placeholder="输入时间至今多久">
<p>{{day|date}}</p>
</div>
</body>
<script>
new Vue({
el: "#app",
data(){
return{
day:""
}
},
filters: {
//val 是过滤前的值
//return 过滤后的值
date(val) {
var time1 = new Date(val).getTime();
var time2 = new Date().getTime();
var dis = time2 - time1;
if ((dis / 1000 > 0) && (dis / 1000) <= 60) {
return Math.floor(dis / 1000) + "秒前"
} else if (dis / 1000 > 60 && dis / 1000 < 3600) {
return Math.floor(dis / 1000 / 60) + "分钟前";
} else if (dis / 1000 > 3600 && dis / 1000 < (3600 * 24)) {
return Math.floor(dis / 1000 / 3600) + "小时前";
} else if (dis / 1000 > (3600 * 24) && dis / 1000 < (3600 * 24 * 7)) {
return Math.floor(dis / 1000 / 3600 / 24) + "天前";
} else if (dis / 1000 > 3600 * 24 * 7 && dis / 1000 < (3600 * 24 * 30)) {
return Math.floor(dis / 1000 / 3600 / 24 / 7) + "周前";
} else if (dis / 1000 > (3600 * 24 * 30) && dis / 1000 < (3600 * 24 * 30 * 12)) {
return Math.floor(dis / 1000 / 3600 / 24 / 30) + "月前";
} else if (dis / 1000 > 3600 * 24 * 30 * 12) {
return Math.floor(dis / 1000 / 3600 / 24 / 30 / 12) + "年前";
}
}
}
})
</script>
</html>
全局组件
Vue.component 来创建组件:
Vue.component("btn",{
template:`<button @click="n++">{{n}}</button>`,
data(){return {n:1}}
})
局部组件
1.定义组件
const step = {
template:`<div><button @click="n--">-</button>{{n}}<button @click="n++">+</button></div>`,
data(){return {n:1}}
}2.注册组件
const app = new Vue({
components:{step}
})
3.使用组件
<step></step>
<step></step>
<body>
<div id="app">
<!-- 03 使用组件 -->
<step></step> <br>
<step></step> <br>
</div>
<script>
// 01 定义组件
var step = {
template: `<span>
<button @click="count--" :disabled="count<=1">-</button>
<input type="text" v-model="count">
<button @click="count++" :disabled="count>=999">+</button>
<span>`,
data() {
return {
count: 1,
}
}
}
new Vue({
el: "#app",
//02 注册组件
components: { step },
})
</script>
props传递参数
传递
<step :num="10"></step>
<step :num="5"></step>
接收
props:{
"num":{type:Number,default:1}
},
使用
data(){return {n:this.num}}
对象与数组的默认值必须是函数的返回值
props细节
1.每一个数据项,都可以有3个属性进行约束type,类型约束,约束父组件给子组件传递的数据类型,类型可以是:Object、Array、Number、String、Boolean等几种。
2.default,指定默认值,如果父组件没有传递数据,可以指定默认值
3.required,指定该数据项是否必须传递
组件传参父传子
<body>
<div id="app">
<!-- 03 使用组件 -->
<h1>组件传参</h1>
<p>父传子</p>
<step v-model="r"></step> <br>
<step :value="r" @input="r=$event" :min="100" :max="500" :step="10"></step> <br>
<input type="range" min="100" max="500" v-model.number="r">
<div :style="{border:'2px solid red',borderRadius:r+'px',width:r+'px',height:r+'px'}"></div>
</div>
<script>
// 01 定义组件
new Vue({
el: "#app",
//02 注册组件
components: { step },
data() {
return {
r: 100,
}
}
})
</script>
js
// 01 定义组件
var step = {
template: `<span>
<button @click="count-=step" :disabled="count<=min">-</button>
<input type="text" v-model.lazy.number="count"/>
<button @click="count+=step" :disabled="count>=max">+</button>
</span>`,
props:{ //props接收父组件传递过来的参数
value:{ //参数名称value
type:Number, //参数数据类型是number
default:1 //默认值是1,如果不传value的值是1
},
// 接收父组件传递过来参数最小,最大值,步进值
min:{
type:Number,
default:1
},
max:{
type:Number,
default:999
},
step:{
type:Number,
default:1
}
},
data() {
return {
count: this.value//count的默认值是父组件传过来的参数value
}
},
watch:{
count:{
handler(){
// 限定最大值,最小值
if(this.count>=this.max){this.count=this.max};
if(this.count<=this.min){this.count= this.min}
// 子传父 通过emit发送事件
this.$emit("input",this.count);
},
deep:true,
},
value:{
handler(){
// 监听value值的变化更新count(可选)
this.count = this.value;
},
deep:true
}
}
}
// 为什么不直使用this.value 和input框绑定
// 答:父组件传到子组件的参数必须是只读
// 当count的数据发生变化的时候通知父组件更新数据
1、父组件定义数据 2、父组件通过属性的方式给子组件传递数据 3、子组件通过props属性接受数据并做参数设置 4、子组件使用传递过来的数据
组件传值总结
<body>
<!--
a.父组件向子组件传值:通过v-bind:的形式进行数据的传递(可直接简写为冒号)
然后子组件 使用props来接收
b.子组件向父组件传值:
局部组件TodoItem的li有handleItemClick事件
this.$emit("delete",this.index):子组件向外触发事件,并携带参数
父组件中 @delete="handleItemDelete" 监听到删除事件,
于是调用handleItemDelete:function(index)方法
-->
<div id="root">
<div>
<input type="text" v-model="inputValue">
<button v-on:click="handleBtnClick">提交</button>
</div>
<ul>
<!--<li v-for="item in list">{{item}}</li>-->
<!--父组件(最外层的Vue实例)中data里面的list 传给子组件
子组件遍历list,得到item,然后给了子组件的一个变量content
创建这个子组件todo-item的同时,也监听到子组件的delete事件
index指的是是第几个todo-item
向子组件传值:不仅传content,还把对应的下标传下去
-->
<todo-item v-bind:content="item"
v-bind:index="index"
v-for="(item,index) in list"
@delete="handleItemDelete"> <!--父组件监听delete事件 去执行handleItemDelete方法-->
</todo-item>
</ul>
</div>
<script>
//2.局部组件 同样,子组件要是想用index,就必须接收index
var TodoItem ={
props:['content','index'],
template:"<li @click='handleItemClick'>{{content}}</li>",
methods:{
handleItemClick:function () {//子组件一旦被点击 不但触发delete事件,同时还把this.index作为参数 带给父组件
this.$emit("delete",this.index); //子组件向外触发事件 index传给父组件
}
}
}
var app=new Vue({
el:'#root',
//2.注册局部组件 到 Vue实例中
components:{
TodoItem:TodoItem
},
data:{
list: [],
inputValue:''
},
methods:{
handleBtnClick:function () {
this.list.push(this.inputValue)
this.inputValue='';
},
handleItemDelete:function(index){
alert(index);
this.list.splice(index,1);//从哪个位置删除1个元素
}
}
});
</script>
</body>
组件的插槽(嵌套)
使用 <slot> 作为我们想要插入内容的占位符
<step>
你好,我是嵌套内容
</step>
template:`<div><h1>组件的标题</h1><slot></slot></div>`
具名插槽
<body>
<div id="app">
<div slot="header">我是头部内容</div>
<div slot="main">我是主体内容</div>
<div slot="footer">我是底部内容</div>
</div>
</body>
<script>
var mySon = {
data: function() {
return {};
},
template: `
<div>
<div><slot name='header'></slot></div>
<div><slot name='main'></slot></div>
<div><slot name='footer'></slot></div>
</div>
`,
methods: {}
};
var vue = new Vue({
el: "#app",
data: {},
methods: {},
components: {
"my-son": mySon
}
});
</script>
弹框组件的使用
http://t.csdn.cn/1Os9T
插槽的作用域
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<body>
<div id="app">
<h1>插槽的作用域(父组件自定义渲染子组件局部内容)</h1>
<!-- 使用组件 -->
<lis :list="list">
<template v-slot:default="scope">
<span>{{scope.item}}</span>
</template>
</lis>
</div>
<script>
//定义组件
var lis = {
template: `
<div>
<div v-for="item in list" :key="item">
<slot :item="item"></slot>
</div>
</div>
`,
props: {
list: {
type: Array
}
}
}
new Vue({
el: "#app",
//注册组件
components: {
lis,
},
data() {
return {
list: ["Vue", "React", "Angular"]
}
}
})
</script>
Vue动画
动画-过渡class
在进入/离开的过渡中,会有 6 个 class 切换。
v-enter-active 进入开始 v-enter-to 进入结束 v-enter-active进入整个状态 v-leave-active 离开开始 v-leave-to 离开结束 v-leave-active离开整个状态
<style>
.fade-enter-active {
/* 进入的整个状态 */
transition: all ease 1s;
}
.fade-enter {
/* 进入初始状态 */
opacity: 0;
transform: rotate(-180deg);
}
.fade-enter-to {
/* 进入最终状态 */
opacity: 1;
transform: rotate(0deg);
}
.fade-leave-active {
/* 离开整个状态 */
transition: all ease 1s;
}
.fade-leave {
opacity: 1;
transform: rotate(0deg);
}
.fade-leave-to {
opacity: 0;
transform: rotate(180deg);
}
</style>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<body>
<div id="app">
<h1>动画</h1>
<button @click="flag =!flag">切换</button>
<p>
<transition name="fade">
<img src="./img/sun1.jpg" alt="" v-if="flag" width="100">
</transition>
</p>
</div>
<script>
new Vue({
el: "#app",
data() {
return {
flag: true
}
}
})
</script>
动画-使用关键帧动画
<style>
@keyframes fadein {
from {
opacity: 0;
transform: scale(0);
}
to {
opacity: 1;
transform: scale(1);
}
}
@keyframes fadeout {
0% {
opacity: 1;
transform: scale(1);
}
100% {
opacity: 0;
transform: scale(0);
}
}
.fade-enter-active {
/* 进入的整个状态,执行一个关键帧动画 */
animation: fadein ease 1s;
}
.fade-leave-active {
/* 离开整个状态,执行一个关键帧动画 */
animation: fadeout ease 1s;
}
</style>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<body>
<div id="app">
<h1>动画</h1>
<button @click="flag =!flag">切换</button>
<p>
<transition name="fade">
<img src="./img/sun1.jpg" alt="" v-if="flag" width="100">
</transition>
</p>
</div>
<script>
new Vue({
el: "#app",
data() {
return {
flag: true
}
}
})
</script>
动画-引入第三方
animate动画库:https://www.jq22.com/yanshi819
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="./css/animate.min.css">
<title></title>
</head>
<style>
</style>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<body>
<div id="app">
<h1>动画</h1>
<button @click="flag =!flag">切换</button>
<p>
<transition name="fade" enter-active-class="flipInX animated" leave-active-class="hinge animated">
<img src="./img/sun1.jpg" alt="" v-if="flag" width="100">
</transition>
</p>
</div>
<script>
new Vue({
el: "#app",
data() {
return {
flag: true
}
}
})
</script>
动画模式
in-out 先进在出,out-in先出在进
<transition mode="out-in" enter-active-class="animated slideInLeft" leave-active-class="slideOutRight animated">
<button key='a' v-if="flag">A</button>
<button key='b' v-else>B</button>
</transition>
动画列表过渡
我们会使用 <transition-group> 组件实现列表过渡
<transition-group tag="div" name="slide" >
<div class="item" v-for="item in undoList" :key="item.name">
.....
</transition-group>.slide-leave-active{
animation: slideOut ease 1s;
position: absolute;
}
/* transition-group 正在移动中的类名 */
/* 移动中的元素 */
.slide-move{
transition: all ease 1s;
}
<transition-group tag="div" enter-active-class="fadeIn animated" leave-active-class="fadeOut animated">
>
<img v-show="current ===index" v-for="(item,index) in count" :key="item" :src="item" width="100%" >
</transition-group>