基本介绍
vue是什么
目标:了解vue的一些基础概念。
官方网站: https://cn.vuejs.org/
vue是:渐进式javascript框架。
两组概念
(1)框架
- 库。只提供一些API给开发者使用。jquery 是一个js库
- 框架。拥有自己的规则和元素,它比库要更加强大一些。
- UI框架 - bootstrap。包含 js html css 主要实现了一套支撑网站开发的常用控件(对话框,弹出框,tab页签…)
- JS框架 - 纯js编写,提供了开发网站功能的标准(规则),约定开发规则,通过这些规则组织你的功能代码,。
(2)渐进式
- 它可以很简单,帮助,确保最快上手,最快使用
- 它也可以很复杂,配合不同的工具,在各种复杂的应用场合下工作。
上得厅堂,下得厨房
文可提笔安天下,武可上马定江山
能做什么
- 充当模板引擎,渲染数据,制作网页
网页上的四个要素
- 结构 — html
- 样式 — css
- 行为 — js
- 数据 — 后端接口返回的json数据
- 通过脚手架工具,开发单页应用。直接用它来开发网站!
- 在其它框架下开发微信小程序或者跨端,跨平台应用
小结:啥都能做!
安装vue
在不同的学习阶段有不同的使用方式:
-
基础阶段:直接当做一个普通的js库来引入使用(与jquery类似)
- 本地方式
- 先下载:https://cn.vuejs.org/js/vue.js
- 然后在你的.html文件中引入:
<script src="./vue.js"></script>
- 直接引入公网中的js
- 引入:
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
- 本地方式
-
项目阶段:以npm包的方式来引入
- 安装
npm i vue
- 导入后使用即可
- 安装
总结:在基础学习阶段,使用本地下载引入的方式或者公网中的js均可。
体验vue
第一个vue程序。
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><!-- 2. 视图 --><div id="app"><h3>{{msg}}</h3><input v-model="msg" type="text"></div><!-- 引入VUE核心js文件 --><script src="./vue.js"></script><!-- 功能代码 --><script>// 需要把数据渲染到页面上// 页面上输入的内容,收集到数据中// 2. 控制数据模型和视图管理者const vm = new Vue({el: '#app',// 1. 数据模型data: {msg: 'hi vue'}})</script>
</body>
</html>
安装live-server插件
在我们写一些页面功能时,如果希望实时观察到效果,可以安装这个插件。(与学习vue无关)
功能说明
它是一个vscode的插件,它会监听代码的改动,一旦我们修改了代码,它会立即刷新网页。
安装过程
使用步骤
- 使用vscode打开某个文件夹 (不是打开单个文件!)
- 打开某个.html文件上,右键,在弹出的菜单上选择
open with live server
此时,它会自动调起浏览器,并打开我们当前选择的.html文件。
补充
另一种打开方式
在当前的.html打开时,在vscode的状态栏上找到liver-server 的图标,点击一次。
更友好的工作模式
在你的电脑屏幕上同时打开vscode和浏览器,一边写代码一看效果。
vue的特点
声明式渲染
允许采用简洁的模板语法来声明式地将数据渲染进 DOM 的系统。
<div id="app">{{ message }}
</div>
数据驱动视图
在vue中,通过修改数据即可更新视图(页面),大大解放了操作dom的时间,把精力放在业务上。 所以,我们在写vue代码时,会更加关心数据的构成。
双向数据绑定
vue是一个典型的 MVVM 思想的框架
- M 是数据模型 model
- V 是视图(界面)view
- VM 是控制数据模型和视图的管理者
把上面的代码,可以拆分成,M + V + VM 结构。
数据可以影响视图变化,视图变化也会影响数据变化。
组件化开发
把一个网站功能,分割若干个组件,相同类型的组件可复用,组件功能是独立的,可维护性高。
vue实例和它的三大件
-
el
-
data
-
methods
vue实例
const vm = new Vue({el: ,data: ,methods: ,
})
理解:
- Vue(V是大写的)是一个构造器,用它来创建vue实例。
- vm就是创建出来的实例对象,
- 这个构造器只有一个参数,这个参数是一个对象,其中的属性名和属性值都有特定的含义。
el选项
el选项,用来指定vue实例管理的容器。
<body>{{msg}}<div id="app">{{msg}}<!-- 被管理的容器才可以使用vue提供的功能 --></div><script src="./vue.js"></script><script>// 初始化vue实例,vue实例就是vm的意思const vm = new Vue({// 初始化的配置对象,里面有很多选项// el === element 元素,标签,容器// el指定当前vue实例管理的容器是谁。// 值是:选择器 | dom元素// el: '#app',// el: document.querySelector('#app'),// Do not mount Vue to <html> or <body> - mount to normal elements instead.// el不能指定 html 和 body 容器el: 'body',data: {msg: 'hi vue'}})</script>
</body>
</html>
要点:
- 可以是选择器,也可以是某个dom元素
- 只能是普通的dom(div,p),不能是 html,body 容器
- 不在此容器内的部分,不会受到vue实例影响
data选项
作用:它是一个对象,它用来规定数据。
<div id="app"><h3>理解data</h3><p>姓名:{{name}}</p><p>爱好1:{{aihao[0]}}</p><p>爱好2:{{aihao[1]}}</p><ul><li>QQ:{{lianxi.QQ}}</li><li>email:{{lianxi.email}}</li><li>weixin:{{lianxi.weixin}}</li></ul></div><script>// data: 它是一个对象,用来规定数据。// 现在是把vue当作一个模板引擎来使用。// 它的作用是把数据显示在页面上。data就是用来// 约定数据的。// 在后面的学习的,这个部分的数据会是// 从ajax接口中获取到的// 访问数据:// 方法一:在视图中,通过{{}}插值表达式 直接访问。/// 不要写data.XXX - 不要写data - 不要写data// 方法二:通过Vue实例vm来访问// vm.XXXconst vm = new Vue({el: "#app",// el: document.getElementById("app"),data: {name: '凡哥-凡叔',aihao:['听音乐','读书'],lianxi: {QQ:"123456",email:'xxxxxx',weixin:'yyyyyy'}}})console.log(vm)console.log(vm.name)console.log(vm.aihao[1])console.log(vm.lianxi.QQ)</script>
访问方式:
- 通过实例可以直接访问data中的数据 vm.msg
- 在模板中使用数据的字段名称即可。{{msg}}
注意:
- 在data中显性声明的数据,都是响应式数据,可以数据驱动视图。
- 在模板中使用的数据,建议在data中提前声明,即使没有值也需要声明。
methods选项
目标:知道vue选项中methods选项的使用方法和注意事项。
作用:为vue实例提供自定义函数的(大白话:自己的业务函数书写位置)
调用方法:
- vue实例直接调用,且函数的this指向就是vue实例,就是vm
- 在vue实例管理的模板(管理的容器|视图)中使用这些函数
// Vue构造器中的参数是一个对象,它有很多的属性// el,// data// methods// ... 还有好多好多....// methods 是一个对象// 在对象中,正常定义函数// (1) 定义函数// (2) 调用函数// 1. 通过vm实例来调用// 2. 也可以在页面上,通过{{函数名}}来调用 --不推荐--// 3. 当做事件的回调函数来使用。const vm = new Vue({el: "#app",data: {name: '凡哥-凡叔'},methods: {// 定义函数// 函数用来做你自己业务逻辑// 方法1:"changeName1": function() {console.log('changeName1')this.name = "小凡1"},// 方法2:推荐// es6中支持对对象中的方法的简写changeName2 () {console.log('changeName2')console.log(this == vm)this.name = "小凡2"},// 方法3:箭头函数。// 其中的this是有问题!!// 这里的this指向的是window,而不是vm实例// 所以,不能使用this来操作数据。changeName3: () => {console.log('changeName3')console.log(this)this.name = "小凡3"}}})// console.log(vm)// vm.changeName2()// vm.changeName1()
注意:
书写函数有很多方式
- 普通的写法
- es6简写格式 (推荐使用)
- 有箭头函数 (不使用。因为其中的this不指向vue实例)
在函数的内部(不是箭头函数的情况)
- this会指向vue实例。
插值表达式
目标:了解vue术语插值表达式是什么和使用场景。
在vue中{{ }}
语法,叫做:插值表达式,大白话就是输出值的语法。
在插值表达式中可以写:
- 写data数据字段名称
- 写methods函数的名称,进行调用
- 对data数据字段进行表达式运算
- 加减运算
- 三元运算
- …
不能写
- js语句:声明变量,分支,循环
- 访问在vue实例之外,自定义的全局变量
<div id="app"><h3>理解插值表达式</h3><p>姓名:{{name}}</p><!-- 字符串的拼接 --><p>{{name +',你好'}}</p><!-- 算术运算 --><p>{{num/5}}</p><p>{{num > 90 ? 'A+':'不是A+'}}</p><p>method:{{test1()}}</p><!-- 不能声明变量 --><!-- {{var a = 1}} --><!-- 不能写分支 --><!-- {{ if(true) {} }} --><!-- 不能访问除了vm实例中声明的数据 --><!-- {{num123}} --></div><script>// 插值表达式: {{}}// 作用:输出值(把数据渲染到页面)// {{}} 中可以写什么// 1. data数据字段名// 2. methods函数名称,进行调用// 3. data数据字段进行表达式运算// 算术// 字符串拼接// 三元// {{}} 不可以写什么// 1. 不能写js语句:声明变量,分支,循环.....// 2. 不能访问除了vm实例中声明的数据// [Vue warn]: Property or method "num123" is not // defined on the instance(实例) but referenced(引用) // during rendervar num123 = 100const vm = new Vue({el: "#app",data: {name: 'vue',num: 80},methods: {test1 () {console.log('test1')}}})</script>
指令
指令(directive),其实就是一个以v-开头的标签属性,例如:v-model
双向绑定指令。
vue提供了一些指令,这些指令都是以v-开头,他们可以扩展标签的原有功能。这些指令的值,可以是js表达式,当关联js表达式依赖的数据发生变化,对应的指令就会产生作用。
扩展功能:
- 输入框双向绑定
- 标签的显示隐藏
- 标签显示的内容
- …
学习vue,主要就是要学习两个地方的内容:
- Vue实例(vue实例与三大件)
- 模板(视图)中的规则:插件表达式,指令
v-text和v-html
目标:能够使用v-text和v-html去更新标签内容。
这组指令作用:
- 更新标签的内容
- 根据数据进行更新
具体的作用:
- v-text 更新标签的内容,格式是文本,和 innerText 相似。
- v-html 更新标签的内容,格式是html,和 innerHTML 相似。
在代码中体验:
<div id="app"><h3>v-html,v-text</h3><!-- {{}}可以用来设置标签中的部分内容 --><p>学习内容:{{str}}</p><p>{{str}}</p><!-- v-text:设置标签中的 全部内容 --><p v-text="str"></p><!-- v-text:设置标签中的 如果这里内容是html字符串,它会转义一下,只是显示字符串而不会显示成对应的dom结构 --><div v-text="strHtml"></div><!-- v-html用来设置标签中的内容。与v-text不同,它直接解析其中的html结构,并渲染 --><div v-html="strHtml"></div></div><script>// v-text : ===> innerText// v-html : ===> innerHTMLconst vm = new Vue({el: "#app",data: {str: 'vue',// 有时,从后端取回来的数据是一个html字符串。// 例如:获取文章详情,取回来就是一html字符串。strHtml: '<h1>vue</h1>'}})</script>
总结:
- v-text 更新 纯文本
- v-html 更新 html内容
v-show和v-if
功能
能够使用v-show和v-if去控制标签的显示隐藏。
格式
<元素 v-show="布尔值"></元素>
<元素 v-if="布尔值"></元素>
这对指令的共同点:都能控制元素的是否可见
这对指令的不同点:
- v-show是通过 display:none来控制隐藏
- v-if 是通过动态创建和移除元素。
示例
<div id="app"><h3>v-if,v-show</h3><div v-if="isVisiable">我是通过v-if来控制是否可见!</div><div v-show="isVisiable">我是通过v-show来控制是否可见!</div></div><script>// 作用:控制标签的可见与不可见// 格式:// <元素 v-show="布尔值"></元素>// <元素 v-if="布尔值"></元素>// 如果是false,则不可见,如果是true,则可见// 区别:// 对于v-if,如果为false,则,在页面根本就不生成这个dom。// 所以不可见。// 对于v-show,如果为false,则,在页面有这个dom,display:none。// 所以不可见。const vm = new Vue({el: "#app",data: {isVisiable: false}})setInterval(function() {vm.isVisiable = !vm.isVisiable},5000)</script>
总结:区分下使用场景:
- v-show 性能较好,对应需要频繁切换显示与隐藏的功能,可以使用v-show。
- v-if 减少标签,状态切换次数少的时候,使用使用v-if
v-on
功能
v-on指令的作用是:指令监听 DOM 事件,并在触发时运行一些 JavaScript 代码。
格式
三种使用格式
# 格式一:把要执行的代码直接写在""内部。适合少量代码
<标签 v-on:事件名="要执行的代码"></标签>
# 格式二:指向methods中的定义的函数
<标签 v-on:事件名="methods中的函数"></标签>
# 格式二:指向methods中的定义的函数,并传入参数
<标签 v-on:事件名="methods中的函数(实参)"></标签>
说明:
- 能支持所有原生事件名:所有的原生js事件
- v-on可以简写成@
示例
<div id="app"><h3>v-on</h3><div v-show="isVisiable">内容</div><!-- 格式一:把要执行的代码直接写在""内部。适合少量代码 --><button v-on:click="isVisiable=true">显示内容</button><button v-on:click="isVisiable=false">隐藏内容</button><!-- 格式二:指向methods中的定义的函数 --><!-- 加与不加()一样:v-on:click="f1()" 与 v-on:click="f1" --><button v-on:click="f1">调用methods中的函数</button>
<br><!-- 格式三:指向methods中的定义的函数 --><!-- 注意:1. 如果要传入参数,则必须要加()2. 如果传入当前这个事件的事件对象,则传入固定名字 $event --><button v-on:click="f2(10)">调用methods中的函数传入10</button><br><button v-on:click="f3(11,$event)">调用methods中的函数传入11,传入事件对象</button></div><script>// 功能: v-on 用来监听事件// 格式:// 格式一:把要执行的代码直接写在""内部。适合少量代码// <标签 v-on:事件名="要执行的代码"></标签>// 事件名:就是所有的dom原生事件 // click,input,mouseenter,blur,......// 格式二:指向methods中的定义的函数// <标签 v-on:事件名="methods中的函数"></标签>// 格式三:指向methods中的定义的函数,并传入参数// <标签 v-on:事件名="methods中的函数(实参)"></标签>const vm = new Vue({el: "#app",data: {isVisiable: false},methods: {f1 () {console.log("f1被调用")alert(1)this.isVisiable = true},f2 (m) {alert(m)console.log(m)},// 形参名m,eventObj。这两名,是可以自己定义的。f3 (m, eventObj) {console.log(m, eventObj)}}})</script>
总结:绑定函数的时候带不带括号?
- 如果你需要接受事件触发的默认传参,不带括号
- 如果你需要自己来进行传参,需要带括号,自己传实参
- 如果什么参数都不要,带不带无所谓
案例-折叠面板
用v-on和v-show实现折叠面板
<div id="app"><h2>案例:折叠面板</h2><div class="box"><div class="title" ><h4>我是标题</h4><span class="btn" @click="isOpen=!isOpen">{{isOpen ? '收起' : '展开'}} </span> </div><div class="container" v-show="isOpen">我是内容<br>我是内容</div></div>
</div>
<script>var vm = new Vue({el: '#app',data: {isOpen: false}})
</script>
补充-修饰符
<div id="app"><h3>v-on 修饰符</h3><div v-on:click="hClickDiv">div<button @click="hClickBtn">按钮</button><br><button v-on:click.stop="hClickBtn">点击按钮不会冒泡</button><br><a href="http://www.baidu.com" v-on:click="hClickA">百度</a><br><a href="http://www.baidu.com" v-on:click.prevent="hClickA">不跳转百度</a><br><a href="http://www.baidu.com" v-on:click.prevent.stop="hClickA">不跳转百度不冒泡</a></div> </div><script>// vue中的事件也有冒泡机制。// 在子元素上的点击事件,也会触发父元素上的点击事件。// 如果要阻止冒泡,只需给事件添加个修饰符.stop// 格式: 事件名.stop// 示例:click.stop// 如果要阻止默认行为,只需给事件添加个修饰符.prevent// 格式: 事件名.prevent// 示例:click.prevent// 如果需要,也可以一起使用,相当于两个效果叠加// 格式: 事件名.prevent.stop// 示例:click.prevent.stop// v-on: ----简写成---> @const vm = new Vue({el: "#app",methods: {hClickDiv () {console.log("hClickDiv")},hClickBtn (){console.log("hClickBtn")},hClickA () {console.log('hClickA')}}})</script>
v-for 列表渲染
功能
快速批量生成列表结构
格式
格式1:完整格式
<元素 v-for="(遍历变量,索引变量) in 可遍历的数据项" :key="唯一的id"></元素>
格式2:简写格式
在完整格式的基础上,可以省略 :key 和 索引变量。
<元素 v-for="遍历变量 in 可遍历的数据项"></元素>
遍历目标
对于v-for指令,可遍历的数据项可以是:
- 数组
- 对象
- 数值
代码
<div id="app"><h2>v-for</h2><div class="box"><h4>1. 对数组进行遍历</h4><ul><li v-for="(item,idx) in hobbies">{{idx}} - {{item}}</li></ul></div><div class="box"><h4>2. 对对象进行遍历</h4><span v-for="(item,prop,idx) in info">{{idx}}-{{prop}}-{{item}}</span></div><div class="box"><h4>3. 对数值进行遍历</h4><span v-for="item in 10">{{item}},</span></div>
</div>
<script src="./vue.js"></script>
<script>var vm = new Vue({el: '#app',data: {info: {name: '小张', age: 18, height: '150'},hobbies: ['唱歌', '跳舞', '打篮球']}})
</script>
使用了v-for指令的元素,在其内部可以通过插值表达式来访问遍历变量和循环变量。
v-bind
作用
动态绑定标签上的属性的值。(标签上的属性不能使用插值表达式来设置)。
例如:如何动态设置img的内容?
格式
<元素 v-bind:属性名1="值1" v-bind:属性名2="值3"></元素>
v-bind指令有简写用法 :
冒号,例如:
<img :src="data数据">
演示代码
<div id="app"><h3>v-bind</h3><!-- 如果去修改src属性? --><!-- <img alt="se" src="http://img3m8.ddimg.cn/93/1/61888458-1_b_2.jpg"> --><img alt="se" :src="imgSrc" :title="title"><br><img alt="se" v-bind:src="imgSrc" v-bind:title="title"><button v-on:click="hClick">改成11</button></div><script>// 作用 : 动态绑定标签上的属性的值// 格式 :// <元素 v-bind:属性名1="值1" v-bind:属性名2="值2"></元素>// 简写:// v-bind: ----简写---> :const vm = new Vue({el: "#app",data: {title: 'se',imgSrc: 'http://img3m8.ddimg.cn/93/1/61888458-1_b_2.jpg'},methods: {hClick () {// 设为 11this.title = "11不香吗?"this.imgSrc = 'http://img3m0.ddimg.cn/83/24/61887260-1_b_1.jpg'}}})</script>
练习题
如下两种写法的区别是什么?
<div id="myId"></div>
<div :id="myId"></div>
案例:购物车
素材代码
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><style>h4,p {margin: 0;font-weight: normal;}a{text-decoration: none;}body{background-color: #eee;}#app{background-color:#fff;width: 900px;margin: 50px auto;text-align: center;box-shadow: 3px 3px 3px rgba(0 , 0, 0, 0.5);padding:1em 2em;}.list {padding: 1em;width: 100%;box-sizing: border-box;display: flex;flex-wrap:wrap;}.book {position: relative;flex-basis: 22%;margin-right:2%;margin-bottom:1em;text-align: center;background-color: #fff;padding: 1em 0;transition: all .2s linear;}.book:hover {box-shadow: 0 15px 30px rgba(0, 0, 0, .1);transform: translate3d(0, -2px, 0);}.title {line-height: 2em;margin: 0;padding: 0;}.figure img {width: 150px;height: 150px;}.desc {margin: 0;font-size: 16px;}.price {margin: 0;font-size: 14px;}.btn {cursor: pointer;position: absolute;right: 0.8em;top: 0.8em;border: none;color: #ff6700;padding: .5em .5em;font-size: 12px;}.btn:active {border: none;}.btn:hover {background-color: #ff6700;color: #fff}.cart {border: 1px solid #eee;background-color: #fff;text-align: center;position: fixed;padding: 1em;right: 100px;top: 200px;}</style>
</head><body><div id="app"><h3>我的购物车</h3><div class="list"><div class="book" title="当你学会独处"><a href=""><div class="figure"><img src="http://img3m8.ddimg.cn/70/15/28522168-1_l_3.jpg" alt="当你学会独处(学会独处,学会与自己谈话)"></div><h4 class="title" title="当你学会独处">当你学会独处</h4><p class="desc"></p><p class="price"><span class="num">29.9</span></p></a><button class='btn' title="移出购物车">-</button></div><div class="book" title="JavaScript高级程序设计"><a href=""><div class="figure"><img src="http://img3m3.ddimg.cn/2/21/22628333-1_b_2.jpg"alt=" JavaScript高级程序设计"></div><h4 class="title" title="JavaScript高级程序设计">JavaScript高级程序设计</h4><p class="desc"></p><p class="price"><span class="num">78</span></p></a><button class='btn' title="移出购物车">-</button></div><div class="book" title="断舍离"><a href=""><div class="figure"><img alt="断舍离" src="http://img3m3.ddimg.cn/68/20/23271503-1_l_10.jpg"title="断舍离"></div><h4 class="title" title="断舍离">断舍离</h4><p class="desc"></p><p class="price"><span class="num">29.9</span></p></a><button class='btn' title="移出购物车">-</button></div><div class="book" title="王子与贫儿"><a href=""><div class="figure"><img src="http://img3m0.ddimg.cn/67/20/28535530-1_l_3.jpg"alt="王子与贫儿"></div><h4 class="title" title="王子与贫儿">王子与贫儿</h4><p class="desc"></p><p class="price"><span class="num">39.9</span></p></a><button class='btn' title="移出购物车">-</button></div><div class="book" title="高效能人士的七个习惯"><a href=""><div class="figure"><img src="http://img3m2.ddimg.cn/3/4/25253022-1_b_11.jpg"alt="高效能人士的七个习惯"></div><h4 class="title" title="高效能人士的七个习惯">高效能人士的七个习惯</h4><p class="desc"></p><p class="price"><span class="num">59.3</span></p></a><button class='btn' title="移出购物车">-</button></div></div></div><script>var bookList = [{name: '当你学会独处',price: 29.9,picSrc: 'http://img3m8.ddimg.cn/70/15/28522168-1_l_3.jpg'},{name: 'JavaScript高级程序设计',price: 78,picSrc: 'http://img3m3.ddimg.cn/2/21/22628333-1_b_2.jpg'},{name: '断舍离',price: 29.9,picSrc: 'http://img3m3.ddimg.cn/68/20/23271503-1_l_10.jpg'},{name: '王子与贫儿',price: 39.9,picSrc: 'http://img3m0.ddimg.cn/67/20/28535530-1_l_3.jpg'},{name: '高效能人士的七个习惯',price: 59.3,picSrc: 'http://img3m2.ddimg.cn/3/4/25253022-1_b_11.jpg'}]</script>
</body></html>
基本实现
-
v-for循环生成dom结构
-
:src,:title,:alt 绑定属性
-
v-on:click绑定点击