Vue学习 一阶段
一、基础部分
一、简单了解
- let---变量 const---常量
- const的使用注意:
注意一:一旦给const修饰的标识符被赋值之后,不能修改。
const name = 'why'; name = 'abc'; //---error
注意二:在使用const定义标识符,必须经行赋值。 -- const name = ‘xx’;
注意三:常量的含义是指向的对象不能修改,但是可以改变对象内部的属性。
const obj = { name : 'why', age : 18, height: 165 } //不可 obj = xx;但是可修改内部属性值 obj.name = 'kobe'; obj.age = 40; obj.height = 166;
--------建议:在ES6开发中,优先使用 const,只有需要改变某一个标识符的时候才使用 let
- v-for 语句 --遍历循环数组----item获取movies中的数据,放入item中,将其输出界面
*******数组中的响应式方法 当看见 方法中包含 ...items: T[] 则可一次多个值 (,,,)
1.push方法 2.pop()方法:删除数组中最后一个元素 3.shift():删除数组中第一个元素 4.unshift():在数组最前面添加元素
5.splice(start,二参,) 6.sort() 排序 顺序排序 7.reverse() 排序 直接反排序 8.通过索引值修改数组的元素
-
//1.push方法 // this.letters.push('aasd') // this.letters.push('aasd','ahyeh','hhhsd') //2.pop()方法:删除数组中最后一个元素 // this.letters.pop(); //3.shift():删除数组中第一个元素 // this.letters.shift(); //4.unshift():在数组最前面添加元素 // this.letters.unshift('12asd','asdf','124756s'); //5.splice(start,二参,)作用:删除元素//插入元素//替换元素---start既初始位置 //删除元素:第二个参数转入你要删除几个元素(如果没有传值,则删除之后所有元素) //替换元素:第二个参数,表示要替换几个元素,后面是用于替换前面<删除>的元素 //插入元素:既第二个元素 0 ,不删除元素,直接在第一个参数后加。 // this.letters.splice(1,3,'m','n','n'); //6.sort() 排序 顺序排序 // this.letters.sort(); //7.reverse() 排序 直接反排序 // this.letters.reverse(); //8.通过索引值修改数组的元素 // this.letters[0] = 'aaaa';
1. v-for 语句 --遍历循环数组
-
<!-- 1.在遍历过程中,没有使用索引值(下标值)--> <ul> <li v-for="item in movies">{{item}}</li> </ul> <!-- 1.在遍历过程中,获取索引值(下标值)--> <ul> <li v-for="(item,index) in movies">{{index+1}}.{{item}}</li> </ul>
2. v-for 遍历对象
-
<!-- 1.在遍历对象过程中,如果只是获取一个值,获得的是value--> <ul> <li v-for="item in info">{{item}}</li> </ul> <!-- 2.获取key和value--> <ul> <li v-for="(item,key) in info">{{item}} - {{key}}</li> </ul> //-------------------对象结构数据 info:{ name:'why', age: 18, height:1.65 }
3. 在使用 v-for 添加上key属性
官方推荐:在对应的元素或组件添加一个:key 属性。
---原因:如在执行插入操作时,为了更加高效的插入。加上一个 key 属性,作用唯一标识符
目的: key 的作用主要是为了高效的更新虚拟DOM
4.for语句的一些写法
let totalPrice = 0 1.普通的for循环 for (let i = 0; i < this.books.length;i++){ totalPrice += this.books[i].price * this.books[i].count } return totalPrice //2.for(let i in this.books)---简单形式 for (let i in this.books){ totalPrice += this.books[i].price * this.books[i].count } return totalPrice //3.for(let i of this.books)----简单形式 for(let item of this.books){ totalPrice += item.price * item.count } return totalPrice
- v-on:click / @click语句
- v-on:click / @click语句--监听事件-----执行methods中定义的方法。
- v-on参数 <目前理解:本身有个默认参数event,在需额外传入值时,两个都写 (abc,$event)event特殊点+$>
------如果该方法不需要额外参数,那么方法后的()可以不加。
<注意:如果方法本身中有一个参数,那么会默认将原生事件event参数传递进去>
------如果需要同时传入某个参数,同时需要event时,可以通过 $event 传入事件
- v-on修饰符
- .stop -- 规定其只在该 / 作用域:button / 中,而不执行以外的方法
- .prevent -- 阻止默认事件的发生,如:提交表单,先打印后提交,提交由自己控制。-----
- .(keyCode | keyAliast) ---只当事件是从特定键触发时才触发回调。--就是键盘某个键 触发事件方法
- .native --监听组件根元素的原生事件
- .once --只触发一次回调
- methods属性--在Vue对象中定义的方法。
<button v-on:click="add">+</button> <button @:click="sub">-</button> //语法糖 v-on 和 @ 简写 methods:{ //methods方法 Vue对象中定义的方法 add:function () { this.counter++; }, sub:function () { this.counter--; } }
- Vue中的MVVM
- options中的选项
***el:
类型:string | HTMLElement
作用:决定之后Vue实例会管理哪一个DOM
***data:
类型:Object | Function(组件当中data必须是一个函数)
作用:Vue实例对应数据对象
***methods:
类型:{ [ key : string ] : Function}
作用:定义属于Vue的一些方法,可以在其他地方调用,也可以在指令中使用
***生命周期函数:
二、插值语法
- Mustache语法<双大括号>----胡须----该语法,不仅仅可以直接写变量,也可以写简单的表达式
<!-- mustache语法中,不仅仅可以直接写变量,也可以写简单的表达式 --> <h1>{{firstName + lastName}}</h1> <h1>{{firstName + ' ' + lastName}}</h1> <h1>{{firstName}} {{lastName}}</h1> <h1>{{counter * 2}}</h1>
- v-once语法-----只渲染一次,不会随着数据的改变而改变-----------v-once后不需跟任何表达式
<h1>{{message}}</h1> <h1 v-once> {{message}}</h1>
- v-html语法-----指令后为string类型,会将string的HTML解析出来且进行渲染。
<h2>{{url}}</h2> <h2 v-html="url"></h2>
<a href="http://www.baidu.com">百度一下</a>
- v-text 语法-----用于将数据<字符串string >显示在界面中。作用与Mustache类似,注意:v-text会将<h2>内容</h2>覆盖。
<h2>{{message}}</h2> <h2 v-text="message">.liyinhe</h2>
- v-pre 语法------------将<h1>内容</h1> 原封不动输出。
- v-cloak 语法----掩饰、隐藏-----在某些情况下,我们的浏览器可能会直接显示出未编译的Mustache标签
<style> [v-cloak]{ display: none; } </style> //----------------样式 <div id="app" v-cloak> //-------------v-cloak--斗篷隐藏掩饰。 {{message}} //某种情况下,浏览器会显示未编译的样式。用于隐藏 </div> setTimeout(function () { const app = new Vue({ el:'#app', data:{ message:'你好呀!' }
以上的指令都是主要用于将值插入到模板内容当中-------------------------------------------------------------------------------------------------------------
三、v-bind
内容需要动态来决定,对于某些属性也可用动态来绑定:如 a 中href属性-----img中src属性
以下------v-bind指令
- v-bind指令
作用:动态绑定属性
语法糖<简写>: :
<div id="app"> //对应的imaURL和ahref 都写在data:{}中 <!-- 普通写法--> <img v-bind:src="imaURL" alt=""> <a v-bind:href="ahref">百度一下</a> <!-- 语法糖写法--> <img :src="imaURL" alt=""> <a :href="ahref">百度一下</a> </div>
- v-bind对象语法绑定 ------------对象语法:class后面跟着的一个对象。
用法一:直接通过{}绑定一个类
<h2 :class="{'active':isActive}">Hello World</h2>
用法二:也可通过判断,传入多个值
<h2 :class="{'active':isActive,'line':isLine}">Hello World</h2>
用法三:和普通类同时存在,并不冲突
<h2 class="title" :class="{'active':isActive,'line':isLine}">Hello World</h2> //当isActive和isLine都为true,则会有三个类名
用法四:过于复杂,可放在一个methods 或 computed中
<h2 class="title" :class="classes">Hello World</h2> //classes是一个计算属性
用法5:也可以用数组,但用得少。
v-bind:style对象语法来绑定一些CSS内联样式。-------------对象
<!-- <h2 :style="{key(属性名):value(属性值)}">{{message}}</h2>--> <!-- 这里 50px必须加上单引号,否则vue会将其看着变量在data中寻找--> <h2 :style="{fontSize:'50px'}">{{message}}</h2> <!--直接用一个变量使用--> <h2 :style="{fontSize:finalSize + 'px',backgroundColor:finalColor}">{{message}}</h2> <!-- style后跟着太长可放在methods中如下--> <h2 :style="getStyles()">{{message}}</h2> const app = new Vue({ el:'#app', data:{ message:'你好呀!', finalSize:100, finalColor:'red', }, methods:{ getStyles:function(){ return {fontSize:this.finalSize + 'px',backgroundColor:this.finalColor} }
- v-bind:style数组语法来绑定一些CSS内联样式。-------------数组(用得不多)
- <div v-bind : style = " [ baseStyle , overridingStyles ] “ > < /div >
- style后面跟着的是一个数组类型
四.计算属性
- 计算属性的基本使用-----------计算属性是有缓存的,多次使用只调用一次
<h2>{{fullName}}</h2> computed:{ //计算属性() fullName:function () { //属性名fullName直接使用 return this.firstName + ' ' + this.lastName } },
- 计算属性复杂些操作
<div id="app"> <h2>总价格:{{totalPrice}}</h2> </div> <script src="../js/vue.js"></script> <script> const app = new Vue({ el:'#app', data:{ books:[ {id:110,name:"Unix编程艺术",price:119}, {id:111,name:"代码大全",price:109}, {id:112,name:"深入理解计算机原理",price:98}, {id:113,name:"现代操作系统",price:89} ] }, computed:{ totalPrice:function () { let result = 0 for (let i=0;i < this.books.length; i++){ result += this.books[i].price } return result //for循环的其他写法在Vue中 // for(let i in this.books){ // // } // for (let book of this.books){ // // } }
- 计算属性的setter和getter
- 每个计算属性都包含一个getter方法和一个setter方法,
- 实际情况下只使用getter来读取----只读属性。当然也可以使用setter方法<不常用>。
computed:{ //1.该写法为简写 // fullName:function () { // return this.firstName + ' ' + this.lastName // } //--------------------------------- //完整写法 fullName:{ //2.在计算属性中set方法一般没有set方法, --只读属性 // set:function (newValue) {//一般要有参数如:newValue // }, get:function () { //3.可简写为方法1. return this.firstName + ' ' + this.lastName } } }
2.计算属性和methods的比较。
---计算属性是有缓存的,多次使用只调用一次
---methods用一次调用一次,比计算属性慢。
---以反应界面上简洁,多用计算属性。而不用methods
块级作用域ES6的补充-------ES5之前 if / for 都没有块级作用域的概念,常用function的作用域来解决应用外部变量问题
- ------ES5 中的 var 是没有块级作用域的(if/for)
- ------ES6 中的 let 是有块级作用域的(if/for)
对象的字变量增强写法
五、 filter / map / reduce高阶函数的使用
编程范式: 命令式编程/声明式编程
编程范式:面向对象编程(第一公民:对象) / 函数式编程(第一公民:函数)
1. filter函数: ---filter函数有一个要求:必须返回一个Boolean值
---true时 <函数内部会自动将这次回调的 n 加入到新的数组>
---false时 <函数内部会过滤掉这次的 n >
- ----filter函数的使用
const nums = [ 10 , 20 , 300 , 222 , 55 , 40] //filter函数的使用 let newNums = nums.filter(function(n){ return n < 100 }) //----10 20 55 40
2.map函数: ---将 n 添加到新的数组
---map使用
const nums = [ 10 , 20 , 300 , 222 , 55 , 40] let new2Nums = newNums.map(function (n){ return n*2 })
3.reduce函数: --- 对数组中所有的内容进行汇总。
- ---reduce使用
let total = new2Nums.reduce(function (preValue,n){ return preValue + n },0) //--------一个累加的过程
- 高阶函数的应用:确实很秀
// 3.for(let i of this.books) for(let item of this.books){ totalPrice += item.price * item.count } return totalPrice //超级版 ---确实方便 return this.books.reduce(function(preValue,book){ return preValue + book.price * book.count },0)
六、v-model ---表单绑定
1. v-model的原理以及简单使用 ----v-model其实就是一个语法糖,其本质是包含两个操作:
*** v-bind 绑定一个value属性
*** v-on 指令给当前元素绑定input事件
-
<input type="text" v-model="message"> //----这是v-model直接绑定 ------------------------------------------------------------------------- //方法一:通过methods方法 // methods:{ // valueChange(event){ // this.message = event.target.value; // } <input type="text" :value="message" v-on:input="valueChange"> //方法二:直接在@input=“ message = $event.target.value” <input type="text" :value="message" @input="message = $event.target.value">
2. v-model
- 表单互斥: 使用相同的 name = “sex”
- 如果使用了 v-model 也可以起到 互斥的效果
v-model + radio 的使用:
<labal for="male">
<input type="radio" value="男" v-model="sex" id="male">男
</labal>
<labal for="female">
<input type="radio" value="女" v-model="sex" id="female">女
</labal>
小问题:为什么 单选框时 可点击文字而来选定 到多选框却不可以了?
没有绑定Id的原因、v-bind 绑定
v-model + checkbox 使用:
// 1.checkbox单选框
<label for="agree">
<input type="checkbox" id="agree" v-model="isAgree"> 同意协议
</label>
<h2>你选择的是{{isAgree}}</h2>
// 2.checkbox多选框
<input type="checkbox" value="篮球" v-model="hobbies">篮球
<input type="checkbox" value="足球" v-model="hobbies">足球
<input type="checkbox" value="羽毛球" v-model="hobbies">羽毛球
<input type="checkbox" value="棒球" v-model="hobbies">棒球
<h3>你选择的爱好:{{hobbies}}</h3>
data:{
message:'你好呀!',
isAgree:false, //单选框 --boolean值
hobbies:[] //多选框 ---多选框数组
}
v-model + select ----也分单选和多选 和checkbox类似
***单选时:-----v-model 绑定的是一个值
-----选中option中的一个时,会将它对应的value赋值到mySelect中
***多选时: -----v-model 绑定的是一个数组
-----选中多个值时,会将选中的option对应的value添加到数组mySelect中
-
//选择一个值 //选择多个值 <select v-model="mySelect"> <select v-model="mySelect" multiple> 多个 <option value="apple">苹果</option> <option value="orange">橘子</option> <option value="banana">香蕉</option> </select> <p>你最喜欢的水果:{{mySelect}}</p>
v-model 修饰符: 如: v-model.lazy = "message" 失去焦点在更新
- ***lazy 修饰符可以让数据在失去焦点或者回车时才会更新
- ***number修饰符 可以让在输入框中输入的内容自动转成数字类型
- ***trim 修饰符 可以过滤内容左右两边的空格
<div id = "app"> <input type="text" v-model.lazy="message"> <p>当前内容:{{message}}</p> <input type="number" v-model.number="age"> <p>当前内容:{{age}}</p> <input type="text" v-model.trim="message"> <p>当前内容:{{message}}</p>
七、组件化 重要!!!
把一个页面拆分成一个个小的组件,组件实现功能,组件又可再分。 抽象组件树
组件的使用三步骤: ***创建组件构造器
***注册组件
***使用组件
1. 组件的简单使用:
-
//3.使用组件 -----原理版 <div id="app"> <my-cpn></my-cpn> </div> //1.创建组件构造器 const cpnC = Vue.extend({ template:'' + '<div>' + '<h2>我是标题</h2>' + '<p>我是内容</p>' + '</div>' }) //2.注册组件 Vue.component('使用组件的标签名',cpnC) Vue.component('my-cpn',cpnC)
使用组件,必须在<div> / 作用域 内中
2.组件 ---全局组件 和 局部组件
***全局组件,可以在多个Vue的实例下使用 //2.注册的是---全局组件 Vue.component('使用组件的标签名',cpnC)
***局部组件
const app = new Vue({ el: '#app', data:{ }, components:{ //cpn使用组件的标签名 : 该创建的组件名 cpn: cpnC } })
3.父组件 和 子组件
<div id="app">
<cpn1></cpn1>
</div>
//1.创建第一个组件构造器(子组件)
const cpnC1 = Vue.extend({
template:'' +
'<div>' +
'<h2>我是标题</h2>' +
'<h3>nihaojfd</h3>' +
'</div>'
})
//2.创建第二个组件构造器(父组件)
const cpnC2 = Vue.extend({
template:'' +
'<div>' +
'<h2>我是标题2</h2>' +
'<h3>nihaojfd2</h3>' +
'<cpnC1></cpnC1>' +
'</div>'
,components:{ //在创建组件父组件中,注册子组件
cpnC1:cpnC1
}
})
//可当成一个顶级组件 root
const app = new Vue({
el:'#app',
data:{
message:'你好呀!'
},
components:{
cpn1:cpnC2 //注册父组件
}
})
4.注册组件的语法糖:
***全局组件: 直接在注册组件时,将对应的组件内容 { } 大括号填入
***局部组件 : 同理
-
Vue.component('cpn1',{ template:'' + '<div>' + '<h2>我是标题</h2>' + '<h3>nihaojfd</h3>' + '</div>' })
5.组件模板抽离写法----使代码更清晰。
Cannot resolve symbol 'cpn1'?存在问题待定,后期补充。 这必须 用反单引号 左上角 ` `
<!--1.第一种模板抽离 -->
<script type="text/x-template" id="cpn1">
<div>
<h2>w j </h2>
<h2>jdfhun</h2>
</div>
</script>
<!--2.第二种模板抽离 -->
<template id="cpn1">
<div>
<h2>w sdfj </h2>
<h2>jdfhun</h2>
</div>
</template>
<script src="../js/vue.js"></script>
<script>
//1.注册一个全局组件
Vue.component('cpn1',{
template: `#cpn1`, //注意注意 : 左上角 ` ` 才可以
})
6.组件内部 可保存自己数据:
***组件对象也有 data 属性 (methods等。) data 属性 必须是一个函数 而且这个函数返回一个对象,对象内部保存数据。
<template id="cpn1"> <h2>{{title}} </h2> </template> Vue.component('cpn1',{ template: `#cpn1`, data(){ return{ title:'abcde' } } })
7.父子组件间的通信
***Patent父组件 ---------props--------------> Child子组件
***Child 子组件 ----------$emit Events----------------> Patent父组件
- 1. 父组件 ---------props--------------> 子组件
父组件向子组件 传递值:-------------》 <!--组件使用 v-bind在这不支持驼峰 c-info--> <div><cpn :c-info="info"></cpn></div> <!-- 组件模板--> <template id="cpn"> <h2>{{cInfo}}</h2> </template> <script src="../js/vue.js"></script> <script> //创建子组件 const cpn = { template: `#cpn`, props:{ cInfo:{ type:Object, default(){ return{} } } } } const app = new Vue({ el:'#app', data:{ info:{ name:'tony', age:19, height:1.65 } }, //注册子组件 components:{ cpn }
- 2. 子组件----------trim---------------> 父组件
<!--组件的使用--> <div id="app"> <cpn @item-click="cpnclick"></cpn> </div> <!--子组件模板--> <template id="cpn"> <div> <button v-for="item in categories" @click="btnclick(item)"> {{item.name}} </button> </div> </template> <script src="../js/vue.js"></script> <script> //1.子组件 const cpn = { template: `#cpn`, data(){ //子组件中可以使用data ,methods 属性 return{ categories:[ {id: 'aaa',name:'热门推荐'} , {id: 'bbb',name:'手机数码'}, {id: 'ccc',name:'家用电器'}, {id: 'ddd',name:'电脑办公'} ] } }, methods:{ btnclick(item){ //发射事件 :自定义事件完成的 this.$emit('item-click',item) } } } //------------------ const app = new Vue({ el:'#app', data:{ message:'你好呀!' }, components:{ //注册子组件 cpn }, methods:{ cpnclick(item){ console.log('cpnClick',item) } } })
8.组件化开发
watch 监听属性的改变 -----和data 、props、methods 同型
***父组件直接访问子组件 : 使用 $children<是数组类型 > 或 $refs
***子组件直接访问父组件 : 使用$parent
slot <插槽>
1.***为了使封装的组件更加具有扩展性
2.***让使用者可以决定组件内部的一些内容到底展示什么
<div id="app"> <cpn><button>案例</button></cpn> <cpn><h2></h2></cpn> <cpn></cpn> <cpn></cpn> </div> <template id="cpn"> <div> <!-- 抽离共性放组件,不同放slot--> <h2>我是组件</h2> <p>我是组件,时代反击</p> <slot><button>如果指定了使用指定。未指定使用默认</button></slot> </div> </template>
2.具名插槽 给插槽 slot 取名字
<div id="app"> <cpn><span slot="left">标题</span></cpn> </div> <template id="cpn"> <div> <slot name="left"><span>左边</span></slot> <slot name="center"><span>中心</span></slot> <slot name="right"><span>右边</span></slot> </div> </template>
- 编译作用域:父组件模板的所有东西都会在父级作用域内编译;子组件模板的所有东西都会在子级作用域内编译
- 作用域插槽:----父组件替代插槽的标签,但是内容由子组件来提供
- 多样性输出。
<div id="app"> <cpn></cpn> <cpn> <!--在父组件拿到子组件数据--> <template slot-scope="slot"> <span v-for="item in slot.data">{{item}}--</span> </template> </cpn> <cpn> <template slot-scope="slot"> <!--用join('**')方法 在输出数组间 加 符号--> <span>{{slot.data.join('**')}}</span> </template> </cpn> </div> <template id="cpn"> <div> <slot :data="planguages"> <ul> <li v-for="item in planguages">{{item}}</li> </ul> </slot> </div> </template> <script src="../js/vue.js"></script> <script> const app = new Vue({ el:'#app', data:{ message:'你好呀!' }, components:{ cpn:{ template:`#cpn`, data(){ return{ planguages:['JavaScript','C++','Java','C#','Python'] } } } } })