daily-share
daily-share copied to clipboard
vue2.5基础整理(2020-2-11)
Vue2.5开发基础学习
vue基础
- 注意: vue不支持低版本浏览器内容
使用vue.js 实现hello world
// 如何在页面上实现一个简单的hello world
// 1. 方式1: 原生的方式
var app = document.getElementById('app')
app.innerHTML = 'hello world'
// 2. 方式2: vue的方式
// 引入vue的cdn
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
const app = new Vue({
el: "#app",
data: {
content: 'hello world'
}
})
使用vuejs实现ToDolist
-
v-for
循环指令 -
v-on
绑定指令v-on:click
-
v-model
input的数据双向绑定
代码演示
<div id="app">
<input type="text" v-model='inputVal'>
<button v-on:click="add">添加</button>
<ul>
<li v-for=" item in list">{{ item }}</li>
</ul>
</div>
//
const vm = new Vue({
el: '#app',
data: {
list: ['a', 'b'],
inputVal: ''
},
methods:{
add() {
this.list.push(this.inputVal)
this.inputVal = ''
}
}
})
MVVM 设计模式
MVP模式 --- M-模型层 V-视图 P- 控制器
前端组件化
v-bind:
组件绑定值, 自组件可以用props 接收一个值
Vue.component()
全局组件化创建
- 也可以在实列上添加组件
vue基础精讲
— vue 的组件是一个实例组成的
基础详细
-
v-on
简写方式@
-
v-bind
简写方式:
注意: 凡事$ 的都是vue实例的方法和属性
简单的组件传值
子组件向父组件传值
this.$emit('delete')
使用$emit 方法向外(向上一层)传递一个事件
在父组件中监听delete事件
@delete='change'
在父组件的方法中写change
vue的生命周期的钩子
生命周期就是vue实例在某一个 时间点 会自动执行的函数
const vm = new Vue({
el: '#app',
data: {
test: 'hello world'
},
beforeCreate() {
console.log(this.$el)
console.log('beforeCreate')
},
created() {
console.log(this.$el)
console.log('created')
},
beforeMount() {
console.log(this.$el)
console.log('beforeMount')
},
mounted() {
console.log(this.$el)
console.log('mounted')
},
beforeUpdate() {
console.log('beforeUpdated')
},
updated() {
console.log('updated')
},
beforeDestroy() {
console.log('beforeDestroy')
},
destroyed() {
console.log('Destroyed')
}
})
vue的模版语法
v- 后接的内容都是js表达式
v-text
插值表达式
v-html
支持html内容
计算属性,和监听器
- computed 计算属性
- 内置缓存,提升性能、
- methods 方法实现
- watch 监听器
计算属性的setter 和 getter
计算属性中的get, 和set方法一般情况下不使用,如果需要改变计算属性的值,那么必须存在set方法
计算属性默认只有 getter ,不过在需要时你也可以提供一个 setter :
const vm = new Vue({
el: '#app',
data: {
firstName: 'zhu',
lastName: 'yaogeng'
},
computed: {
fullname: {
// getters
get() {
return this.firstName + this.lastName
},
// setter
set(value) {
const name = value.split(' ')
this.firstName = name[0]
this.lastName = name[1]
}
}
}
})
vue 中如何绑定样式
如何快速的实现样式绑定呢,
- class 方式
-
:class="{calssname: 变量}"
方式1; class的对象绑定 -
:class="[activeted]"
, 方式2;数组的方式
-
- style 方式
-
:style="{ color: 'red'}"
对象的方式 -
:style="[{ color: red}]"
数组方式
-
vue 的条件渲染
vue的条件渲染 ,v-if, v-show
V-if和v-show的区别
v-show
是display: none,v-if
是dom的删除和添加
在vue项目中,可以使用v-if 和 v-else
v-if="show === a"
方式使用
<input /> // dom 的复用。diff算法 , 需要加一个key值,解决条件该改变,dom没有被更新的问题
vue中的列表渲染
v-for
做数组循环.
不建议使用index作为key值
<div v-for='(item, index) in item' :key="index">
</div>
-
尝试修改数组的内容时,不能直接给数组赋值
1.直接更改数组的引用
2.可以用以下的改变数组,通过视图更改数组(变异方法)
- push
- pop
- shift
- unshift
- splice
- sort
- reverse
tmplate
模版占位符
- 语法中循环对象
<div v-for="(item, key, index) in obj"></div>
- 对象更改数据,也需要更改对象的引用方法
Vue的set方法
- 对象的方法
// 通过Vue.set方法更改值
Vue.set(vm.userInfo, 'address', 'beijing')
vm.$set(vm.userInfo, 'address', 'beijing')
- 数组的方法
Vue.set(vm.userInfo, 1, 5) // 通过数组下标的方法去使用
vm.$set(vm.userInfo, 2, 10)
深入理解vue组件的细节
is属性, 组件如果不能正常的渲染到指定的位置化,建议是用以下的问题
<tr is="row"></tr>
<body>
<div id="app">
<table>
<tbody>
<tr is='todo' :title='22'></tr>
<tr is='todo' title='成功插入'></tr>
</tbody>
</table>
</div>
<script>
Vue.component('todo', {
props: ['title'],
template: '<tr><td>{{ title }}</td></tr>'
})
const vm = new Vue({
el: '#app',
methods: {
}
})
</script>
</body>
组件中的data 必须是一个函数,函数中需要返回一个对象
data:function() {
return {
content: ''
}
}
// 因为子组件不仅只调用一次,组件会调用多次,为了让每一个字组件的都有一个独立的数据空间,避免数据污染
vue在必要的情况下,操作dom. 通过ref 来操作dom
- 标签通过ref 是获取一个标签
<div ref='hello'>
</div>
this.$refs.hello // 获取dom节点
- 如果是组件,通过ref,则获取的是组件的实例
this.$emit('change') // 实际上,可以看成是一个发布订阅模式
<!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.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<div ref='div'>{{ msg }}</div>
<do ref='one' @change='change'></do>
<do ref='two' @change='change'></do>
total-------<span>{{ total }}</span>
</div>
<script>
Vue.component('do', {
data: function() {
return {
count: 0
}
},
template: '<div v-text="count" @click="change"></div>',
methods: {
change() {
this.count = ++this.count
this.$emit('change')
}
}
})
const vm = new Vue({
el: '#app',
data: {
msg: 'hello world',
total: 0
},
methods: {
change() {
// console.log('ok')
this.total = this.$refs.one.count + this.$refs.two.count
}
},
mounted() {
console.log(this.$refs.div, 'ok')
}
})
</script>
</body>
</html>
详细介绍父子组件之间的传值
父组件如何向子组件传值
- 通过属性的方式传递
<counter :count="0"></counter>
props: ['count'],
template: '<div>{{ count }}</div>'
// 单向数据流---- , 可以改变自身的data, 如果直接改变props,vue会报警告
单向数据流 可以通过拷贝副本,进行
子组件向父组件传值,通过事件的$emit()方式
$emit('change', 参数)
vue组件参数校验 与非 Props特性
props 参数校验, props 特性,
props 特点:不会在dom标签上显示,父给子传,子能拿到
// 方式1
props: {
content: Number
}
// 方式2 多种类型
props: {
content: [Number, String]
}
// 方式3
props: {
content: {
type: String,
required: false, // 可以不传
default: '默认值',
validator: function(value) { // 对值进行校验
return (vlaue.length > 5) // 自定义校验器
}
}
}
非props 特性
- 特性:
- 外层传递,不接受的话,不能使用
- 非props 属性会展示在子组件最外层标签上
给组件绑定原生事件
给子组件绑定一个事件的话,绑定的是一个自定义的事件,
- 方式1
- 自定义事件如何触发:
this.$emit('click')
- 自定义事件如何触发:
- 方式2
-
@click.native
变成原生的点击事件,不是内部组件向外触发的自定义事件
-
非父子组件的传值
-
方式: 组件中逐层传递
-
两个组件传值,但不具备父子组件的关系
- vuex
- 总线机制(bus/总线/发布订阅/观察者模式)
Vue.prototype.bus = new Vue()
// 每个vue的实例都有一个bus的属性
Vue.component('child', {
data: function() {
return {
selfContent: this.content
}
},
props: {
content: String
},
template: '<div></div>',
methods: {
handleClick: function() {
this.bus.$emit('change', this.content)
}
},
mounted: function() {
// this
var that = this
this.bus.$on('change', funciton(msg) {
this.selfContent = msg
})
}
})
Vue 中使用插槽
插槽
-
方式1: 使用
v-html
<com content='<p>hello</p>'></com>
-
方式2: 使用
slot
语法-
<slot>默认值</slot>
可以存在默认值 -
具名插槽:同样具名插槽也有默认值
- 父组件
<div slot='header'></div>
- 子组件
<slot name='header'></slot>
-
demo
<body>
<div id="app">
<do content='<p>您好,世界</p>'>
<p slot='header'>我用自己的插槽, 可以滚蛋了</p>
<p slot='footer'>我用自己的插槽, 可以滚蛋了</p>
</do>
</div>
<script>
Vue.component('do', {
props: ['content'],
template: `<div>
<slot name='header'>这是插槽</slot>
<h1> hello world </h1>
<p v-html='content'></p>
<slot name='footer'>这是插槽</slot>
</div>`
})
const vm = new Vue({
el: '#app',
data: {
}
})
</script>
</body>
. vue 的作用域插槽
子组件负责数据,父组件负责显示内容, 当组件做循环,
- 作用域插槽必须是
template
开始和结尾, 同时使用slot-scope=''
接收
<child>
<template slot-scope='props'>
<h1>{{ props.item }}</h1>
</template>
</child>
Vue.component("child", {
data: funciton() {
return {
list: [1, 2, 3, 4]
}
},
template: `<div>
<slot
v-for="item of list"
:item=item
></slot>
</div>`
})
动态组件和v-once
有一个属性 :is='组件名'
组件创建,和销毁浪费性能。 使用v-once 能提高性能效率
- 方式1
<body>
<div id="app">
<child-one v-if='type === "child-one"'></child-one>
<child-two v-if='type === "child-two"'></child-two>
<button @click='change'>改变</button>
</div>
<script>
Vue.component('child-one', {
template: '<div>子组件一</div>'
})
Vue.component('child-two', {
template: '<div>子组件二</div>'
})
const vm = new Vue({
el: '#app',
data: {
type: 'child-one'
},
methods: {
change() {
this.type = this.type === 'child-one' ? 'child-two' : 'child-one'
}
}
})
</script>
</body>
- 方式2
<body>
<div id="app">
<component :is='type'></component>
<button @click='change'>改变</button>
</div>
<script>
Vue.component('child-one', {
template: '<div v-once>子组件一</div>'
})
Vue.component('child-two', {
template: '<div v-once>子组件二</div>'
})
const vm = new Vue({
el: '#app',
data: {
type: 'child-one'
},
methods: {
change() {
this.type = this.type === 'child-one' ? 'child-two' : 'child-one'
}
}
})
</script>
</body>
Vue Css的动画原理
当vue中,被transition 标签的元素添加动画class ,默认前缀v-
-
fade-enter
进入 第一帧 -
fade-enter-active
进入第二帧 -
fade-leave
离开第一帧 -
fade-leave-activ
离开第二帧
.fade-enter {
opacity: 0;
}
.fade-enter-active {
transition: opacity 2s;
}
.fade-leave-to {
opacity: 0;
}
.fade-leave-active {
transition: opacity 2s;
color: red;
}
在vue中使用animate.css库
借用keyframes
@keyframes bounce-in {
0% {
transform: scale(0);
}
50% {
transform: scale(1.5);
}
100% {
transform: scale(1)
}
}
.fade-enter-active {
transform-origin: left center;
animaition: bounce-in 1s;
}
.fade-leave-active {
transform-origin: left center;
animaition: bounce-in 1s reverse;
}
自定义命名规范
<transition
name='fade'
enter-active-class='active'
leave-active-class='leave'
></transition>
Animatie.css 库
class 类名必须加animated 动画
<transition
name='fade'
enter-active-class='animated 类名'
leave-active-class='animated 类名'
></transition>
- 必须使用自定class
- 必须有aninated 这个类名
<div id="app">
<transition name='fade'
enter-active-class='animated flash red'
leave-active-class='animated shake blue'
>
<h1 v-show='show'>hello, world!</h1>
</transition>
<button @click='change'>改变</button>
</div>
vue 中如何使用过渡和动画
appear
appear-active-class='animated swing'
<transitiion
appear
appear-active-class='animated swing'
></transitiion>
手动结束时常
type='transition'
或者 :duration='10000'
自定义播放时长
或者:duration="{enter: 3000, leave: 1000}"
入场动画和出场动画时常
vue中的js动画和velocity.js的结合
-
@before-enter='handleBeforeEnter'
入场动画 -
@enter='handleEnter'
-
@after-enter='handleAfterEnter'
-
@before-leave
…. 出场动画
methods: {
handleBeforeEnter: function(el) {
el.style.color='red'
},
handleEnter: function(el, done) {
setTimeout(() => {
el.style.color ='green'
done() // 告诉vue回调函数被执行完了
}, 2000)
},
handleAfterEnter: function(el) {
el.style.color = '#0000'
}
}
js常用的动画库 velocity.js
多个元素和组件之的过渡动画
- 元素关键点位置: key值设置
- transition: 上的mode设置
<style>
.fade-enter, .fade-leave-to {
opacity: 0;
}
.fade-enter-active, .fade-leave-active {
transition: opacity 1s;
}
</style>
<body>
<div id="app">
<transition name='fade' mode='out-in'>
<div v-if='show' key='1'>hello, world!</div>
<div v-else key='2'>您好,世界!</div>
</transition>
<button @click='change'>改变</button>
</div>
<script>
const vm = new Vue({
el: '#app',
data: {
show: true
},
methods: {
change() {
this.show = !this.show
}
}
})
</script>
</body>