内置对象Vue
new Vue():它是Vue里的内置对象,传递参数是对象类型传递
<script src="js/vue.js"></script>
<script>
new Vue({
})
</script>
修饰符:
- let :修饰变量
- const:修饰常量
这样定义可以实现数据分离,不用像原生js那样去绑定,且可以直接在控制台去修改值,当数据发送改变时,界面也会跟着改变
<div id="name">{{message}}</div>
</body>//写在head中没用
<script src="js/vue.js"></script>
<script>
const name=new Vue({
el:"#name",//挂载,管理这个div
data:{
message:"年后"
}
})
</script>
列表展示
<div id="name">
<ul>
<!--这里v-for可以想象成foreach,将值赋给item,item进行遍历-->
<li v-for="item in movies">{{item}}</li>
</ul>
</div>
<script src="js/vue.js"></script>
<script>
const name =new Vue({
el:"#name",
data:{
//列表自然是用数组声明
movies:["海贼王","盗梦空间","大话西游","大鱼"]
}
})
</script>
列表展示:声明是数组
v-for:可以想象成foreach,将值赋给item,item进行遍历
可以在浏览器中控制台上再添加数据:在具体变量后加入push方法
计数器
第一种方式实现:
<div id="name">
<h3>当前计数:{{num}}</h3>
<!--
v-on:click="num++"
v-on:click:设置一个监听事件
num++:从vue对象中拿值并赋值
-->
<button v-on:click="num++">+</button>
<button v-on:click="num--">-</button>
</div>
<script src="js/vue.js"></script>
<script>
const name=new Vue({
el:'#name',
data:{
num:0
}
})
</script>
v-on:click=“num++”:
- v-on:click:设置一个监听事件
- num++:从vue对象中拿值并赋值
第二种方式实现
给button设置一个函数,并在Vue对象中实现
methods:方法区
this:指向当前对象,所以可以直接拿到num属性
MVVM
- model view view model
- 当我们有数据需要展示时,view model会帮在view页面上显示
Model层
- 数据层
- 数据可能是我们固定的死数据,更多的是来自我们服务器,从网络上请求下来的数据
View层
- 视图层
- 在前端中,通常指DOM层
- 主要是给用户展示各种信息
ViewModel
- 视图模型层
- 是View和Model沟通的桥梁
- 一方面实现了数据绑定,能实时将Model的数据反应到View中
- 一方面实现了DOM监听,当DOM发生一些时间(点击,滚动)时,可以监听到,并在需要的情况下该百年对应的Data
插值语法
- v-once:指令只使用一次
<div id="app">
<h3>{{num}}</h3>
<h3 v-once>{{num}}</h3>
</div>
<script src="js/v2.6.10/vue.js"></script>
<script>
const app = new Vue({
el:'#app',
data:{
num:0
}
})
</script>
- v-html
- v-pre:可以拒绝Vue对象的解析
动态绑定事件
- v-bind:将vue对象中的数据,动态编译填充到a标签中
<div id="app">
<a v-bind:href="aHref">百度</a>
<br />
<!-- 语法糖写法 -->
<a :href="aHref">百度</a>
</div>
<script src="js/v2.6.10/vue.js"></script>
<script>
const app = new Vue({
el:'#app',
data:{
num:0,
aHref:'https://ww.baidu.com'
}
})
</script>
绑定class属性(对象语法)
绑定class属性(数组语法)
除了在标签上编译class名,也可以使用方法的形式去编译,且于普通class属性同时存在
绑定style属性(对象语法)
使用语法糖且使用方法的方式返回
绑定style属性(数组语法)
计算属性computed
当我们在静态页面页面拼接字符时,整体效果不好
计算属性可以看成是一个对象的get方法,且去掉()
计算属性并不是方法,computed是将它里面的方法当作属性来使用
computed的setter和getter
computed里的方法可以看成是一个对象,里面有getter和setter
computed:{
Name:{
set:function(newValue){
},
get:function(){
return this.filstName +' '+ this.lastName
}
}
如计算属性的具体内容如上,是有set和get方法,set需要对应的返回值,但我们一般不使用set方法,所有就有了简便方法
setter方法具体使用
计算属性和methods的对比
计算属性会有一个缓存,每次你用的时候都会看体内的属性有没有改变,没有改变就直接填充,且只填充一次,不需要每次都加载。效率就比methods高
可以看到methods运行了三次,而computed只运行了一次
const
- 一旦赋值后,就不可在修改
- 在使用const时,必须进行赋值
- const指向的对象名不能修改,但是可以改变内部的属性
对象字面量增强写法
- 属性的增强写法
const name='why';
const age=18;
const height=1.88;
//它会将name作为key,why作为value
const obj ={
name;
age;
height
}
- 函数的增强写法
//往常写法
const obj={
run:function(){
}
}
//增强写法
const obj={
run(){
}
}
v-on 事件监听
- 语法糖
//原写法
<li v-on:click="getClick" >{{temp}}</li>
//语法糖
<li @click="getClick" >{{temp}}</li>
如果该方法不需要额外参数,那么方法后的()可以不添加
- 在事件定义时,写方法时省略了小括号,但是方法本身是需要一个参数的,这个时候,Vue会默认将浏览器生产的event事件对象作为参数传入到方法
<li @click="getClick" >{{temp}}</li>
methods:{
getclick(event){
consolo.log(event)
}
}
当我们需要event对象时,可以这样写
- 方法定义时,我们需要event对象,同时又需要其他参数
<li @click="getClick(123,$event)" >{{temp}}</li>
methods:{
getclick(abc,event){
consolo.log(abc,event)
}
}
如果不写(),event对象会在第一个形参中,即abc中!
v-on修饰符
- stop:拒绝冒泡
可以看到当我们的按钮被点击时,div的click事件也触发了,形成一种冒泡
我们可以使用.stop来解决这一问题
<div @click="divClick">
<button @click.stop="btnClick">按钮</button>
</div>
- prevent:修改默认事件
像form表单只要一点击submit,就会自动提交,我们使用prevent来修改这一默认事件,让我们自己来提交
<div id="app">
<form action="https://www.baidu.com">
<button type="submit" @click.prevent="submitClick">提交</button>
</form>
</div>
- 监听键盘的enter键
<div id="app">
<input type="text" @keyup.enter="keyClick" />
</div>
v-if和v-else-if和v-else的使用
<div id="app">
<h3 v-if="score>=90">优秀</h3>
<h3 v-else-if="score>=80">良好</h3>
<h3 v-else-if="score>=60">及格</h3>
<h3 v-else>不及格</h3>
</div>
v-show与v-if的区别
//当条件为false时,vue会将它从dom元素中删除,当为true时,又会出现
<h3 v-if="score>=90">优秀</h3>
//当条件为false时,vue会给他添加一个行内样式,display:none,并显示
<h3 v-show="score>=90">优秀</h3>
数组中遍历对象
数组中响应式方法
- unshift():在数组最前面添加元素,可一次添加多个值
this.letters.unshift('11','22');
- push():在数组末尾加上元素,view也可以实时更新,可一次添加多个值
this.letters.push('a');
- pop():删除数组末尾的元素
this.letters.pop();
- shift():删除数组第一位元素
this.letters.shift();
- sort():元素排序
this.letters.sort();
- reverse():元素反转
- splice():删除元素、插入元素、替换元素
删除元素
//删除元素,从下标1开始包含1,删除2个元素
//删除前:1,2,3,4,5 删除后:1,4,5
this.letters.splice(1,2)
替换元素
//替换元素,从下标1开始包含1,替换2个元素,后面为替换的指
//替换前:1,2,3,4,5 替换后:1,a,b,4,5
this.letters.splice(1,2,'a','b')
插入元素
//插入元素,在下标1插入元素,0:不删除也不替换
//插入前:1,2,3,4,5 插入后:1,a,b,2,3,4,5
this.letters.splice(1,0,'a','b')
js高阶函数
-
filter:必须返回一个布尔值
true:将当前元素添加到新的数组,数组为filter内部创建 false:过滤函数
const nums=[10,20,40,120,440,770,110];
//n:nums数组的元素
let newNums=nums.filter(funcrtion (n){
return n>100
})
console.log(newNums);//[120,440,770,110]
-
map:将返回的值,添加到新的数组中,数组为map函数内部创建
const nums=[10,20,40];
//n:nums数组的元素
let newNums=nums.filter(funcrtion (n){return n*2
})
console.log(newNums);//[20,40,80]
- reduce:将数组中的元素进行汇总(元素相加)
```html
const nums=[10,20,30,40];
//temp初始值为0 n为nums数组的元素
let total= nums.reduce(function(temp ,n){`在这里插入代码片`
return temp+n//返回相加的值
},0)
- 使用链式加箭头函数集成以上函数
const arrs=[10,20,30,40,110]
let total=arrs.filter(arr => arr<100).map(arr => arr*2).reduce((temp,arr)=>temp+arr);
console.log(total);//200
表单绑定v-model
- v-model:将用户的值以String类型传给对象
我们使用v-model双向绑定message到input标签的value属性上了,那么当input的value属性值发生改变时,h3标签也会随着改变,但html值是不会改变的,目前也不清楚这一现象
v-model作用原理如下:
可以将v-model想象成一个语法糖,背后其实包含两个操作
- v-bind绑定一个属性
- v-on监听input事件
//v-model
<input type="text" v-model="message" />
//原理:v-on:input:绑定input的value事件,当value的值发生改变就触发
//$event.target.value; $envent:浏览器的event对象 target.value:获取input的值
<input type="text" v-bind="message" v-on:input="message=$enven.target.value"
-
v-model结合radio类型使用
可以看到被选中的是男时,h3标签也会显示男,因为v-model双向绑定了input的value属性
radio:绑定同一属性,所以只能单选
label:点击文字时,也可以选中 -
v-model结合checkbok使用
checkbok:可以复选 -
v-model集合select
v-model的修饰符
-
我们每次在input中实时写入数据,而对象中的数据也要跟着实时更新,会浪费掉一些不必要的资源,所以当input标签失去焦点时,再实时更新数据
-
lazy:当用户敲enter或者失去焦点时再实时更新数据。
<input type="text" v-model.lazy="message" />
- number:当用户输入数字时更新数据
//修饰了number,所以v-model会将数据以number(int)类型传入过去
<input type="number" v-model.number="age" />
- trim:去掉空格
<input type="number" v-model.trim="name" />
组件化
- 创建组件构造对象
// 第一步:创建组件构造器 需要拿到vue对象 及extend方法
//template:模板(文本内容),要显示的html代码
const cpnC = Vue.extend({
template :`<div>
<h2>我是标题</h2>
<p>我是内容</p>
</div>`
})
- 注册组件
//第二步:注册组件 myCpn:组件的标签名 cpnC:组件构造器
Vue.component('my-cpn', cpnC)
- 使用组件:需要在Vue管理的实例中使用
<div id="app">
<my-cpn></my-cpn>
</div>
全局组件和局部组件
- 全局组件:可以在多个vue实例中使用
//注册组件 myCpn:组件的标签名 cpnC:组件构造器
Vue.component('my-cpn', cpnC)
- 局部组件:只能在一个vue实例中使用,它在vue实例中被注册的,使用它只能在vue实例中被实现
const app = new Vue({
el:'#app',
data:{
name:'张三'
},
components:{
cpn: cpnC
}
})
注:cpn为组件的标签名,尽量不要使用“-”
父组件与子组件的区别
- 首先创建两个组件构造器
const cpnC1 = Vue.extend({
template :`<div>
<h2>我是标题1</h2>
<p>我是内容</p>
</div>`
})
const cpnC2 = Vue.extend({
template :`<div>
<h2>我是标题2/h2>
<p>我是内容</p>
</div>`
})
- 在第二个组件构造器注册第一个组件构造器,之后在template中使用标签名,这样第二个组件构造器就是父构造器,
const cpnC2 = Vue.extend({
const cpnC2 = Vue.extend({
template :`<div>
<h2>我是标题</h2>
<p>我是内容</p>
<cpn1></cpn1>
</div>`
,
components:{
cpn1:cpnC1
}
})
- 这里要注意:cpnC1被注册了,但是父类组件没有被注册,所以我们可以使用局部组件的方式注册它
const app = new Vue({
el:'#app',
data:{
name:'张三'
},
components:{
cpn: cpnC2
}
})
注册组件的语法糖
在全局组件中,这样我们就可以内部创建组件构造器
Vue.component('cpn',{
template :`<div>
<h2>我是标题</h2>
<p>我是内容</p>
</div>`
})
在局部组件
const app = new Vue({
el:'#app',
data:{
name:'张三'
},
components:{
cpn: {
template :`<div>
<h2>我是标题</h2>
<p>我是内容</p>
</div>`
}
}
})
组件模板抽离
使用template标签,并设定一个id
组件数据的存放
- 组件是访问不到vue实例中的data中的数据的
- 它的数据存放在,组件构造器中的data函数中,需要返回一个对象,我们可以访问这个对象里的数据
Vue.component('cpn',{
template:'#cpnC',
data() {
return {
title:'我是头部',
name:'我是内容'
}
}
})
- 组件也有自己的方法,在组件的构造器中
写这个例子时,发现组件组件必须要依靠vue实例来实现,否则不显示内容,且button按钮,外部必须要有一个div包裹
父子组件通信
- 父组件可以通过props向子组件转递数据
1.父组件在子组件标签上通过v-bind事件向子组件传递数据
2.子组件通过props,并在其中设定属性名,需要与标签上的一样
3.展示pros的属性名,实际上拿到的是父组件的数据
注:子模板template中必须要加上div!!!,当子模版的标签过多时,必须要一个根标签包裹起来!!!!!
子组件可以指定父组件传递进来的数据类型
components:{
cpn:{
template:'#cpn',
props:{
//对象形式 Array:数组 Number:整数
mymovies:Array,
mynum:Number
}
}
子组件指定默认值
components:{
cpn:{
template:'#cpn',
props:{
//对象形式 Array:数组 Number:整数 default:默认值
mymovies:{
type:Array,
default:['']
},
mynum:{
type:Number,
default:0
}
}
}
}
- 子组件通过事件向父组件发送消息
1.设定一个点击事件,并将这些数据封装起来,通过whis.$emit(‘cpnclick’)发送一个cpnclick事件
2.父组监听子组件的cpnclick事件,拿到数据
<div id="app">
<!-- 父組件通过监听事件获取item,
组件之间如果不传递参数就会默认接收item,
并不会接收envent,因为他们不是浏览器之间的监听-->
<cpn @btnclick="cpnclick"></cpn>
</div>
<template id="cpn">
<div>
<button v-for="item in movies" @click="btnClick(item)">
{{item.name}}
</button>
</div>
</template>
<script src="../js/v2.6.10/vue.js"></script>
<script>
//实例vue
const app =new Vue({
el:'#app',
components:{
cpn:{
template:'#cpn',
data() {
return {
movies:[
{id:01,name:'西游记'},
{id:02,name:'水浒传'},
{id:03,name:'三国演义'}
]
}
},
methods:{
btnClick(item){
//子组件发送一个事件
this.$emit('btnclick',item);
}
}
}
},
methods:{
cpnclick(item){
console.log('父组件',item)
}
}
})
</script>
父子间的访问方式
- 父组件访问子组件:使用 $ children或者$ refs
使用$ children方式
只需要设定一个点击事件,在事件中使用this.$children.子组件的方法名(属性)就好
使用refs方式:开发中常用
在子标签名上加上ref=“别名”
在具体方法中,使用this.$refs.别名.子组件的方法名(属性)就好
- 子组件访问父组件:使用$ parent
在具体方法中,使用this.$ parent