Vue.js-起步
Vue.js是什么
1)Vue是一套用于构建用户界面的渐进式框架
2)使用Vue不影响使用jQuery,BootStrap
3)Vue是MVVM思路,model view view model 数据模型和视图双向绑定
4)Vue解决的是DOM查找困难的情况,只要将数据跟视图绑定在一起,那么视图变了,数据就变了,数据变了视图就变了。双向绑定。
开始第一个vue画面
1)添加引用
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
2)声明样渲染
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
{{message}}
</div>
<script>
var app = new Vue({
el: '#app',
data: {
message: 'Hello World!'
}
})
</script>
</body>
</html>
执行结果
完成以上操作后数据和DOM已经建立关系,所有东西都是响应式的,
只要data的message发生变化,绑定的{{message}}也会发生变化
3)绑定元素
带v- 是指令的意思
下面是将元素节点的title的特性和vue里的title进行绑定
<div id="app" v-bind:title="title">
{{message}}
</div>
<script>
var app = new Vue({
el: '#app',
data: {
message: 'Hello World!',
title:'akk'
}
})
</script>
4)条件指令
带v- 是指令的意思
下面是将元素节点的div的特性和vue里的flag进行绑定
<div id="app">
<div v-if="flag">hello world</div>
</div>
<script>
var app = new Vue({
el:'#app',
data:{
flag: true
}
})
</script>
当使用v-if的时候是移除DOM元素 偶尔隐藏使用
而使用v-show是使用display:none样式隐藏 ;频繁隐藏使用
5)循环指令
使用v-for进行循环
<div id="app">
<table border="1">
<tr v-for="i in num">
<td v-for="j in i">{{j}}*{{i}}={{j*i}}</td>
</tr>
</table>
</div>
<script>
var app = new Vue({
el:'#app',
data:{
num: 9
}
})
</script>
6)处理用户输入
通过click事件来调用methods里方法名来关联methods里的方法
<div id="app">
<div>{{ message }}</div>
<button v-on:click="reverseMessage">按钮</button>
</div>
<script>
var app = new Vue({
el:'#app',
data:{
message: 'akk'
},
methods:{
reverseMessage: function () {
this.message = this.message.split('').reverse().join('')
}
}
})
</script>
通过v-mode的方法绑定数据,当发生输入框中变更的时候,message的div也会变化
<div id="app">
<div>{{ message }}</div>
<input type="text" v-model="message" id="akk">
</div>
<script>
var app = new Vue({
el:'#app',
data:{
message: 'akk'
}
})
</script>
Vue.js组件
vue支持组件化开发,复杂页面可以拆分成多个组件,最后拼接成一个页面
创建了一个叫做akk的组件 传递name参数,并且使用到template中,
最后展示是hello vue
第一种
<div id="app">
<akk name = 'vue'></akk>
</div>
<script>
Vue.component('akk', {
props:['name'],
template: '<h1>hello {{name}}</h1>'
})
var app = new Vue({
el:'#app',
data:{
message: "hello world"
}
})
</script>
第二种
在这里插入代码片
Vue.js实例
new出来的Vue对象就是一个Vue实例
<div id="app">
<div>{{a}}</div>
</div>
<script>
var data = {a:1}
// 冻结data 后面的变更将不会影响
Object.freeze(data);
var app = new Vue({
el:'#app',
data:data,
// 初始化会进入的方法
//vue2一般使用Mounted进行初始化,new Vue中包含了一系列的生命周期方法
created:function(){
console.log("akk")
}
})
data.a=11
console.log(data.a == app.a)
console.log(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>")
// 以下都为true。通过$可以获取对应的属性
console.log(app.$el==document.getElementById("app"))
console.log(app.$data==data)
</script>
Vue.js模板语法
{{}} 插值的方式模板语法,即不在html标签中
v-bind html特性使用的模板语法
<div>{{a}}</div>
<!-- v-on可以简写@click v-bind可以简写:disabled-->
<button v-bind:disabled="b" v-on:click="num++">按钮</button>
<div v-html="a"></div>
<div>{{num<9?'yes':'no'}}</div>
<!-- 将字符串变为跳转网址-->
<a v-bind:href="href">百度</a>
</div>
<script>
var app = new Vue({
el:'#app',
data:{
a:"<h1>asdf</h1>",
b:false,
num:6,
href:'http://www.baidu.com'
}
})
</script>
Vue.js 计算属性
当需要在大括号中放入表达式的时候就可以使用计算属性
计算属性有缓存,方法没有,一般使用简写的get就够用,特殊情况可以使用getset
<div id="app">
<!-- 如果是方法每次调用都会被执行一遍-->
<div>{{reverseMessage()}}</div>
<!-- 如果是计算每次调用都会先看有没有缓存-->
<div>{{reverseMessages}}</div>
</div>
<script>
var app = new Vue({
el:'#app',
data:{
message:'hello'
},
methods:{
reverseMessage(){
return this.message.split('').reverse().join('');
}
},
computed:{
reverseMessages:{
get(){
return this.message.split('').reverse().join('');
},
set(newVal){
}
}
// 简写方式
// reverseMessages(){
// return this.message.split('').reverse().join('');
// }
}
})
</script>
Vue.js 侦听器
侦听器更适合异步,耗时操作
本地变化计算属性就可以了
<div id="app">
<div>{{ message }}</div>
<input type="text" v-model="message" id="akk">
</div>
<script>
var app = new Vue({
el:'#app',
data:{
firstName:'azto',
lastName:'akk',
fullName:'azto akk'
},
// 异步的时候使用监听,耗时操作,网络操作
// 最佳应该使用计算属性,计算属性更适合本地的变化
watch:{
firstName(val){
this.fullName = val +' '+this.lastName;
},
lastName(val){
this.fullName = this.firstName + ' ' + val;
}
}
})
</script>
Vue.js Class绑定
<div id="app">
<!-- 这是最基本的写法,v-bindclass通过直接控制样式的truefalse来显示与否-->
<!-- <div v-bind:class='{mydiv:flag,mydiv2:hasBorder}' class='mydiv1'>{{msg}}</div>-->
<!-- 将两个样式整成一个对象,通过对象直接显示不用加大括号-->
<div v-bind:class='classObj' class='mydiv1'>{{msg}}</div>
</div>
<script>
var app = new Vue({
el:'#app',
data:{
msg:'hello world',
flag:true,
hasBorder:true,
classObj:{
mydiv:true,
mydiv2:true
}
}
})
</script>
<style>
.mydiv2{
border: 30px;
}
.mydiv1{
font-size: 30px;
}
.mydiv{
font-weight: bold;
color: #f84cff;
}
</style>
<div id="app">
<!-- 调用计算属性中的get方法获取属性-->
<div v-bind:class='classObj' class='mydiv1'>{{msg}}</div>
<!-- 使用三元运算符来控制显示与否-->
<div v-bind:class="[flag ? mydivClass : '',mydiv2Class]">{{msg}}</div>
<!-- 通过数组的方法 mydiv2Classs始终加进来,mydiv样式由flag影响 和之前的v-bind:class对等-->
<div v-bind:class="[{mydiv:flag},mydiv2Class]">{{msg}}</div>
</div>
<script>
var app = new Vue({
el:'#app',
data:{
msg:'hello world',
flag:true,
hasBorder:true,
mydivClass:'mydiv',
mydiv2Class:'mydiv2',
},
computed:{
classObj(){
return{
mydiv:this.flag, mydiv2:this.hasBorder
}
}
}
})
</script>
<style>
.mydiv2{
border: 30px;
}
.mydiv1{
font-size: 30px;
}
.mydiv{
font-weight: bold;
color: #f84cff;
}
</style>
Vue.js Style绑定
Style的绑定和Class的绑定差不多
<div id="app">
<div v-bind:style='{color:fontcolor,fontSize:fontsize+"px"}'>{{msg}}</div>
<div v-bind:style='{color,fontSize}'>{{msg}}</div>
<div v-bind:style='styleObj'>{{msg}}</div>
// 不可以是变量,只能是属性
<div v-bind:style='[hasBorder ? "" : styleObj]'>{{msg}}</div>
</div>
<script>
var app = new Vue({
el:'#app',
data:{
msg:'hello world',
flag:true,
hasBorder:true,
fontcolor:'red',
fontsize:100,
// 以上是当作变量使用给color赋值
// 下面是直接当作属性来使用的
color:'green',
fontSize:'50px',
classObj:{
mydiv:true,
mydiv2:true
},
styleObj:{
//这里不能直
color:'red',
fontSize:'30px'
}
}
})
</script>
<style>
.mydiv2{
border: 30px;
}
.mydiv1{
font-size: 30px;
}
.mydiv{
font-weight: bold;
color: #f84cff;
}
</style>
Vue.js 条件渲染
if else 通过控制一个变量来决定这个元素是否渲染
v-if 为true 这个元素显示 false不显示
多个元素需要处理 可以使用’template‘标签 渲染完成之后是不会有template元素的
v-show css的display 显示不显示dom树中都有这个元素 v-show不支持v-else 和 template
<div id="app">
<!-- 多个元素需要处理 可以使用’template‘标签 渲染完成之后是不会有template元素的-->
<template v-if="isShow">
<p>123</p>
<div>123</div>
<span>123</span>
</template>
<div v-else>akkkk</div>
性别:
<div v-if="gender==0">男</div>
<div v-else-if="gender==1">女</div>
<div v-else>未知</div>
<hr>
<!-- Vue为了提交渲染的效率是有缓存的,可以使用key区分,让不使用缓存-->
<template v-if="loginType=='username'">
<label>用户名<label/>
<input type="text" placeholder="请输入用户名" key="username"/>
</template>
<template v-else>
<label>用户名</label>
<input type="text" placeholder="请输入邮箱" key="email"/>
</template>
<hr>
<div v-show="isHide">123123v-show</div>
</div>
<script>
var app = new Vue({
el: '#app',
data: {
message:'akk',
isShow:false,
gender:0,
loginType:'username',
isHide:false
}
})
</script>
Vue.js 列表渲染
数组列表的更新要使用以下方法才能时时更新
push()
pop()
shift()
unshift()
splice()
sort()
reverse()
filter()、concat() 和 slice()它们不会变更原始数组,而总是返回一个新数组。当使用非变更方法时,可以用新数组替换旧数组
响应式的变量要在一开始的时候就放到Vue()里,如果没有放进去就不是响应式的 如果是变更Vue里面的对象的元素是可以添加的
Vue.set(app.对象,‘key’,‘value’)// 添加
<div id="app">
<table border="1">
<tr>
<td>循环下标</td>
<td>书名</td>
<td>作者</td>
</tr>
<!-- in也可以使用of代替-->
<!-- 便利一个数组对象-->
<tr v-for="(book,index) in books" v-bind:key="index">
<td>{{index}}</td>
<td>{{book.name}}</td>
<td>{{book.author}}</td>
</tr>
</table>
<hr>
<!-- 遍历普通对象object-->
<div v-for="s in site">
{{s}}
</div>
<!--拿到key(porperty)-->
<div v-for="(s,porperty,index) in site" v-bind:key="index">
{{s}}-{{porperty}}--{{index}}
</div>
</div>
<script>
var app = new Vue({
el: '#app',
data: {
books:[
{ name:'三国演义',author:'罗贯中'},
{ name:'红楼梦',author:'曹雪芹'},
{ name:'西游记',author:'吴承恩'},
{ name:'水浒传',author:'施耐庵'}
],
site:{
url:'www.baidu.com',
name:'akk',
server:'github'
}
}
})
</script>
Vue.js 事件处理
事件是v-on 也可以简写成@
v-on 提供了事件修饰符
.stop
.prevent
.capture
.self
.once
.passive
<!-- 阻止单击事件继续传播 -->
<a v-on:click.stop="doThis"></a>
<!-- 提交事件不再重载页面 -->
<form v-on:submit.prevent="onSubmit"></form>
<!-- 修饰符可以串联 -->
<a v-on:click.stop.prevent="doThat"></a>
<!-- 只有修饰符 -->
<form v-on:submit.prevent></form>
<!-- 添加事件监听器时使用事件捕获模式 -->
<!-- 即内部元素触发的事件先在此处理,然后才交由内部元素进行处理 -->
<div v-on:click.capture="doThis">...</div>
<!-- 只当在 event.target 是当前元素自身时触发处理函数 -->
<!-- 即事件不是从内部元素触发的 -->
<div v-on:click.self="doThat">...</div>
v-on 提供了按键修饰符
键盘都有keyCode
.enter
.tab
.delete (捕获“删除”和“退格”键)
.esc
.space
.up
.down
.left
.right
你还可以通过全局 config.keyCodes 对象自定义按键修饰符别名:
// 可以使用 v-on:keyup.f1
Vue.config.keyCodes.f1 = 112
<div id="app" >
<div>{{counter}}</div>
<!-- <input type="button" value="自增" @click="counter++">-->
<input type="button" value="自增" @click="increment(2)">
<input type="text" @keydown.enter="submit">
</div>
<script>
var app = new Vue({
el: '#app',
data: {
message: 'Hello World!',
counter:0
},
methods:{
submit(){
console.log("submit()")
},
increment(step){
this.counter=this.counter+step;
}
}
})
</script>
Vue.js 表单输入绑定
常见表单
input
textarea
select
使用v-mode来进行数据绑定
<div id="app">
<!-- 绑定单行文本-->
<input type="text" v-model="message">
<div>{{message}}</div>
<!-- 绑定多行文本-->
<textarea name="" id="" cols="30" rows="10" v-model="textarea"></textarea>
<p style="white-space: pre-line">{{textarea}}</p>
<hr>
<!-- 绑定单个复选框-->
<input type="checkbox" v-model="isRead">
<div>{{isRead}}</div>
<!-- 绑定多个复选框-->
<input type="checkbox" value="足球" v-model="favorites">足球</input>
<input type="checkbox" value="篮球" v-model="favorites">篮球</input>
<input type="checkbox" value="乒乓球" v-model="favorites">乒乓球</input>
<input type="checkbox" value="棒球" v-model="favorites">棒球</input>
<div>{{favorites}}</div>
<hr>
<!-- 绑定单选按钮-->
<input type="radio" value="男" v-model="gender">男</input>
<input type="radio" value="女" v-model="gender">女</input>
<div>{{gender}}</div>
<hr>
<!-- 绑定下拉框按钮-->
<select v-model="edu">
<option value="小学">小学</option>
<option value="初中">初中</option>
<option value="高中">高中</option>
</select>
<div>{{edu}}</div>
<hr>
<!-- 下拉框多选-->
<select v-model="favorites" multiple >
<option v-for="(f,index) in fs" :key="index" :value="f">{{f}}</option>
</select>
<div>{{favorites}}</div>
<hr>
<!-- 当勾选的时候为yes 没有勾选的时候为no 绑定到toggle-->
<input type="checkbox" true-value="yes" false-value="no" v-model="toggle">
<div>{{toggle}}</div>
<hr>
<!-- 不会实时显示,让移除光标的时候才会更新视图-->
<input type="text" v-model.lazy="message">
<div>{{message}}</div>
</div>
<script>
var app = new Vue({
el: '#app',
data: {
message: '',
textarea:'',
isRead:false,
favorites:[],
gender:'',
// 默认选中小学可以些edu:'小学'
edu:'',
fs:[
'足球',
'篮球',
'乒乓球',
],
toggle:''
}
})
</script>
Vue.js 组件基础
vue中可以定义一个组件,当页面复杂的时候可以拆分成很多组件最后拼起来
<div id="app">
<akk title="组件一"></akk>
<akk title="组件二"></akk>
<!-- 监听组件触发事件-->
<azto @sayhello="hello" v-for="(i,index) in blogs" :title="i.title" :date="i.date" :author="i.author" :key="index"></azto>
</div>
<script>
// 组件里面必须要将data定义成方法,返回值里面才是数据
Vue.component('akk', {
data(){
return{
counter:0
}
},
props: ['title'],
template: '<div><button @click="counter++">hello {{counter}}</button><div>{{title}}</div></div>'
})
Vue.component('azto',{
props: ['title','date',"author"],
template: '<div>' +
'<div>{{title}}</div>' +
'<div>{{date}}--{{author}}</div>' +
'<button @click="$emit(\'sayhello\',title)">text</button>' +
'</div>'
})
var app = new Vue({
el:'#app',
methods:{
hello(val){
console.log("hello vue"+val)
}
},
data:{
blogs:[
{title:'标题一',date: '20200101',author:'A'},
{title:'标题二',date: '20200102',author:'B'},
{title:'标题三',date: '20200103',author:'C'}
]
}
})
</script>