Vue学习总结-入门
MVC:后端开发概念,模块视图
MVVM:前段视图层概念
vue代码和MVVM对应关系
v-cloak,v-text,v-html
v-cloak:解决插值表达式闪烁问题,只会替换当前占位符,不会把整个元素内容清空
v-text:默认无闪烁问题;会覆盖元素中原本内容
v-html:以html格式解析数据输出,默认无闪烁问题;会覆盖元素中原本内容
v-bind
书写格式2种:
v-on,缩写是@
跑马灯
<template>
<div class="hello">
<input type="button" value="开始" v-on:click="lang">
<input type="button" value="结束" @click="stop">
<h4>{{msg}}</h4>
</div>
</template>
<script>
export default {
name: 'HelloWorld',
data () {
return {
msg: 'Welcome to Your Vue.js App',
intervalId:null
}
},
methods:{
lang() {
if (this.intervalId != null) return;
this.intervalId = setInterval( () => {
var start = this.msg.substring(0,1)
var end = this.msg.substring(1)
this.msg = end+start
},400)
// console.log(this.msg)
},
stop(){
clearInterval(this.intervalId)
this.intervalId = null;
}
}
}
</script>
<style scoped>
</style>
事件修饰符
<template>
<!-- <div class="inner" @click="divHandler">-->
<!-- <!–stop 阻止冒泡–>-->
<!-- <input type="button" value="阻止冒泡" v-on:click.stop="btnHandler">-->
<!-- <br/>-->
<!-- <!–prevent 阻止默认行为–>-->
<!-- <a href="http://baidu.com" @click.prevent="linkClick">有问题去百度</a>-->
<!-- <br/>-->
<!-- <!–capture 实现捕获触发事件机制–>-->
<!-- <div class="inner" @click.capture="divHandler">-->
<!-- <input type="button" value="捕获" v-on:click="btnHandler">-->
<!-- <br/>-->
<!--self 实现只有点击当前元素才会触发事件-->
<!-- <div class="inner" @click.self="divHandler">-->
<!-- <input type="button" value="点击当前元素" v-on:click="btnHandler">-->
<!-- <br/>-->
<!--once 只触发一次事件函数-->
<!-- <div class="inner" @click.self="divHandler">-->
<!-- <a href="http://baidu.com" @click.prevent.once="linkClick">有问题去百度</a>-->
<!-- <br/>-->
<!-- 演示stop和self区别-->
<!-- <div class="outer" @click="div2Handler">-->
<!-- <div class="inner" @click="divHandler">-->
<!-- <input type="button" value="开始" v-on:click.stop="btnHandler">-->
<!-- <br/>-->
<!-- </div>-->
<!-- </div>-->
<!-- self只会阻止自己身上冒泡行为的触发,不会真正阻止冒泡行为的触发-->
<div class="outer" @click="div2Handler">
<div class="inner" @click.self="divHandler">
<input type="button" value="开始" v-on:click="btnHandler">
<br/>
</div>
</div>
</template>
<script>
export default {
name: 'HelloWorld',
data () {
return {
msg: 'Welcome to Your Vue.js App',
}
},
methods:{
divHandler(){
console.log('触发了inner divv的点击事件')
},
btnHandler(){
console.log('触发了btn divv的点击事件')
},
linkClick(){
console.log('触发了链接点击事件')
},
div2Handler(){
console.log('触发了out div2的点击事件')
}
}
}
</script>
<style scoped>
.inner{
height: 150px;
background-color: #42b983;
}
.outer{
padding:40px;
background-color:red;
}
</style>
v-model实现表单元素的数据双向绑定
<template>
<!-- self只会阻止自己身上冒泡行为的触发,不会真正阻止冒泡行为的触发-->
<div >
<h4>{{msg}}</h4>
<!-- v-bind只能实现数据单向绑定,从M自动绑定到V,无法实现数据双向绑定-->
<!-- <input type="text" :value="msg" style="width: 100%;">-->
<!-- v-model,可以实现表单元素和model中数据的双向数据绑定-->
<!-- 注意:v-model只能应用在表单元素中-->
<!-- input (radio,text,address,email..) select checkbox textarea-->
<input type="text" v-model="msg" style="width: 100%;">
</div>
</template>
<script>
export default {
name: 'HelloWorld',
data () {
return {
msg: 'Welcome to Your Vue.js App',
}
},
methods:{
}
}
</script>
<style scoped>
.inner{
height: 150px;
background-color: #42b983;
}
.outer{
padding:40px;
background-color:red;
}
</style>
v-model实现简易计算器
<template>
<div >
<input type="text" v-model="n1" style="width: 100%;">
<select v-model="opt">
<option value="+">+</option>
<option value="-">-</option>
<option value="*">*</option>
<option value="/">/</option>
</select>
<input type="text" v-model="n2">
<input type="button" value="=" @click="calc">
<input type="text" v-model="result">
</div>
</template>
<script>
export default {
name: 'HelloWorld',
data () {
return {
n1:0,
n2:0,
result:0,
opt:'+'
}
},
methods:{
calc(){
// switch (this.opt) {
// case '+':
// this.result = parseInt(this.n1)+parseInt(this.n2);
// break;
// case '-':
// this.result = parseInt(this.n1) - parseInt(this.n2);
// break;
// case '*':
// this.result = parseInt(this.n1)*parseInt(this.n2);
// break;
// case '/':
// this.result = parseInt(this.n1)/parseInt(this.n2);
// break;
//
// }
//注意:这是投机取巧方式,开发中尽量少用
var codeStr = ' parseInt(this.n1)' + this.opt + 'parseInt(this.n2)'
this.result = eval(codeStr)
}
}
}
</script>
<style scoped>
</style>
vue中通过属性绑定为元素设置class类样式
<template>
<div >
<!-- <h1 class=" red thin">这是一个很大很大的H1</h1>-->
<!-- 方式1,直接传递一个数组,注意:这里的class需要使用v-bind做数据绑定-->
<!-- <h1 :class=" ['thin','italic']">这是一个很大很大的H1</h1>-->
<!--在数组中使用三元表达式-->
<!-- <h1 :class=" ['thin','italic',flag?'active':'']">这是一个很大很大的H1</h1>-->
<!-- 在数组中使用对象代替 三元表达式,提供效率-->
<!-- <h1 :class=" ['thin','italic',{'active':flag}]">这是一个很大很大的H1</h1>-->
<!-- 在为calss使用v-bind绑定对象时候,对象属性是类名,
由于对象属性可带引号,也可不带引号,所以这里没有写引号
属性的值是一个标识符-->
<h1 :class=" classObj">这是一个很大很大的H1</h1>
</div>
</template>
<script>
export default {
name: 'HelloWorld',
data () {
return {
flag:true,
classObj:{red:true,thin:true,italic:true,active:false}
}
},
methods:{
}
}
</script>
<style scoped>
.red{
color: red;
}
.thin{
font-weight: 200;
}
.italic{
font-style: italic;
}
.active{
letter-spacing: 0.5em;
}
</style>
vue中的样式style
<!-- 对象就是无序键值对集合-->
<h1 :style="styleObj ">这是一个H1</h1>
//数组形式
<h1 :style="[styleObj,styleObj2] ">这是一个H1</h1>
data () {
return {
styleObj:{color:'red', 'font-weight':280},
styleObj2:{'font-style':'italic'}
}
v-for循环普通数组
<p>{{list[0]}}</p>
<p v-for="item in list">{{item}}</p>
<p v-for="(item,i) in list">索引值:{{i}}-----每一项:{{item}}</p>
data () {
return {
list:[1,2,3,4,5,6],
}
},
v-for循环对象数组
<p v-for="(item,i) in list">{{item.id}}--{{item.name}}---{{i}}</p>
list:[
{id:1,name:'zs'},
{id:2,name:'zs2'},
{id:3,name:'zs3'},
{id:4,name:'zs4'},
],
v-for循环对象
<!-- 注意,在遍历对象键值对时候,除了有val key,在第三个位置还有索引-->
<p v-for="(val,key,i) in user">{{val}}---{{key}}---{{i}}</p>
user:{
id:1,
name:'托尼',
gender:'男'
}
v-for迭代数字
<!-- in后面放普通数组,对象数组,对象,数组-->
<!-- 如果使用v-for迭代数字,前面的count从1开始-->
<p v-for="count in 10">这是第{{count}}次循环</p>
v-for使用key注意事项
<div>
<label>Id:
<input type="text" v-model="id">
</label>
<label>Name:
<input type="text" v-model="name">
</label>
<input type="button" value="添加" @click="add">
</div>
<!-- 注意v-for循环时,key属性只能使用number获取string-->
<!-- 注意key在使用时候,必须使用v-bind属性绑定的形式,指定key值-->
<!-- 在组件中使用v-for循环的时候,或者在一些特殊情况中,如果v-for有问题,
必须在使用v-for的同时指定唯一'字符串/数组' 类型:key值-->
<p v-for="item in list" :key="item.id">
<input type="checkbox">{{item.id}}---{{item.name}}
</p>
</div>
data () {
return {
id:'',
name:'',
list:[
{id:1,name:'李四'},
{id:2,name:'嬴政'},
{id:3,name:'赵高'},
{id:4,name:'韩飞'},
]
}
},
methods:{
add(){
this.list.unshift({id : this.id, name : this.name})
}
}
v-if和v-show
<div >
<!-- <input type="button" @click="toggle">-->
<input type="button" @click="flag=!flag">
<!-- v-if特点:每次都会从新删除或创建元素-->
<!-- v-show特点:每次不会从新删除或创建元素,只是切换了元素的display:none样式-->
<!-- v-if有较高的切换性能消耗-->
<!-- v-show有较高的初始渲染消耗-->
<!-- 如果元素频繁切换,不要使用v-if,推荐使用v-show-->
<!-- 如果元素可能永远不会被显示出来被用户看到,则推荐使用v-if-->
<h3 v-if="flag">这是v-if控制</h3>
<h3 v-show="flag">这是v-show控制</h3>
</div>
data () {
return {
flag:true,
}
},
methods:{
toggle(){
this.flag = !this.flag;
}
}
品牌列表案例1,数据添加和删除,过滤
<template>
<div>
<div class="panel panel-primary">
<div calss="panel-heading">
<h3 class="panel-title">添加品牌</h3>
</div>
<div class="panel-body form-inline">
<label>
Id:
<input type="text" class="form-control" v-model="id">
</label>
<label>
Name:
<input type="text" class="form-control" v-model="name">
</label>
<!-- 在Vue中,使用事件绑定机制,为元素指定处理函数的时候,
如果加了()可以给函数传参-->
<input type="button" value="添加" class="btn btn-primary" @click="add()">
<label>
搜索关键字:
<input type="text" class="form-control" v-model="keywords">
</label>
</div>
</div>
<div>
<table class="table table-bordered table-hover table-striped">
<thead>
<tr>
<th>Id</th>
<th>Name</th>
<th>Ctime</th>
<th>Operation</th>
</tr>
</thead>
<tbody>
<tr v-for="item in search(keywords)" :key="item.id">
<td>{{item.id}}</td>
<td v-text=item.name></td>
<td v-text=item.ctime></td>
<td><a href="" @click.prevent="del(item.id)">删除</a></td>
</tr>
</tbody>
</table>
</div>
</div>
</template>
<script>
export default {
// name: 'HelloWorld',
data() {
return {
id: '',
name: '',
keywords: '',
list: [
{id: 1, name: '奔驰', ctime: new Date()},
{id: 2, name: '宝马', ctime: new Date()},
]
}
},
methods: {
add() {
var car = {id: this.id, name: this.name, ctime: new Date()};
this.list.push(car);
},
del(id) {
// this.list.some((item,i)=>{
// if(item.id == id){
// this.list.splice(i,1)
// return true;
// }
// })
var index = this.list.findIndex(item => {
if (item.id == id) {
return true;
}
})
this.list.splice(index, 1)
},
search(keywords) {
// var newList = [];
// this.list.forEach(item=>{
// if(item.name.indexOf(keywords) != -1){
// newList.push(item)
// }
//
// })
// return newList;
//forEach some filter findIndex都属于数组的新方法,都会对数组每一项进行遍历
var newList = this.list.filter(item =>{
// if(item.name.indexOf(keywords) != -1)
if(item.name.includes(keywords)){
return item
}
})
return newList;
}
}
}
</script>
品牌列表案例2,过滤器
<p>{{msg | componentFilter('可爱')}}</p>
//组件内部过滤器
filters:{
componentFilter:function(msg, value){
return msg.replace(/美丽/g, value)
}
// <!-- 定义一个Vue全局过滤器-->
Vue.filter('msgFormat', function (msg,arg) {
return msg.replace(/美丽/g, arg)
})
//日期格式转换
filters: {
dateFormat:function (datestr,pattern = '') {
var dt = new Date(datestr)
var y = dt.getFullYear()
var m = dt.getMonth() + 1
var d = dt.getDate()
// return `${y}-${m}-${d}`
if( pattern.toLowerCase() === 'yyyy-mm-dd'){
return `${y}-${m}-${d}`
}else{
var hh =dt.getHours()
var mm = dt.getMinutes()
var ss = dt.getSeconds()
return `${y}-${m}-${d} ${hh}:${mm}:${ss}`
}
}
}
字符串的padStart方法使用
var hh =dt.getHours().toString().padStart(2,'0')
自定义按键修饰符及自定义键盘修饰符
<label>
Name:
<input type="text" class="form-control" v-model="name" @keyup.enter="add">
</label>
<label>
Name:
<input type="text" class="form-control" v-model="name" @keyup.f2="add">
</label>
Vue.config.keyCodes.f2 = 113;