什么是Vue?
Vue (读音 /vjuː/,类似于 view) 是一套用于构建用户界面的渐进式框架。与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用。Vue 的核心库只关注视图层,不仅易于上手,还便于与第三方库或既有项目整合。另一方面,当与现代化的工具链以及各种支持类库结合使用时,Vue 也完全能够为复杂的单页应用提供驱动。
官网地址:Vue
Vue (读音 /vjuː/,类似于 view) 是一套用于构建用户界面的渐进式框架。与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用
MVVM模式:
- Model:数据存储
- View: 页面展示
- View Model : 业务逻辑处理 这块的话就是一个vue实例
开始第一个Vue
去官网下载vue.js
在页面导入vue.js
<script src="js/vue.js"></script>
声明式渲染
Vue.js 的核心是一个允许采用简洁的模板语法来声明式地将数据渲染进 DOM 的系统:
<div id="app">
{{message}}
</div>
<script type="text/javascript">
new Vue({
el:'#app',
data:{
message:"hello vue"
}
})
</script>
条件渲染(v-if)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<script src="js/vue.js"></script>
<style>
#show1{
background-color: blue;
width: 100px;
height: 50px;
}
</style>
</head>
<body>
<!-- view -->
<div id="app">
<p>{{name}}</p>
<p v-if="perm">权限:管理员</p>
<!-- <span>aaa</span> -->
<p v-else>权限:普通用户</p>
<!-- v-if和v-else 不能有其他元素-->
<h2>年龄阶段</h2>
<p v-if="age>30">成年人</p>
<p v-else-if="age>18">年轻人</p>
<p v-else>少儿</p>
<h2>v-show</h2>
<p v-show="isShow" id="show1">我是v-show</p>
<button @click="tab">切换</button>
</div>
<script type="text/javascript">
const vm=new Vue({
el:'#app',
data:{
name:"扬州炒饭",
perm:false,
age:20,
isShow:true
},
methods:{
tab:function(){
this.isShow=!this.isShow;
}
}
})
</script>
</body>
</html>
小结:
- v-if : 不显示就是将元素去除
- v-show : 不显示就是将元素display:none
列表渲染(v-for)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>列表渲染</title>
<script src="js/vue.js"></script>
</head>
<body>
<div id="app">
<ul>
<li v-for="item,index in list">
id===={{item.id}}
text===={{item.text}}
下标 {{index}}
</li>
</ul>
<p v-for="item,index in list[0]">{{item}}</p>
<h2>条件循环(id为2倍数的)</h2>
<ul>
<li v-for="item,index in list" v-if="index%2==0" :key="index">{{item.id}}====={{item.text}}</li>
</ul>
</div>
<script type="text/javascript">
const vm=new Vue({
el:'#app',
data:{
list: [
{ id: 0, text: '蔬菜' ,img:'https://cn.vuejs.org/'},
{ id: 1, text: '奶酪' },
{ id: 2, text: '随便其它什么人吃的东西' },
{ id: 3, text: '啊啊' },
{ id: 4, text: '擦擦' }
]
}
})
</script>
</body>
</html>
用key管理可复用元素
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<script src="js/vue.js"></script>
</head>
<body>
<div id="app">
<div v-if="isLogin" class="login" key="login">
<h1>登录</h1>
<input type="text" name="name">
</div>
<div v-else class="reg" key="reg">
<h1>注册</h1>
<input type="text" name="name">
</div>
<button @click="tab" type="button">切换</button>
</div>
<script type="text/javascript">
const vm=new Vue({
el:'#app',
data:{
isLogin:true
},
methods:{
tab:function() {
this.isLogin=!this.isLogin;
}
}
})
</script>
</body>
</html>
小结:
- 如果你想切换登录或者注册页面时不清理元素内容 就不用加 key
- 如果切换时也要清理你输入的元素 这个时候加上key就可以了
模板语法
Vue.js 使用了基于 HTML 的模板语法,允许开发者声明式地将 DOM 绑定至底层 Vue 实例的数据。所有 Vue.js 的模板都是合法的 HTML,所以能被遵循规范的浏览器和 HTML 解析器解析。
插值
文本
数据绑定最常见的形式就是使用“Mustache”语法 (双大括号) 的文本插值:
<span>Message: {{ msg }}</span>
插入Html内容
<div id="app">
<!-- 插入html文本 -->
<h2>{{htmlText}}</h2>
<h2 v-html="htmlText"></h2>
</div>
<script type="text/javascript">
var vm=new Vue({
el:'#app',
data:{
htmlText:'<span>我是span</span>'
}
})
</script>
注意:动态渲染html很容易导致xss攻击,使用时要注意
Attribute
<style type="text/css">
#name1{
background-color: #0000FF;
}
#name2{
background-color: red;
}
</style>
<div id="app">
<!-- 绑定动态属性 -->
<div :id="name">
绑定动态属性
</div>
</div>
<script type="text/javascript">
var vm=new Vue({
el:'#app',
data:{
name:'name1'
}
})
表达式
<!-- 表达式的使用 -->
<H1>{{uname+age}} </H1>
<!-- 三元运算 -->
<h2>{{sum==10?'yes':'no'}}</h2>
var vm=new Vue({
el:'#app',
data:{
uname:'炒饭',
age:'20',
sum:10
}
})
事件绑定
v-bind
<!-- 完整语法 -->
<a v-bind:href="url">...</a>
<!-- 缩写 -->
<a :href="url">...</a>
<!-- 动态参数的缩写 (2.6.0+) -->
<a :[key]="url"> ... </a>
v-on
<!-- 完整语法 -->
<a v-on:click="doSomething">...</a>
<!-- 缩写 -->
<a @click="doSomething">...</a>
<!-- 动态参数的缩写 (2.6.0+) -->
<a @[event]="doSomething"> ... </a>
计算属性 computed
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<script src="js/vue.js"></script>
</head>
<body>
<div id="app">
<div >
{{name+age}}
</div>
<h1>{{sum}}</h1>
<!-- 倒叙单词 -->
<h2>{{reversed.split('').reverse().join('')}}</h2>
<h2>{{reversedWord}}</h2>
<h1>循环偶数</h1>
<ul>
<li v-for="item,index in lists">
<h4>{{item.text}}</h4>
<h4>{{item.id}}</h4>
</li>
</ul>
</div>
<script type="text/javascript">
const vm=new Vue({
el:'#app',
data:{
name:"炒饭",
age:20,
reversed:'abcd',
list: [
{ id: 0, text: '蔬菜' ,img:'https://cn.vuejs.org/'},
{ id: 1, text: '奶酪' },
{ id: 2, text: '随便其它什么人吃的东西' },
{ id: 3, text: '啊啊' },
{ id: 4, text: '擦擦' }
]
},
computed:{
sum:function(){
//会将计算的结果进行缓存,只要name和age值不变 就只进行一次计算
return this.name+this.age
},
reversedWord:function(){
return this.reversed.split('').reverse().join('')
},
lists:function(){
return this.list.filter((item,i)=>{
return i%2==0
})
}
}
})
</script>
</body>
</html>
小结:
- 会将计算的结果进行缓存,只要name和age值不变 就只进行一次计算
侦听器 watch
虽然计算属性在大多数情况下更合适,但有时也需要一个自定义的侦听器。这就是为什么 Vue 通过 watch
选项提供了一个更通用的方法,来响应数据的变化。当需要在数据变化时执行异步或开销较大的操作时,这个方式是最有用的
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>侦听器</title>
<script src="js/vue.js"></script>
</head>
<body>
<div id="app">
<div>{{name}}</div>
<div>{{rename}}</div>
<ul>
<li v-for="item in list">{{item}}</li>
</ul>
</div>
<script type="text/javascript">
const vm=new Vue({
el:'#app',
data:{
name:"炒饭",
list: [
{ id: 0, text: '蔬菜' ,img:'https://cn.vuejs.org/'},
{ id: 1, text: '奶酪' },
{ id: 2, text: '随便其它什么人吃的东西' },
{ id: 3, text: '啊啊' }
]
},
computed:{
rename:{
// getter
get: function () {
return this.name.split('').reverse().join('')
},
// setter
set: function (newValue) {
return this.name=newValue.split('').reverse().join('')
}
}
},
watch:{
name:function(e){
console.log("值为"+e)
},
list:function(e){
console.log("监听=======list")
for (let s of e) {
console.log(s.text)
}
console.log("值为"+e.id)
}
}
})
</script>
</body>
</html>
Class与Style绑定
绑定class
对象语法
<!-- 通过对象绑定class -->
<div class="style1" :class="{active:isTrue}"></div>
<!-- 直接放对象 -->
<div :class="obj1"></div>
数组语法
<!-- 数组 -->
<div :class="arr"></div>
具体代码
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Class 与 Style 绑定</title>
<script src="js/vue.js"></script>
<style type="text/css">
.active{
background-color: #FF0000;
}
.style1{
width: 150px;
height: 200px;
}
.arr{
background-color: blue;
width: 400px;
height: 200px;
}
</style>
</head>
<body>
<div id="app">
<!-- 通过对象绑定class -->
<div class="style1" :class="{active:isTrue}"></div>
<!-- 直接放对象 -->
<div :class="obj1"></div>
<!-- 数组 -->
<div :class="arr"></div>
<!-- 字符串 -->
<div :class="str1"></div>
<!-- 数组 和 对象-->
<div :class="obj"></div>
</div>
<script type="text/javascript">
const vm=new Vue({
el:'#app',
data:{
isTrue:true,
obj1:{active:true,style1:true,'flex':true},
arr:['arr','aaaa'],
str1:"bgcolor",
obj:['aaa',{active:true},{style1:true}]
}
})
</script>
</body>
</html>
绑定内联样式
<<div style="width: 100px;height: 100px;background-color: aquamarine;" :style="{border:'2px solid red'}"></div>
<!-- 内联样式拼接 -->
<div style="background-color: red;" :style="{ height:wids+'px',hieght:hei+'px' }"></div>
<!-- 内联放置对象 -->
<div :style="obj1"></div>
<script type="text/javascript">
const vm=new Vue({
el:'#app',
data:{
wids:500,
hei:300,
colors:'red',
obj1:{
width:'600px',
height:'30px',
'margin-top':'50px',
'background-color':'blue'
}
}
})
</script>
小测试 侧边栏切换
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script src="js/vue.js"></script>
<style type="text/css">
.menu{
width: 100vw;
height: 100vh;
background: #0000FF;
position: fixed;
left: 0;
top: 0;
}
.right{
width: 50vw;
height: 100vh;
transform: translateX(100vw);
background: red;
position: fixed;
transition: transform 2s;
left: 0;
top: 0;
}
.active{
transform: translateX(50vw);
}
</style>
</head>
<body>
<div id="app">
<div class="menu">
菜单
<button @click="tab">切换</button>
</div>
<div class="right" :class="{active:isTrue}">
侧边
</div>
</div>
<script type="text/javascript">
var aa=new Vue({
el:"#app",
data:{
isTrue:false
},
methods:{
tab:function(){
this.isTrue=!this.isTrue
console.log("isTrue"+this.isTrue)
}
}
})
</script>
</body>
</html>
小结:
- Class与Style绑定 的方式常用的就两种
- 通过对象绑定
- 通过数组绑定
- 内联样式用 :style
- 绑定Calss 用 :class
事件绑定
监听事件
<div id="app">
<button type="button" @click="current-=1">-</button>
<h2>{{current}}</h2>
<button type="button" @click="current+=1">+</button>
<button type="button" @click="clickadd">add</button>
</div>
<script type="text/javascript">
const vm=new Vue({
el:'#app',
data:{
current:0
},
methods:{
clickadd:function(){
this.current++
}
}
})
</script>
事件处理方法
<div id="app">
<button type="button" @click="good">good</button>
</div>
<script type="text/javascript">
const vm=new Vue({
el:'#app',
data:{
name:'炒饭'
},
methods:{
good:function(enent){
alert("我想吃"+this.name)
// event 是原生 DOM 事件
if (event) {
console.log(enent)
alert(event.target.tagName)
}
}
}
})
</script>
内联处理器中的方法
<div id="app1">
<button type="button" @click="meth1('hello',$event)">内联处理器中的方法</button>
</div>
<script type="text/javascript">
const vm1=new Vue({
el:'#app1',
methods:{
meth1:function(msg,event){
alert(msg)
console.log(event)
}
}
})
</script>
要是想访问事件对象,这块使用$event
事件修饰符
vue.js 为 v-on
提供了事件修饰符。之前提过,修饰符是由点开头的指令后缀来表示的。
- .stop
- .prevent
- .capture
- .self
- .once
- .passive
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>事件修饰符</title>
<script src="js/vue.js"></script>
</head>
<body>
<div id="app">
<div @click="clickparent">
<!-- stop修饰符,阻止冒泡向上传递 -->
<button @click.stop="clickchild">点击1</button>
</div>
<form action="" method="post">
<input type="text" v-model="city" value="">
<!-- 提交事件不再重载页面 -->
<input type="submit" @click.prevent="meth1" value="提交">
</form>
</div>
<script type="text/javascript">
const vm=new Vue({
el:'#app',
data:{
message:"hello vue",
city:'陕西'
},
methods:{
clickchild:function(e){
console.log(e)
},
clickparent:function(e){
console.log(e)
},
meth1:function(){
console.log("提交事件不再重载页面")
console.log(this.city)
}
}
})
</script>
</body>
</html>
按键修饰符
.enter
.tab
.delete
(捕获“删除”和“退格”键).esc
.space
.up
.down
.left
.right
<div id="app">
<!-- 当按下删除键时触发delete1方法 -->
delete1:<input type="text" @keydown.delete="delete1">
<!-- 当按下删除键时触发enter1方法 -->
enter1:<input type="text" @keydown.enter="enter1">
</div>
<script type="text/javascript">
const vm=new Vue({
el:'#app',
methods:{
delete1:function(){
console.log("delete1")
},
enter1:function(){
console.log("enter1")
}
}
})
</script>
其他事件见官网。。。。
表单输入绑定
<div id="app">
<span>单行文本========={{message}}</span>
<input type="text" v-model="message" />
<span>多行文本========={{message}}</span>
<textarea type="text" v-model="message" ></textarea>
<div>复选框</div>
<div v-for="item in hobbies">
{{item}}
<input type="checkbox" name="hobby" v-model="checkHobby" :value="item">
</div>
<span>{{checkHobby}}</span>
<div>单选按钮</div>
<div v-for="item in hobbies">
{{item}}
<input type="radio" name="hobby1" v-model="radioHobby" :value="item">
</div>
<span>单选按钮value==={{radioHobby}}</span>
<div>选择框</div>
<div>
<select v-model="selectHob">
<option disabled value="">请选择</option>
<option v-for="item in hobbies" :value="item">{{item}}</option>
</select>
<h2>{{selectHob}}</h2>
</div>
</div>
<script type="text/javascript">
const vm=new Vue({
el:'#app',
data:{
message:"hello vue",
hobbies:['听歌','打游戏','娱乐','敲代码'],
checkHobby:[],
radioHobby:'',
selectHob:''
}
})
</script>
过渡动画
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>过渡动画</title>
<script src="js/vue.js"></script>
<style type="text/css">
.act{
width: 300px;
height: 300px;
background-color: #FF0000;
}
.fade-enter-active, .fade-leave-active {
transition: opacity 3s;
}
.fade-enter, .fade-leave-to /* .fade-leave-active below version 2.1.8 */ {
opacity: 0;
}
</style>
</head>
<body>
<div id="app">
<!-- name 值必须时style 的class第一个值框架里面写的这样式 -->
<transition name="fade">
<div class="act" v-if="isShow">
</div>
</transition>
<button @click="tab">切换内容</button>
</div>
<script type="text/javascript">
const vm=new Vue({
el:'#app',
data:{
isShow:true
},
methods:{
tab:function(){
this.isShow=!this.isShow
}
}
})
</script>
</body>
</html>
具体其他操作看官网