vue学习
1. vue指令的写法
Vue.directive('clickoutside',{
bind: function(el,binding,vNode){
function documentClickHandle(e) {
if(el.contains(e.target)) {
return false
}
if(binding.expression)
{
binding.value(e)
}
}
el.__vueClickOutside = documentClickHandle
document.addEventListener('click',documentClickHandle)
},
unbind: function(el,binding) {
document.removeEventListener('click',el.__vueClickOutside)
delete el.__vueClickOutside
}
})
2. vue $mount 和 el的区别
原文:https://blog.csdn.net/c2311156c/article/details/80415633
如果在实例化vue的时候指定el,则该vue将会渲染在此el对应的dom中,反之,若没有指定el,则vue实例会处于一种“未挂载”的状态,此时可以通过$mount来手动执行挂载。
注:如果$mount没有提供参数,模板将被渲染为文档之外的的元素,并且你必须使用原生DOM API把它插入文档中。
var MyComponent = Vue.extend({
template: '<div>Hello!</div>'
})
// 创建并挂载到 #app (会替换 #app)
new MyComponent().$mount('#app')
// 同上
new MyComponent({ el: '#app' })
// 或者,在文档之外渲染并且随后挂载
var component = new MyComponent().$mount()
document.getElementById('app').appendChild(component.$el)
3.vue 插件
import PhotoBox from './PhotoBox.vue'
import Vue from 'vue'
let instance = null
function photoShow (config) {
if (!instance) {
instance = new Vue({
data: {
show: false,
index: 0,
picList: []
},
methods: {
showPics ({list, index}) {
this.picList = [].concat(list || [])
this.index = index || 0
this.show = true
},
hidePics () {
this.show = false
}
},
render (h) {
return h(PhotoBox, {
props: {
show: this.show,
index: this.index,
picList: this.picList
},
on: {
'on-close': () => {
this.hidePics()
}
}
})
}
}).$mount()
document.body.appendChild(instance.$el)
}
if (config instanceof Array) {
config = {
list: config,
index: 0
}
}
instance.showPics((config) || {})
}
function photoHide () {
instance && (instance.hidePics())
}
export const photoBoxInit = {
install (Vue) {
Vue.prototype.$photoShow = photoShow
Vue.prototype.$photoHide = photoHide
}
}
export default PhotoBox
main.js中引入
import {photoBoxInit} from '@/components/photo-box'
/**
* @description 将图片弹窗注册到全局 使用 vue实例 this.$photoShow 调用弹窗 同时可以调用 this.$photoHide 关闭
*/
Vue.use(photoBoxInit)
使用
this.$photoShow(['asdfasdf.jpg'])
4. 小球动画
<h2>小球动画</h2>
<button @click="ballShow=!ballShow">小球动画</button>
<transition @before-enter="beforeEnter"
@enter="enter" @after-enter="afterEnter" v-bind:css="false">
<div class="ball" v-show="ballShow"></div>
</transition>
var app=new Vue({
el:'#app',
data:{
ballShow: false
},
methods:{
ballAnimate() {
this.ballShow=!this.ballShow
},
beforeEnter(el) {
el.style.transform = "translate(0,0)"
},
enter(el,done) {
el.offsetWidth //为了触发浏览器的重排,否则看不出来动画效果
el.style.transform = "translate(150px,350px)";
el.style.transition = "all 0.4s cubic-bezier(0.49,-0.29,0.75, 0.14)";
el.addEventListener('transitionend', done) //动画执行完成后调用done回调,也就是afterEnter
},
afterEnter(el) {
this.ballShow= !this.ballShow;
}
}
})
5. 列表动画 transition-group
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>vuejs列表动画</title>
<style>
*{margin: 0; padding: 0;}
ul,li {list-style: none;}
.head-box {
line-height: 30px;
}
.head-box input[type='text'] {
height: 22px;
line-height: 22px;
padding: 0 5px;
}
li {
border: 1px dashed #999;
margin: 5px;
line-height: 35px;
padding-left: 10px;
font-size: 14px;
transition: all .4s ease;
width: 90%;
}
li:hover {
background-color: hotpink;
}
.v-enter, .v-leave-to {
opacity: 0;
transform: translateY(50px);
}
.v-enter-active,.v-leave-active {
transition: all .6s ease;
}
.v-leave-active { /*移除时下一条记录也能跟随动*/
position: absolute;
}
.v-move {
transition: all 1s;
}
</style>
</head>
<body>
<div id="app">
<div class="head-box">
<label>书Id: <input type="text" v-model="id" placeholder="请输入id"/></label><br>
<label>书名: <input type="text" v-model="name" placeholder="请输入名称" @keyup.enter="addBook"/></label>
<button @click="addBook">提交</button>
</div>
<transition-group tag="ul" appear> <!-- transition-group默认会使用一个span标签 --> <!--appear属性是页面首先进入时有动画效果-->
<li v-for="(item,index) in books" :key="item.id" @click="deleteBook(index)">
{{item.id}} --- {{item.name}}
</li>
</transition-group>
</div>
<script src="https://cdn.bootcss.com/vue/2.6.10/vue.min.js"></script>
<script>
var app=new Vue({
el:'#app',
data:{
id: '',
name: '',
books:[
{id:1, name:'《Vue.js实战》'},
{id:2, name:'《JavaScript语言精粹》'},
{id:3, name:'《JavaScript高级程序设计》'}
]
},
methods:{
addBook() {
if(!this.id || !this.name) return
this.books.push({id:this.id,name: this.name});
this.id=this.name="";
},
deleteBook(index) {
console.log(index);
this.books.splice(index,1);
}
}
})
</script>
</body>
</html>
效果:

6. 路由切换时动画效果
<template>
<div id="app">
<header class="header">
<h2>路由切换动画</h2>
</header>
<div class="main">
<transition name="routerani">
<router-view/>
</transition>
</div>
<footer class="footer">
<nav class="tabs">
<router-link tag="div" class="tab-item" to="/">主页</router-link>
<router-link tag="div" class="tab-item" to="/about">关于</router-link>
<router-link tag="div" class="tab-item" to="/my">我的</router-link>
</nav>
</footer>
</div>
</template>
<style lang="stylus">
*
margin 0
padding 0
/*隐藏滚动条样式-移动端下用的较多*/
::-webkit-scrollbar{
height: 0;
width: 0;
color: transparent;
}
#app
font-family 'Avenir', Helvetica, Arial, sans-serif
-webkit-font-smoothing antialiased
-moz-osx-font-smoothing grayscale
width 100%
height 100%
padding 40px 0
position relative
overflow-x hidden
.header
position fixed
left 0
top 0
width 100%
background-color rgba(18, 221, 255, 1)
h2
height 40px
line-height 40px
font-size 18px
margin 0
color white
text-align center
.routerani-enter
opacity: 0
transform: translateX(100%)
.routerani-leave-to
opacity: 0
transform: translateX(-100%)
position: absolute
.routerani-enter-active, .routerani-leave-active
transition all 0.6s ease
.footer
position fixed
left 0
bottom 0
width 100%
height 40px
background-color rgba(16, 58, 105, 1)
.tabs
display: flex
.tab-item
flex 1
line-height 40px
text-align center
color white
&.router-link-exact-active
color #42b983
</style>
效果:

网友评论