Vue.js是一套构建用户界面(view)的MVVM框架。
Vue.js的核心库只关注视图层,并且非常容易学习,
非常容易与其他库或已有的项目整合。
简洁: HTML 模板 + JSON 数据,再创建一个 Vue 实例,就这么简单。
数据驱动: 自动追踪依赖的模板表达式和计算属性。
组件化: 用解耦、可复用的组件来构造界面。
轻量: ~24kb min+gzip,无依赖。
快速: 精确有效的异步批量 DOM 更新。
模块友好: 通过 NPM 或 Bower 安装,无缝融入你的工作流。
独立版本
直接下载并用 <script> 标签引入,Vue 会被注册为一个全局变量。
Vue.js 官网下载地址:http://vuejs.org/guide/installation.html
我们可以在官网上直接下载生产版本应用在我们项目中。。
View 层 - HTML 代码如下:
<div id="app">
{{ message }}
</div>
Model 层 - JavaScript 代码如下(需放在指定的HTML元素之后):
new Vue({
el:'#app',
data: {
message:'Hello World!'
}
});
整体代码如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="js/vue.js"></script>
</head>
<body>
<div id="app">
{{ message }}<!-- {{}}插值表达式-->
</div>
<!-- JavaScript 代码需要放在尾部(指定的HTML元素之后) -->
<script>
new Vue({
el:'#app',//vue开始渲染的地方
data: {
message:'Hello World!' //状态
}
});
</script>
</body>
</html>
输出结果Hello World!
除了文本插值,我们还可以像这样来绑定元素特性:
<div id="app">
<span v-bind:title="message">
鼠标悬停几秒钟查看此处动态绑定的提示信息!
</span>
</div>
<script type="text/javascript">
var app = new Vue({
el: '#app',
data: {
message: '页面加载于 ' + new Date().toLocaleString()
}
})
</script>
v-bind特性被称为指令。指令带有前缀 v-以表示它们是 Vue 提供的特殊特性。
该指令的意思是:“将这个元素节点的 title 特性和 Vue 实例的 message属性
保持一致”。
但是如果我们展示的数据包含元素标签或者样式,我们想展示标签或样式所定义
的属性作用,该怎么进行渲染,比如展示内容为:<h1>这是一个h1元素内容h1>
我们先用插值表达式和v-html尝试一下。
<div id="app">
{{myhtml}}
<div v-html="myhtml"></div>
</div>
<script type="text/javascript">
var app = new Vue({
el: '#app',
data: {
myhtml:"11111
",
}
})
</script>
<div id="app">
<div v-show="isShow">动态显示和隐藏</div>
<div v-if="isCreated">动态创建和删除</div>
</div>
<script type="text/javascript">
var app = new Vue({
el: '#app',
data: {
isShow:true,
isCreated:true
}
})
</script>
v-show
作用:通过判断,是否显示该内容。如果值为true,则显示。否则就隐藏。
语法:v-show=”判断表达式”
特点:元素会始终渲染在DOM中,只是被设置了display:none
v-if
作用:判断是否加载固定的内容。如果为真,则加载;为假时,则不加载。
用处:用在权限管理,页面条件加载
语法:v-if=”判断表达式”
特点:控制元素插进来或者删除,而不是隐藏。
v-if与v-show的区别:
一般来说,v-if有更高的切换消耗,安全性更高,而v-show有更多的初始化渲染消耗。因此,如果需要频繁切换而对安全性无要求,使用v-show。如果在运行时,条件不可能改变,则使用v-if较好。
<style type="text/css">
.red{
background-color: red;
}
.yellow{
background-color: yellow;
}
style>
<body>
<div id="box">
<div style="background:yellow">1111div>
<button @click="handleClick()">点button>
<div :class="isActive?'red':'yellow'">我是动态绑定class三目写法div>
<div :class="classobj">我是动态绑定clas对象写法div>
<div :class="classarr">我是动态绑定clas数组写法div>
<div :style="'background:'+'yellow'">1111div>
<div :style="'background:'+(isActive?'red':'yellow')">我是动态绑定style三目写法div>
<div :style="styobj">我是动态绑定style对象写法div>
<div :style="stylearr">我是动态绑定style数组写法div>
div>
<script type="text/javascript">
var vm=new Vue({
el:"#box",
data:{
isActive:true,
classobj:{
a:true,
b:true
//a,b class名字
},
classarr:["a",'b'],
styobj:{
backgroundColor:"red"
},
stylearr:[]
},
//方法
methods:{
handleClick(){
this.isActive=!this.isActive
}
}
})
script>
body>
实现购物车进去是空空如也 点击按钮切换到商品
<div id="box">
<button @click="handleClick()">点button>
<div v-if="isCreated">动态创建和删除11111div>
<div v-else>动态创建和删除22222div>
<ul v-if="datalist.length">
<li v-for="data in datalist">
{{data}}
li>
ul>
<div v-else>购物车空空如也div>
div>
<script type="text/javascript">
var vm=new Vue({
el:"#box",
data:{
isCreated:false,
datalist:[],
which:1
},
methods:{
handleClick(){
this.isCreated=!this.isCreated
this.datalist=['电脑','手机']
}
}
})
script>
<div id="box">
<ul>
<li v-for="(data,index) in datalist" key="data.id">
{{data}}--{{index}}
li>
ul>
<ul>
<li v-for="(data,index) of datalist">
{{data}}--{{index}}
li>
ul>
<ul>
<li v-for="(data,key) in obj">
{{data}}--{{key}}
li>
ul>
<ul>
<li v-for="(data,key) of obj">
{{data}}--{{key}}
li>
ul>
div>
<script>
var vm=new Vue({
el:"#box",
data:{
datalist:['111','222','333'],
obj:{
name:"kongyue",
age:"20",
sex:"nan"
},
}
})
script>
(1) v-for a. in b. of
(2) key:*跟踪每个节点的身份,从而重用和重新排序现有元素 *理想的 key
值是每项都有的且唯一的 id。data.id
(3) 数组更新检测
- 使用以下方法操作数组,可以检测变动 push() pop() shift() unshift() splice() sort() reverse()
- filter(), concat() 和 slice() ,map(),新数组替换旧数组
- 不能检测以下变动的数组 vm.items[indexOfItem] = newValue 解决 (1)Vue.set(example1.items, indexOfItem, newValue)
(2)splice
<body>
<div id="box">
<input type="text" v-model="mytext"/>
{{mytext}}
div>
<script>
var vm=new Vue({
el:"#box",
data:{
mytext:''
}
})
script>
body>
<div id="box">
<input type="text" @input="handleInput()" v-model="mytext"/>
<ul>
<li v-for="data in datalist" >
{{data}}
li>
ul>
div>
<script>
var vm=new Vue({
el:"#box",
data:{
datalist:['aaa','bbb','ccc','aab'],
list:['aaa','bbb','ccc','aab'],
mytext:''
},
methods:{
handleInput(){
console.log(this.mytext);
//只要value改变,就会触发
//利用输入框的字符,过滤出包含字段的元素
//filter 过滤
var newlist=this.list.filter(item=>item.indexOf(this.mytext)>-1)
//console.log(newlist);
this.datalist=newlist;
}
}
})
script>
<div id="box">
<button @click="handleClick">点击1button>
<button @click="handleClick()">点击2button>
<button @click="isShow=!isShow">点击3button>
<div v-show="isShow">111111div>
div>
<script type="text/javascript">
var em=new Vue({
el:"#box",
data:{
isShow:false
},
methods:{
handleClick(){
this.isShow=!this.isShow
}
}
})
script>
.self:只会触发自己范围内的事件,不包含子元素
.once:只会触发一次
.capture:与事件冒泡的方向相反,事件捕获由外到内
.prevent:等同于JavaScript中的event.preventDefault(),防止执行预设的行为(如果事件可取消,则取消该事件,而不停止事件的进一步传播)
.stop:等同于JavaScript中的event.stopPropagation(),防止事件冒泡
在JavaScript事件中除了前面所说的事件,还有键盘事件,也经常需要监测常见的键值。在Vue中允许v-on在监听键盘事件时添加关键修饰符。记住所有的keyCode比较困难,所以Vue为最常用的键盘事件提供了别名:
<div id="box">
<input type="text" v-model="mytext"/>
{{mytext}}
<textarea v-model="mytext">textarea>
<br />
<input type="checkbox" v-model="isCheckbox"/>记住用户名
<p>
<input type="checkbox" value="游泳" v-model="checkgroup"/>游泳
<input type="checkbox" value="长跑" v-model="checkgroup"/>长跑
<input type="checkbox" value="打游戏" v-model="checkgroup"/>打游戏
p>
{{checkgroup}}
<p>
<input type="radio" value="长跑" v-model="picked"/>长跑
<input type="radio" value="游泳" v-model="picked"/>游泳
<input type="radio" value="打游戏" v-model="picked"/>打游戏
p>
{{picked}}
div>
<script>
var vm=new Vue({
el:"#box",
data:{
mytext:'',
isCheckbox:false,
checkgroup:[],
picked:[]
}
})
script>
<html>
<head>
<meta charset="UTF-8">
<title>title>
head>
<body>
<script type="text/javascript" src="js/vue.js" >script>
<div id="box">
<div align="center">
<table border="1" width="400px">
<tr>
<th><input type="checkbox" v-model="isAllChecked" @change="handleChange()"/>全选th>
<th>商品idth>
<th>商品名称th>
<th>商品价钱th>
<th>商品数量th>
tr>
<tr v-for="data in datalist">
<td><input type="checkbox" v-model="checkgroup" :value="data" @change="handledanChange()"/>td>
<td>{{data.id}}td>
<td>{{data.name}}td>
<td>{{data.price}}td>
<td><button @click="handleJian(data)">减button>{{data.num}}<button @click="data.num++">加button>td>
tr>
<tr align="center">
<td colspan="5">总计{{getSum()}}td>
tr>
table>
{{checkgroup}}
div>
div>
<script type="text/javascript">
var em=new Vue({
el:"#box",
data:{
checkgroup:[],
isAllChecked:false,
datalist:[
{
id:"1",
name:"电脑",
price:"300",
num:"3"
},
{
id:"2",
name:"电扇",
price:"200",
num:"3"
},
{
id:"3",
name:"电视机",
price:"100",
num:"3"
},
{
id:"4",
name:"洗衣机",
price:"500",
num:"3"
}
]
},
methods:{
//总计
getSum(){
var sum=0;
for(var i in this.checkgroup){
sum+=this.checkgroup[i].num*this.checkgroup[i].price
}
return sum;
},
//减
handleJian(data){
var num=data.num--;
if(num==1){
data.num=1;
}
},
//全选
handleChange(){
console.log("改变",this.isAllChecked);
if(this.isAllChecked){
this.checkgroup=this.datalist;
}else{
this.checkgroup=[];
}
},
//商品点上全选
handledanChange(){
console.log("handleLiChange判断是不是勾选");
if(this.checkgroup.length===this.datalist.length){
this.isAllChecked=true;
}else{
this.isAllChecked=false;
}
}
}
})
script>
body>
html>
<div id="box">
<input type="text" v-model.lazy="mytext"/>
{{mytext}}
<input type="number" v-model.number="mynumber"/>
{{mynumber}}
<input type="text" v-model.trim="myusername" />
{{myusername}}
div>
<script>
var em=new Vue({
el:"#box",
data:{
mytext:"",
mynumber:0,
myusername:''
}
})
script>
<div id="box">
<p>计算属性{{getMyName}}p>
<p>方法调用{{getMyNameMethods()}}p>
也需要运算结果
<p>计算属性{{getMyName}}p>
<p>方法调用{{getMyNameMethods()}}p>
div>
<script>
var vm=new Vue({
el:"#box",
data:{
myname:"xiaoming"
},
methods:{
getMyNameMethods(){
console.log("getMyNameMethods-方法调用");
return this.myname.substring(0,1).toUpperCase()+this.myname.substring(1);
}
},
//1.依赖的状态改变了,计算属性会重新计算一遍
//2.计算属性会缓存
computed:{
getMyName(){
console.log('getMyName-计算属性调用');
return this.myname.substring(0,1).toUpperCase()+this.myname.substring(1);
}
}
})
script>
<div id="box">
<banner>banner>
<banner>banner>
div>
<script>
//全局定义组件 作用域隔离
Vue.component("banner",{
template:`
banner
`,
methods:{
handleback(){
alert("123");
}
},
})
var vm=new Vue({
el:"#box"
})
script>
<div id="box">
<banner>banner>
<banner>banner>
div>
<script>
//全局定义组件 作用域隔离
Vue.component("banner",{
template:`
banner
`,
methods:{
handleback(){
alert("123");
}
},
//局部定义组件
components:{
bannerchild:{
template:`bannerchild-只能在banner组件中使用`
}
}
})
var vm=new Vue({
el:"#box"
})
script>
- 自定义组件需要有一个root element
- 父子组件的data是无法共享
- 组件可以有data,methods,computed…,但是data 必须是一个函数
父传子用属性向下传
子传父用事件向上传
通过属性往孩子里传递
<div id="box">
<navbar myname="home">navbar>
<navbar myname="list">navbar>
<navbar :myname="parentname">navbar>
div>
<script>
Vue.component("navbar",{
template:`
navbar---{{myname}}
`,
props:["myname"] //接收父组件传来的属性
})
var vm=new Vue({
el:"#box",
data:{
parentname:"parentname父组件状态,动态绑定即可(:myname)"
}
})
script>
<div id="box">
<navbar myname="home" :myshow="false">navbar>
<navbar myname="list" :myshow="true">navbar>
<navbar :myname="parentname" :myshow="true">navbar>
div>
<script>
Vue.component("navbar",{
template:`
navbar---{{myname}}---{{myshow}}
`,
//属性验证
props:{
myname:String,
myshow:Boolean
}
})
var vm=new Vue({
el:"#box",
data:{
parentname:"parentname父组件状态,动态绑定即可(:myname)"
}
})
script>
props:{name:Number}
Number,String,Boolean,Array,Object,Function,null(不限制类型)
<div id="box">
父组件
<child @myevent="handleEvent($event)">child>
div>
<script>
Vue.component("child",{
template:`
child组件
`,
data(){
return {
childname:"子组件状态"
}
},
methods:{
payMoney(){
this.$emit("myevent",1000);//分发 事件
this.$emit("myevent",this.childname);
}
}
})
var vm=new Vue({
el:"#box",
methods:{
handleEvent(ev){
console.log("父组件收到钱了",ev);
}
}
})
script>
<div id="box">
<input type="text" ref="mytext"/>
<button @click="handleAdd">addbutton>
div>
<script>
//ref放在标签上,拿到的是原生节点
var vm=new Vue({
el:"#box",
methods:{
handleAdd(){
console.log("111",this.$refs.mytext.value)
}
}
})
script>
<div id="box">
<input type="text" ref="mytext"/>
<button @click="handleAdd">addbutton>
<child ref="mychild">child>
div>
<script>
//ref放在组件上,拿到的是组件对象
//子组件
Vue.component("child",{
template:`child`,
data(){
return {
childname:"子组件状态"
}
},
methods:{
add(data){
console.log("子组件的方法",data)
}
}
})
var vm=new Vue({
el:"#box",
methods:{
handleAdd(){
console.log(this.$refs.mychild.childname)
this.$refs.mychild.add("孩子挺好")//拿到子组件的状态和方法
}
}
})
script>
var bus = new Vue();
mounted生命周期中进行监听
<div id="box">
<weixinauthor>weixinauthor>
<weixinuser>weixinuser>
div>
<script>
var bus=new Vue();//空vue实例 就是中英事件总线
Vue.component("weixinauthor",{
template:`
我是一个公众号作者
`,
methods:{
handleClick(){
bus.$emit("weixinmessage",this.$refs.mytext.value)
}
}
})
Vue.component("weixinuser",{
template:`我是一个·微信用户`,
mounted(){
bus.$on("weixinmessage",(data)=>{
console.log("收到推送",data)
})
console.log("生命周期函数,当前组件的dom 创建完成之后 就会调用")
}
})
var vm=new Vue({
el:"#box"
})
script>
< component> 元素,动态地绑定多个组件到它的 is 属性
< keep-alive> 保留状态,避免重新渲染
<html>
<head>
<meta charset="UTF-8">
<title>title>
<style type="text/css">
*{
margin: 0px;
padding: 0px;
}
html,body{
width: 100%;
height: 100%;
}
footer ul {
display: flex;
position: fixed;
left: 0px;
bottom: 0px;
width: 100%;
height: 40px;
}
footer ul li {
flex: 1;
text-align: center;
list-style: none;
height: 40px;
line-height: 40px;
background: gray;
}
style>
head>
<body>
<script type="text/javascript" src="js/vue.js" >script>
<div id="box">
<keep-alive>
<component :is="who">component>
keep-alive>
<footer>
<ul>
<li @click="who='home'"><a>首页a>li>
<li @click="who='list'"><a>列表页a>li>
<li @click="who='shopcar'"><a>购物车首页a>li>
ul>
footer>
div>
<script>
var vm=new Vue({
el:"#box",
data:{
who:"home"
},
//局部组件
components:{
"home":{
template:`home `
},
"list":{
template:`list`
},
"shopcar":{
template:`shopcar`
}
}
})
script>
body>
html>
*混合父组件的内容与子组件自己的模板–>内容分发
*父组件模板的内容在父组件作用域内编译;子组件模板的内容在子组件作用域内编译。
<div id="box">
<child>
<div>aaaaaaaaaadiv>
child>
<swiper>
<div v-for="data in datalist">
{{data}}
div>
swiper>
div>
<script>
Vue.component("child",{
template:`
child
`
})
Vue.component("swiper",{
template:`
`
})
var vm=new Vue({
el:"#box",
data:{
datalist:['111','222','333']
}
})
script>
<div id="box">
<child>
<div slot='a'>aaaaaaaaaadiv>
<div slot="b">bbbbbbbbbbdiv>
child>
div>
<script>
Vue.component("child",{
template:`
child
`
})
var vm=new Vue({
el:"#box",
data:{
}
})
script>
<html>
<head>
<meta charset="UTF-8">
<title>title>
head>
<style type="text/css">
.kerwinfade-enter-active, .kerwinfade-leave-active {
transition: all 1.5s;
}
.kerwinfade-enter, .kerwinfade-leave-to /* .fade-leave-active below version 2.1.8 */ {
opacity: 0;
transform: translateX(100px);
}
.kerwinbounce-enter-active {
animation: bounce-in .5s;
}
.kerwinbounce-leave-active {
animation: bounce-in .5s reverse;
}
@keyframes bounce-in {
0% {
opacity: 0;
transform: translateX(100px);
}
100% {
opacity: 1;
transform: translateX(0px);
}
}
style>
<body>
<script type="text/javascript" src="js/vue.js" >script>
<div id="box">
<button @click="isShow=!isShow">点击button>
<transition name="kerwinfade">
<div v-if="isShow">111111div>
transition>
<transition name="kerwinbounce">
<div v-if="isShow">222222div>
transition>
div>
<script>
var vm=new Vue({
el:"#box",
data:{
isShow:false
}
})
script>
body>
html>
<div id="box">
<button @click="isShow=!isShow">点击button>
<transition name="bounce" mode="out-in">
<p v-if="isShow" key="1">1111111p>
<p v-else key="2">222222p>
transition>
div>
<script>
var vm=new Vue({
el:"#box",
data:{
isShow:true
}
})
script>
<div id="box">
<keep-alive>
<transition name="bounce" mode="out-in">
<component :is="who">component>
transition>
keep-alive>
<footer>
<ul>
<li @click="who='home'"><a>首页a>li>
<li @click="who='list'"><a>列表页a>li>
<li @click="who='shopcar'"><a>购物车首页a>li>
ul>
footer>
div>
<script>
var vm=new Vue({
el:"#box",
data:{
who:"home"
},
//局部组件
components:{
"home":{
template:`home `
},
"list":{
template:`list`
},
"shopcar":{
template:`shopcar`
}
}
})
script>
< transition-group>不同于 transition, 它会以一个真实元素呈现:默认为一个 < span>。你也可以通过 tag 特性更换为其他元素。
提供唯一的 key 属性值
什么是生命周期? 简而言之:从生到死的过程,从Vue实例创建-运行-销毁的过程
Vue实例有一个完整的生命周期,也就是从开始创建、初始化数据、编译模板、挂载Dom、渲染→更新→渲染、销毁等一系列过程 生命周期方法?
Vue从生到死的过程中伴随着各种各样的事件,这些事件会自动触发一些方法.这些方法我们统称为生命周期方法 生命周期钩子 = 生命周期函数 =
生命周期事件 创建期间生命周期方法
beforeCreate:
created:
beforeMount
mounted 运行期间生命周期方法
beforeUpdate
updated 销毁期间的生命周期方法
beforeDestroy
destroyed
https://cn.vuejs.org/v2/guide/instance.html#%E7%94%9F%E5%91%BD%E5%91%A8%E6%9C%9F%E5%9B%BE%E7%A4%BA
https://www.swiper.com.cn/usage/index.html
<div id="box">
<div v-name="'red'">1111div>
<div v-name="'yellow'">1111div>
<div v-name="mycolor">1111div>
div>
<script>
//操作底层dom
Vue.directive("name",{
inserted(el,bind){
//指令的生命周期-创建
//插入
//console.log("当前节点插入到父节点了")
//console.log(el) //找到div标签
//console.log(bind)
console.log(bind.value)
//el.style.background="red"
el.style.background=bind.value
},
update(el,bind){
//指令生命周期的-更新
el.style.background=bind.value
}
})
var vm=new Vue({
el:"#box",
data:{
mycolor:"red"
}
})
script>