动画
动画钩子函数
-
v-enter:定义进入过渡的开始状态。在元素被插入之前生效,在元素被插入之后的下一帧移除。
-
v-enter-active:定义进入过渡生效时的状态。在整个进入过渡的阶段中应用,在元素被插入之前生效,在过渡/动画完成之后移除。这个类可以被用来定义进入过渡的过程时间,延迟和曲线函数。
-
v-enter-to:2.1.8 版及以上定义进入过渡的结束状态。在元素被插入之后下一帧生效 (与此同时 v-enter 被移除),在过渡/动画完成之后移除。
-
v-leave:定义离开过渡的开始状态。在离开过渡被触发时立刻生效,下一帧被移除。
-
v-leave-active:定义离开过渡生效时的状态。在整个离开过渡的阶段中应用,在离开过渡被触发时立刻生效,在过渡/动画完成之后移除。这个类可以被用来定义离开过渡的过程时间,延迟和曲线函数。
-
v-leave-to:2.1.8 版及以上定义离开过渡的结束状态。在离开过渡被触发之后下一帧生效 (与此同时 v-leave 被删除),在过渡/动画完成之后移除。
小球动画
<!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="https://cdn.staticfile.org/vue/2.2.2/vue.min.js"></script>
<style>
.ball{
width: 15px;
height:15px;
background-color:red;
border-radius:50% ;
}
</style>
</head>
<body>
<div id="app">
<input type="button" value="加入购物车" @click="flag=!flag">
<transition
@before-enter="beforeEnter"
@enter="enter"
@after-enter="afterEnter">
<div class='ball' v-show="flag">
</transition>
</div>
</div>
<script>
var vm=new Vue({
el:'#app',
data:{
flag:false
},
methods:{
beforeEnter: (el) => {
el.style.transform='translate(0,0)'
},
enter(el,done){
el.offsetWidth
el.style.transform='translate(150px,450px)'
el.style.transition = "all 1s ease"
done()
},
afterEnter(el){
this.flag=!this.flag
}
}
});
</script>
</body>
</html>
组件
父子组件传值
- 子组件默认无法访问到父组件的data上的数据和methods中的方法
- 子组件中的data数据并不是通过父组件传递过来的,而是子组件自身私有的,比如:子组件通过ajax请求回来的数据,都可以放到data上
- 子组件中,props中的数据都是只读的,data上的数据是可读可写得
- 子组件向父组件传递通过this.$emit()
父组件向子组件传值
<!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="https://cdn.staticfile.org/vue/2.2.2/vue.min.js"></script>
</head>
<body>
<div id="app">
<com1 :parentmsg="msg">
</com1>
</div>
<script>
var vm=new Vue({
el:'#app',
data:{
msg:"周志军大帅哥"
},
methods:{},
components:{
//子组件无法访问父组件中的数据和方法
com1:{
template:'<h1>私有组件{{parentmsg}}</h1>',
props:['parentmsg'],//是一个数组,把父组件传递的属性先定义一下,
directives:{},
components:{},
methods:{
}
}
}
});
</script>
</body>
</html>
父组件传方法给子组件
<!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="https://cdn.staticfile.org/vue/2.2.2/vue.min.js"></script>
<script src="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script>
</head>
<body>
<div id="app">
<com2 @func="show">
</com2>
</div>
<template id="temp">
<div>
<input type="button" value="子组件按钮,点击触发父组件方法" @click="myclick">
</div>
</template>
<script>
var com2={
template:"#temp",
data() {
return {
sonmsg:{
name:'刘德容',
age:66
}
}
},
methods:{
myclick(){
//关键
this.$emit('func',this.sonmsg)
}
}
}
var vm=new Vue({
el:'#app',
data:{
datamsgFromSon:""
},
methods:{
show(data1){
this.datamsgFromSon=data1,
console.log(data1)
}
},
components:{
//子组件无法访问父组件中的数据和方法
com2:com2
}
});
</script>
</body>
</html>
- 子组件可以向localStorage存数据,然后父组件从localStorage中取
<!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="https://cdn.staticfile.org/vue/2.2.2/vue.min.js"></script>
<link rel="stylesheet" href="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/css/bootstrap.min.css">
<script src="https://cdn.staticfile.org/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script>
</head>
<body>
<div id="app">
<cmt-box @func="loadComments"></cmt-box>
<ul class="list-group">
<li class="list-group-item" v-for="item in list" :key="item.id">
<span class="badge">评论人:{{item.user}}</span>
{{item.content}}
</li>
</ul>
</div>
<template id="temp1">
<div>
<div class="from-group">
<label >评论人</label>
<input type="text" class="form-control" v-model="user">
</div>
<div class="from-group">
<label >评论内容</label>
<textarea class="form-control" v-model="content"></textarea>
</div>
<div class="form-group">
<input type="button" value="发表评论" class="btn btn-primary" @click="postComment">
</div>
</div>
</template>
<script>
var commentbox={
template:"#temp1",
data() {
return {
user:'',
content:''
}
},
methods:{
postComment(){//发表评论
var comment={id:Date.now(),user:this.user, content:this.content}
//从localStorage获取所有评论
var list=JSON.parse(localStorage.getItem('cmts')||'[]')
//头插入
list.unshift(comment)
//保存最新的评论
localStorage.setItem('cmts',JSON.stringify(list))
this.user=this.content=''
this.$emit('func')
}
}
}
var vm=new Vue({
el:'#app',
data:{
list:[
{id:Date.now(),user:'李白', content:'黄河之水天上来'},
{id:Date.now(),user:'马云', content:'我对钱不敢兴趣'},
{id:Date.now(),user:'马化腾', content:'充八万'}
]
},
created(){
this.loadComments()
},
methods:{
loadComments(){//从本地加载评论
var list=JSON.parse(localStorage.getItem('cmts')||'[]')
this.list=list
}
},
components:{
'cmt-box':commentbox
}
});
</script>
</body>
</html>
路由
基本使用
- 引入包
- 配置路由规则
- 注册在父组件
- 在根DOM上使用
<!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="https://cdn.staticfile.org/vue/2.2.2/vue.min.js"></script>
<script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
<style>
.router-link-active{
color:red;
}
.myactive{
color:green;
}
.v-enter,
.v-leave-to{
opacity: 0;
transform:translateX(140px);
}
.v-enter-active,
.v-leave-active{
transition:all 0.5s ease;
}
</style>
</head>
<body>
<div id="app">
<!-- 理解为占位符 -->
<!-- <a href="#/login">登陆</a>
<a href="#/register">注册</a> -->
<router-link to="/login" tag="span"> 登陆</router-link>
<router-link to="register">注册</router-link>
<transition mode="out-in">
<router-view></router-view>
</transition>
</div>
<script>
var login={
template:'<h3>login</h3>'
}
var register={
template:'<h3>register</h3>'
}
var routerObj=new VueRouter({
routes:[
//component属性值必须是一个模板对象,不能是组件的引用名称
// {path:'/',component:login}
//重定向
{path:'/',redirect:'/login'},
{path:'/login',component:login},
{path:'/register',component:register}
],
linkActiveClass:'myactive'
})
var vm=new Vue({
el:'#app',
data:{},
methods:{},
router:routerObj//将路由规则对象,注册到vm实例上,用来监听URL地址的变化然后展示对应的 组件
});
</script>
</body>
</html>
路由传参
①用?
<!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="https://cdn.staticfile.org/vue/2.2.2/vue.min.js"></script>
<script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
</head>
<body>
<div id="app">
<router-link to="/login?id=10">login</router-link>
<router-link to="/register">register</router-link>
<router-view></router-view>
</div>
<script>
var login={
template:'<h3>login---{{$route.query.id}}</h3>',
created(){
console.log(this.$route.query.id)
}
}
var register={
template:'<h3>register</h3>'
}
var routerObj=new VueRouter({
routes:[
{path:'/login',component:login},
{path:'/register',component:register}
]
})
var vm=new Vue({
el:'#app',
data:{},
methods:{},
router:routerObj
});
</script>
</body>
</html>
②用params
<!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="https://cdn.staticfile.org/vue/2.2.2/vue.min.js"></script>
<script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
</head>
<body>
<div id="app">
<router-link to="/login/12/ls">login</router-link>
<router-link to="/register">register</router-link>
<router-view></router-view>
</div>
<script>
var login={
template:'<h3>login---{{$route.params.id}}--{{$route.params.name}}</h3>',
created(){
console.log(this.$route.params.id)
}
}
var register={
template:'<h3>register</h3>'
}
var routerObj=new VueRouter({
routes:[
{path:'/login/:id/:name',component:login},
{path:'/register',component:register}
]
})
var vm=new Vue({
el:'#app',
data:{},
methods:{},
router:routerObj
});
</script>
</body>
</html>
路由嵌套
配置路由时候配置children属性
<!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="https://cdn.staticfile.org/vue/2.2.2/vue.min.js"></script>
<script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
</head>
<body>
<div id="app">
<router-link to="/account" >account</router-link>
<router-view></router-view>
</div>
<template id="temp">
<div>
<h1>这是account组件</h1>
<router-link to="/account/login">login</router-link>
<router-link to="/account/register">register</router-link>
<router-view></router-view>
</div>
</template>
<script>
var account={
template:'#temp'
}
var login={
template:'<h3>login</h3>',
created(){
console.log(this.$route.params.id)
}
}
var register={
template:'<h3>register</h3>'
}
var router=new VueRouter({
routes:[
{path:'/account',
component:account,
children:[
{path:'login',component:login},
{path:'register',component:register}
]
},
// {path:'/account/login',component:login},
//{path:'/account/register',component:register},
]
})
var vm=new Vue({
el:'#app',
data:{},
methods:{},
router
});
</script>
</body>
</html>
- 尝试用多一个/的形式,发现不行,会连同父组件一起消失
- 用children配置子组件path不带/,否则永远以根路径开始请求,这样不方便用户去理解URL地址。
路由实现经典布局
<!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="https://cdn.staticfile.org/vue/2.2.2/vue.min.js"></script>
<script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
<style>
.header{
background-color: red;
height:80px;
}
.container{
display: flex;
height:600px;
}
.left{
background-color:snow;
flex:2;
}
h1{
margin:0;
padding:0;
}
html,body{
margin:0;
padding:0;
}
.main{
background-color: skyblue;
flex:8;
}
</style>
</head>
<body>
<div id="app">
<router-view></router-view>
<div class ="container">
<router-view name="left"></router-view>
<router-view name="main"></router-view>
</div>
</div>
<script>
var header={
template:'<h1 class="header">header</h1>'
}
var leftBox={
template:'<h1 class="left">leftBox</h1>'
}
var mainBox={
template:'<h1 class="main">mainBox</h1>'
}
//创建路由对象
var router=new VueRouter({
routes:[
// {path:'/',component:header},
// {path:'/left',component:leftBox},
// {path:'/main',component:mainBox}
{path:'/',components:{
default:header,
left:leftBox,
main:mainBox
}}
]
})
var vm=new Vue({
el:'#app',
data:{},
methods:{},
router
});
</script>
</body>
</html>