初识Vue笔记
Vue.js
Vue.js初体验
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
<h2>{{message}}</h2>
</div>
<script type="text/javascript" src="https://cdn.staticfile.org/vue/2.2.2/vue.min.js"></script>
<script>
new Vue({
el:"#app",
data:{
message:"Vue.js初体验",
}
})
</script>
</body>
</html>
vue的列表展示
使用v-for遍历data中的列表
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
<ul>
<li v-for="item in movies">{{item}}</li>
</ul>
</div>
<script type="text/javascript" src="https://cdn.staticfile.org/vue/2.2.2/vue.min.js"></script>
<script>
new Vue({
el:"#app",
data:{
message:"Vue.js初体验",
movies:['星际穿越','大话西游','少年派','盗梦空间'],
}
})
</script>
</body>
</html>
效果:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5z8P8utm-1603358537500)(C:\Users\asus\AppData\Roaming\Typora\typora-user-images\image-20200905233643497.png)]
计数器小案例
@click="increment"是v-on:click="increment"的语法糖写法。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
<h2>当前计数{{counter}}</h2>
<button @click="increment">+</button>
</div>
<script type="text/javascript" src="https://cdn.staticfile.org/vue/2.2.2/vue.min.js"></script>
<script>
new Vue({
el:"#app",
data:{
counter:0,
},
methods: {
increment:function(){
this.counter++
},
},
})
</script>
</body>
</html>
插值操作-指令使用
命令 | 含义 |
---|---|
v-once | 动态内容确定后不能被改变 |
v-html | 可以对内容为html源码的动态内容渲染 |
v-text | 动态内容覆盖标签里的内容 |
v-pre | 对表达式不加以渲染 |
v-cloak | 渲染完成后再显示,避免出现闪动 |
v-bind的基本使用
使用v-bind动态绑定html中的属性。
:src='img’是v-bind:src='img’的语法糖写法。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
<img v-bind:src="img" alt="">
</div>
<script type="text/javascript" src="https://cdn.staticfile.org/vue/2.2.2/vue.min.js"></script>
<script>
new Vue({
el:"#app",
data:{
img:"https://img.lovebuy99.com/uploads/200905/15-200Z5194GM38.jpg"
},
methods: {
increment:function(){
this.counter++
},
},
})
</script>
</body>
</html>
绑定href:url为data中的数据
<a :href="url"></a>
动态绑定class:
<h2 v-bind:class={类名,Boolean1,类名,Boolean2}></h2>
使用data数据域定义的Boolean1和Boolean2动态改变是否包含对应的class。
绑定方式分为数组语法和对象语法。如果过于复杂,可以使用methods或者computed;
动态绑定style:
<h2 v-bind:style={属性名,属性值}></h2>
可以使用methods。
计算属性
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
<h2>{{getfullName}}</h2>
</div>
<script type="text/javascript" src="https://cdn.staticfile.org/vue/2.2.2/vue.min.js"></script>
<script>
new Vue({
el:"#app",
data:{
firstName:"Lebron",
lastName:"JAmes",
},
computed: {
getfullName(){
return this.firstName+' '+this.lastName
}
},
})
</script>
</body>
</html>
计算属性和methods的比较:
methods中的方法在每次调用的时候都会重新执行,而计算属性会将计算结果进行缓存,在一个页面中可以多次复用。
v-on的参数传递
<div id="app">
<!-- 事件调用的方法没有参数 -->
<!-- 括号存在与否没有影响 -->
<button @click="btn1click()">按钮1</button>
<button @click="btn1click">按钮2</button>
<!-- 事件定义时,写函数时加了括号,方法本身是需要参数的而没有传参 -->
<!-- 结果会产生一个undefined类型的对象 -->
<button @click="btn2click(abc)">按钮3</button>
<button @click="btn2click()">按钮4</button>
<!-- 如果省略了括号会产生一个事件对象 -->
<button @click="btn2click">按钮4</button>
<!-- 在调用方法时,如果需要event对象,同时也需要其它对象,
可以使用$event来获取event对象。
-->
<button @click="btn3click(变量,$event)">按钮5</button>
</div>
v-on的修饰符
.stop | 调用event.stopPropagation() |
---|---|
.prevent | 调用event.preventDefalut() |
.native | 监听组件根元素的原生事件 |
.once | 只触发一次回调 |
.{KeyCode|KeyAlias} | 只当事件是从特定的键触发才回调 |
<div id="app">
<!-- 停止冒泡 -->
<button @click.stop="doThis"></button>
<!-- 阻止默认行为 -->
<button @click.prevent="doThis"></button>
<!-- 阻止默认行为,没有参数 -->
<form @submit.prevent></form>
<!-- 串联修饰符 -->
<button @click.stop.prevent="doThis"></button>
<!-- 键修饰符,键别名 -->
<input @Keyup.enter='omEnter'>
<!-- 键修饰符,键代码 -->
<input @Keyup.13="onEnter">
<!-- 只触发一次回调 -->
<button @click.once="doThis"></button>
</div>
v-if和v-else
<div id="app">
<h2 v-if="isTure"> //isTure是一个Boolean值,可以是计算结果,表达式
Vue.js
</h2>
</div>
<div id="app">
<h2 v-if="score>90">优秀</h2>
<h2 v-else-if="score>80">良好</h2>
<h2 v-else-if="score>60">及格</h2>
<h2 v-else>不及格</h2>
</div>
登陆切换小案列
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
<span v-if="isUser">
<label for="username">用户账号</label>
<input type="text" id="username" placeholder="用户名">
</span>
<span v-else>
<label for="email">用户邮箱</label>
<input type="text" id="email" placeholder="用户邮箱">
</span>
<button @click="change">切换</button>
</div>
<script type="text/javascript" src="https://cdn.staticfile.org/vue/2.2.2/vue.min.js"></script>
<script>
new Vue({
el:"#app",
data:{
isUser:true
},
methods: {
change(){
this.isUser=!this.isUser
},
},
})
</script>
</body>
</html>
v-if和v-show的区别
当两者后面的值都为true时,二者并没有区别。但当二者后面的值为false时,v-if修饰的元素不存在于dom中,v-show的条件为false时,只是给元素添加一个行内样式,diaplay:none
v-for遍历
<div id="app">
<!-- info 为data中的对象 -->
<!-- 在遍历对象过程中,如果之后的一个值,那么获得是value -->
<ul>
<li v-for="item in info">{{item}}</li>
</ul>
<!-- 获取key和value 格式:(value key) -->
<ul>
<li v-for="(value key) in info">{{value}}-{{key}}</li>
</ul>
<!-- 获取value,key,index 格式:(value key index0) -->
<ul>
<li v-for="(value key index)">{{value}}-{{key}}-{{index}}</li>
</ul>
</div>
购物车案例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>购物车案例</title>
</head>
<style>
table{
border:1px solid #e9e9e9;
border-collapse: collapse;
border-spacing: 0;
}
th,td{
padding: 8px 16px;
border: 1px solid #e9e9e9;
text-align: center;
}
th{
background-color:#f7f7f7;
color:#5c6b77;
font-weight: 600;
}
</style>
<body>
<div id="app">
<div v-if="books.length">
<table>
<thead>
<tr>
<th></th>
<th>书籍名称</th>
<th>出版日期</th>
<th>价格</th>
<th>购买数量</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<tr v-for="(item,index) in books">
<td>{{item.id}}</td>
<td>{{item.name}}</td>
<td>{{item.date}}</td>
<td>{{item.price | showPrice}}</td>
<td >
<button @click="decrement(index)" v-bind:disabled="item.count<=1">-</button>
{{item.count}}
<button @click="increment(index)">+</button>
</td>
<td><button @click="del(index)">删除</button></td>
</tr>
</tbody>
</table>
<h2>总价格{{getallprice|showPrice}}</h2>
</div>
<div v-else>
<h2>购物车为空</h2>
</div>
</div>
<script type="text/javascript" src="https://cdn.staticfile.org/vue/2.2.2/vue.min.js"></script>
<script>
new Vue({
el:"#app",
data:{
books:[
{
id:1,
name:"《算法导论》",
date:'2016-9',
price:85.00,
count:1
},
{
id:2,
name:"《UNIX编程艺术》",
date:'2006-2',
price:95.00,
count:1
},
{
id:3,
name:"《编程珠玑》",
date:'2018-10',
price:39.00,
count:1
},
{
id:4,
name:"《代码大全》",
date:'2016-3',
price:185.00,
count:1
},
]
},
methods:{
decrement(index) {
this.books[index].count--
},
increment(index) {
this.books[index].count++
},
del(index){
this.books.splice(index,1)
},
},
filters:{
showPrice(price){
return '¥'+price.toFixed(2)
}
},
computed:{
getallprice(){
let total=0
for(let i=0;i<this.books.length;i++){
total+=this.books[i].count*this.books[i].price
}
return total
}
},
})
</script>
</body>
</html>
v-model的使用和原理
<body>
<div id="app">
<input type="text" v-model='mes'>
<p>{{mes}}</p>
</div>
<script type="text/javascript" src="https://cdn.staticfile.org/vue/2.2.2/vue.min.js"></script>
<script>
new Vue({
el:"#app",
data:{
mes:"v-model的使用"
},
})
</script>
</body>
使用v-model可以在改变input中的内容时,而且可以同时改变v-model绑定的数据在data中的值。
实现方法可以使用:value=“变量”+函数(value)的方式来实现。
v-model的修饰符
lazy | lazy 修饰符可以在让数据失去焦点或回车才更行 |
---|---|
number | number可以使输入框中的内容自动转化为数字 |
trim | trim修饰符可以过滤内容两边的空格 |
组件化
全局组件构造和使用
全局组件的注册是在Vue的实例外注册的
<body>
<div id="app">
<cpn></cpn>
</div>
<script type="text/javascript" src="https://cdn.staticfile.org/vue/2.2.2/vue.min.js"></script>
<script>
// 创建组件的构造器对象
const cpnC=Vue.extend({
template:`
<h2>
Vue.Js的组件化操作
</h2>
`
})
//注册组件(使用这中方法注册的组件是全局组件)
//cpn为组件名,cpnC为组件构造器对象。
Vue.component('cpn',cpnC)
new Vue({
el:"#app",
data:{
mes:"v-model的使用"
},
})
</script>
</body>
局部组件
通过Vue实例进行注册,只有在Vue实例管理范围内有效。
<script>
// 创建组件的构造器对象
const cpnC=Vue.extend({
template:`
<h2>
Vue.Js的组件化操作
</h2>
`
})
//注册组件(使用这中方法注册的组件是全局组件)
// Vue.component('cpn',cpnC)
new Vue({
el:"#app",
data:{
mes:"v-model的使用"
},
components:{
cpn:cpnC
}
})
</script>
父组件和子组件的使用和注册
注意:组件应当是一个div容器。
<body>
<div id="app">
<cpn2></cpn2>
</div>
<script type="text/javascript" src="https://cdn.staticfile.org/vue/2.2.2/vue.min.js"></script>
<script>
const cpnC1=Vue.extend({
template:`
<h2>
Vue.Js的组件化操作
</h2>
`
})
const cpnC2=Vue.extend({
template:`
<div>
<h2>
父组件与子组件
</h2>
<cpn1></cpn1>
</div>
` ,
components:{
cpn1:cpnC1
}
})
new Vue({
el:"#app",
data:{
mes:"v-model的使用"
},
components:{
cpn2:cpnC2
}
})
</script>
注册组件的语法糖写法
Vue.component('cpn',{
template:`
<h2>
Vue.Js的组件化操作
</h2>
`
})
组件模板抽离
//模板定义
<template id="tem">
<div>
<h2>
Vue.Js的组件化操作
</h2>
</div>
</template>
//组件注册
const cpnC=Vue.extend({
template:"#tem",
})
在组件中添加动态数据data,data必须是函数。是为了保障每个模板都有自己独立的数据,不受其组件的影响。
const cpnC=Vue.extend({
template:"#tem",
data(){
return {
mes:"组件化data"
}
}
})
父子组件通信-父传子
<my-cpn :cmessage="message"></my-cpn>//通过v-bind绑定将props中的cmessage与父组件中data里 //的message关联,实现父传子的父子组件通信。
const cpnC=Vue.extend({
template:"#tem",
data(){
return{
mess:"欢迎",
}
},
props:{//使用对象,可以对数据进行限制,比如类型和默认值,
cmessage:{
type:String,
default:"加油",
}
},
// props:["cmessage"],可以使用数组来表示父组件的数据
})
new Vue({
el:"#app",
data:{
message:'Vue.Js',
},
})
子传父
<body>
<div id="app">
<my-cpn @itemclick="cpnClick"></my-cpn>
<h2>{{type}}</h2>
</div>
<template id="tem">
<div>
<div>
<button v-for="item in categories" @click="btnClick(item)">{{item.name}}</button>
</div>
</div>
</template>
<script type="text/javascript" src="https://cdn.staticfile.org/vue/2.2.2/vue.min.js"></script>
<script>
const cpnC=Vue.extend({
template:"#tem",
data(){
return{
categories:[
{id:'aaa',name:'热门推荐'},
{id:'bbb',name:'搜集数码'},
{id:'ccc',name:'家用家电'},
{id:'ddd',name:'电脑办公'},
]
}
},
props:{
},
methods: {
btnClick(item){
this.$emit('itemclick',item)
},
},
})
Vue.component('my-cpn',cpnC)
new Vue({
el:"#app",
data:{
message:'Vue.Js',
type:'',
},
methods:{
cpnClick(item){
this.type=item.name
},
}
})
</script>
</body>
父访问子-children-refs
children的使用
在父组件使用this.$children可以获得一个包含所有子组件对象的数组。
refs的使用
在子组件中加上ref=‘key’,在父组件使用的时候使用$refs.key可以获取使用key标注的组件对象。
子访问父 -parent-root
在子组件中使用this.$parent可以获得父组件对象
在子组件中使用this.$root可以获得根组件对象(可以访问Vue实例)
插槽slot
基本使用
<div id="app">
<cpn>html标签</cpn>
<cpn></cpn>
</div>
<template id="tem">
<div>
<h2>
Vue.Js的组件化操作
</h2>
<h2>{{mes}}</h2>
<slot></slot>//可以在中间加入默认内容.在使用时不加内容就使用默认内容
</div>
</template>
具名插槽
<div id="app">
<cpn><span slot="middel">中间</span></cpn>//通过name和slot联系起来
</div>
<template id="tem">
<div>
<slot name="left"><span>left</span></slot>
<slot name="middel"><span>middel</span></slot>
<slot name="right"><span>right</span></slot>
</div>
</template>
作用域插槽
<div id="app">
<cpn></cpn>
<cpn>
<template scope="slot">
<span v-for="item in slot.data">{{item}}-</span>
</template>
</cpn>
</div>
<template id="tem">
<div>
<slot :data="languages">
<div>
<ul>
<li v-for="item in languages">{{item}}</li>
</ul>
</div>
</slot>
</div>
</template>
const cpnC=Vue.extend({
template:"#tem",
data(){
return {
languages:['Java','python','javascript','c++']
}
}
})