day21
1. Vue实例
2. Vue视图
2.1 插值
{{ }}
v-text
v-html
v-once
2.2 绑定属性
v-bind
:
2.3 指令
v-*
2.4 条件渲染
v-if
v-else
v-else-if
v-show
2.5 列表渲染
v-for
key
2.6 样式操作
class
<p :class="{类名:布尔值}">
<p :class="['类名','类名']">
<p :class="'类名'">
style
<p :style="{属性名:值,属性名:值}">
<p :style="[{}, {}, {}]">
2.7 事件
@事件名="代码"
@事件名="方法名"
@事件名="方法名($event, 100, 200)"
.stop
.prevent
.self
.capture
.once
.passive
# 键盘修饰符 用于 键盘事件 keyup keydown keypress
@keyup.13 只有回车键 才触发
.enter
.tab
.space
.esc
.delete
.up
.down
.left
.right
# 系统按键修饰符
@keyup.ctrl.65
.shift
.alt
.meta
2.8 表单
v-model 指令
文本 input:text:password:email:number... textareat
checkbox 单个(绑定给布尔值) 多个(绑定给数组)
radio (绑定给value值)
select (绑定给option的value值) (多选 绑定给数组)
.lazy 失去焦点并且修改vlaue 采取修改v-model绑定的变量值
.trim
.number 转为数字
day21
3 组件 (component)
3.1 组件定义
VUE是组件化开发,整个项目由各种组件组成
什么是组件?
每个Page就是一个组件 (注册组件、登录组件、商品列表组件) 局部
页面的组成部分 (轮播图,选项卡,下拉菜单...) 全局
一个组件就是一个 vue实例
根实例(new Vue()) 其实根实例 就是根组件
组件的组成
data
methods
computed
watch
template 模板
钩子函数
...
3.2 组件基础
注册组件
Vue.component(组件名, {
data: function(){
return {
//Vue 变量
}
},
methods: {
//方法
},
就是Vue实例的选项
template: 'html'
})
组件的使用
<my-button> </my-button>
使用组件的时候 会创建vue实例
类似于 html 自定义元素
每个组件都有独立的作用域
<my-button> </my-button>
<my-button> </my-button>
<my-button> </my-button>
<my-button> </my-button>
组件的模板
模板字符串
内联模板 inline-template
x-template
单文件组件 (最优 使用成本较高) render 渲染函数 代替 template
注意:模板内 必须有个根元素
全局组件和局部组件
Vue.component(组件, {}) 全局组件 在哪都可用
//Vue实例中
{
template:'自己里面的局部, 只能在这用'
//局部
components: {
'组件名': {},
'组件名': {},
'组件名': {}
}
}
局部组件:在全局组件中定义的只能在此全局中使用
父子组件:根据调用位置决定
全局组件&局部组件:根据定义位置
父组件向子组件通信
子组件:props: ['message'],
父组件:<thumb v-for='item in productList' :product="item" :key='item.productName'></thumb>
父组件的值通过props传值子组件
子组件向父组件通信
子组件:this.$emit('add', 2)
父组件:<button-count @add="addFn($event)" @del="delFn"></button-count>
子组件通过$emit向父组件发送事件和参数
todolist用vue实现
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>todoList</title> <style> #app { margin:100px auto 0; width:600px; } .input-box { font-size:0; } .input-box input { box-sizing: border-box; width:500px; font-size:16px; border:1px solid #ccc; padding:10px; line-height: 18px; } .input-box button { width:100px; padding:10px; font-size:16px; border:1px solid #ccc; background: #f5f5f5; cursor: pointer; line-height: 18px; border-left:none; } ul { list-style: none; margin:0; padding:0; } .todo-list { margin-top:20px; } .todo-list li{ border:1px solid #ccc; padding:10px; margin-bottom:10px; font-size:0; } .todo-list i { margin-right:20px; display: inline-block; width:16px; height:16px; border:1px solid #ccc; cursor: pointer; vertical-align: -5px; } .todo-list p { width:500px; display: inline-block; font-size:16px; margin:0; line-height: 20px; } .todo-list span { display:inline-block; height:20px; line-height: 20px; width:40px; cursor: pointer; color:red; font-size:16px; } .done-list { margin-top:20px; } .done-list li{ border:1px solid #ccc; padding:10px; margin-bottom:10px; background: #999; color:#ccc; cursor: not-allowed; text-decoration: line-through; } .edit-input { width:576px; font-size:16px; line-height: 20px; border:1px solid #eee; } </style> </head> <body> <div id="app"> <div class="input-box"> <input type="text" v-model.trim="newTodo" placeholder="请输入代办事项"> <button @click="addTodo">添 加</button> </div> <div class="todo-list"> <ul> <li v-for="(todo,index) in todoList" :key="index"> <div v-show="isEditTodo(index)"> <input type="text" class="edit-input" :value="todo" @change="execEditTodo(index, $event)"> </div> <div v-show="!isEditTodo(index)"> <i @click="addDone(index)"></i> <p @dblclick="editTodoFn(index)">{{ todo }}</p> <span @click="deleteTodo(index)">×</span> </div> </li> </ul> </div> <h3>已完成</h3> <div class="done-list"> <ul> <li v-for="done in doneList" :key="done">{{ done }}</li> </ul> </div> </div> <script src="../dist/js/vue.js"></script> <script> new Vue({ el:"#app", data: { todoList: ['今天代码敲三遍', '晚上和小莉莉去喝酒'], doneList: [], newTodo:'', editTodo: null }, methods: { addTodo() { //如果输入框是空的,不执行 if (this.newTodo.length === 0) { return; } //添加内容到 代办事项 this.todoList.push(this.newTodo) //清空输入框 this.newTodo = ''; }, deleteTodo(index) { this.todoList.splice(index, 1) }, addDone(index) { //把内容添加到 doneList this.doneList.push(this.todoList[index]) //从todoList删掉 this.deleteTodo(index); }, isEditTodo(index){ return this.editTodo === index; }, editTodoFn(index) { this.editTodo = index; }, execEditTodo(index, event) { Vue.set(this.todoList, index, event.target.value) this.editTodo = null; } } }) </script> </body> </html>
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>todoList</title> <style> #app { margin:100px auto 0; width:600px; } .input-box { font-size:0; } .input-box input { box-sizing: border-box; width:500px; font-size:16px; border:1px solid #ccc; padding:10px; line-height: 18px; } .input-box button { width:100px; padding:10px; font-size:16px; border:1px solid #ccc; background: #f5f5f5; cursor: pointer; line-height: 18px; border-left:none; } ul { list-style: none; margin:0; padding:0; } .todo-list { margin-top:20px; } .todo-list li{ border:1px solid #ccc; padding:10px; margin-bottom:10px; font-size:0; } .todo-list i { margin-right:20px; display: inline-block; width:16px; height:16px; border:1px solid #ccc; cursor: pointer; vertical-align: -5px; } .todo-list p { width:500px; display: inline-block; font-size:16px; margin:0; line-height: 20px; } .todo-list span { display:inline-block; height:20px; line-height: 20px; width:40px; cursor: pointer; color:red; font-size:16px; } .done-list { margin-top:20px; } .done-list li{ border:1px solid #ccc; padding:10px; margin-bottom:10px; background: #999; color:#ccc; cursor: not-allowed; text-decoration: line-through; } .edit-input { width:576px; font-size:16px; line-height: 20px; border:1px solid #eee; } </style> </head> <body> <div id="app"> <div class="input-box"> <input type="text" v-model.trim="newTodo" placeholder="请输入代办事项"> <button @click="addTodo">添 加</button> </div> <div class="todo-list"> <ul> <li v-for="(todo,index) in todoList" :key="index"> <div v-show="todo.isEdit"> <input type="text" class="edit-input" v-model.lazy="todo.content" @blur="doneEditTodo(todo)" v-todo-focus="todo.isEdit"> </div> <div v-show="!todo.isEdit"> <i @click="addDone(index)"></i> <p @dblclick="editTodo(todo)">{{ todo.content }}</p> <span @click="deleteTodo(index)">×</span> </div> </li> </ul> </div> <h3>已完成</h3> <div class="done-list"> <ul> <li v-for="done in doneList" :key="done">{{ done }}</li> </ul> </div> </div> <script src="../dist/js/vue.js"></script> <script> new Vue({ el:"#app", data: { todoList: [ {content:'今天代码敲三遍', isEdit: false}, {content: '晚上和小丽丽去钓鱼', isEdit: false} ], doneList: [], newTodo:'', }, methods: { addTodo() { //如果输入框是空的,不执行 if (this.newTodo.length === 0) { return; } //添加内容到 代办事项 this.todoList.push({content:this.newTodo, isEdit:false}) //清空输入框 this.newTodo = ''; }, deleteTodo(index) { this.todoList.splice(index, 1) }, addDone(index) { //把内容添加到 doneList this.doneList.push(this.todoList[index].content) //从todoList删掉 this.deleteTodo(index); }, editTodo(todo){ todo.isEdit = true; }, doneEditTodo(todo) { todo.isEdit = false; } }, directives: { 'todo-focus': function(el, binding) { if (binding.value) { el.focus(); //获取焦点 } } } }) </script> </body> </html>
轮播图用vue实现
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>轮播图</title> <style> .play { margin:0px auto 0px; width:1226px; height:460px; overflow: hidden; position: relative; } .play img { display: block; width:1226px; height:460px; } .img-wrapper a { position: absolute; left:0; top:0; width:1226px; height:460px; opacity: 0; transition: opacity .5s; } .img-wrapper a.active { opacity: 1; } .icon-wrapper{ position: absolute; z-index: 100; bottom:10px; width:100%; text-align: center; font-size: 0; cursor: pointer; } .icon-wrapper span { display: inline-block; width:10px; height:10px; border:1px solid #fff; border-radius:6px; margin:0px 5px; transition: opacity .5s; } .icon-wrapper span.active { background: rgba(255,255,255,.6) } .slider { position: absolute; z-index: 2000; width:30px; height:100px; background: rgba(0,0,0,.5); text-align: center; line-height: 100px; top:50%; transform: translate(0,-50%); color:#fff; cursor: pointer; opacity: 0; transition: .5s; } .left{ left:0; } .right{ right:0; } .play:hover .slider { opacity: 1; } </style> </head> <body> <div id="app"> <div class="play" @mouseenter="onEnterFn" @mouseleave="onLeaveFn"> <div class="img-wrapper"> <a href="#" v-for="img,index in imgList" :class="{active:isActive(index)}"> <img :src="img"> </a> </div> <div class="icon-wrapper"> <span v-for="(img, index) in imgList" :class="{active:isActive(index)}" @mouseenter="controlImg(index)">{{index+1}}</span> </div> <div class="slider-wrapper"> <span class="slider left" @click="prev()"> < </span> <span class="slider right" @click="next()"> > </span> </div> </div> </div> <script src="../dist/js/vue.js"></script> <script> let app = new Vue({ el:'#app', data: { imgList: ['../dist/images/play01.jpg','../dist/images/play02.jpg','../dist/images/play03.jpg','../dist/images/play04.jpg','../dist/images/play05.jpg'], activeImg:0, //当前要显示的图片 delay:5000, //轮播时间间隔 timer: null, //定时器的返回值 }, methods: { //判断是否是激活状态 isActive(index){ return this.activeImg === index; }, //定时函数 runPlay(){ this.activeImg ++; if (this.activeImg >= this.imgList.length) { this.activeImg = 0; } }, //鼠标悬停到轮播图 onEnterFn(){ //停止定时 clearInterval(this.timer) }, //鼠标离开轮播图 onLeaveFn(){ //重新定时 this.timer = setInterval(this.runPlay, this.delay) }, //鼠标悬停在 控制按钮上 controlImg(index){ this.activeImg = index; }, //上一个 prev(){ this.activeImg --; if (this.activeImg < 0) { this.activeImg = this.imgList.length - 1 } }, //下一个 next() { this.activeImg ++; if (this.activeImg >= this.imgList.length) { this.activeImg = 0; } } }, //钩子 vue实例挂载到元素上 mounted(){ this.timer = setInterval(this.runPlay, this.delay) } }); </script> </body> </html>