赞
踩
必看
目录
6.(完成) 作业:v-bind和v-for的结合--点击哪项,该项变红色
4.(掌握)计算属性的缓存(计算属性和methods的对比)
2.(理解)三种方案对比(ES5没有闭包-有闭包-ES6的let)
3.(理解)组件的key属性--v-for绑定key和没有绑定key的区别
(具体请查看资料里的xmind文件)
(这个项目的接口需找老师获取)
- 认识Vuejs
- 为什么学习Vuejs
- 简单认识一下Vuejs
- Vuejs安装方式
- CDN引入
- NPM安装管理
- 下载和引入
- Vuejs初体验
- Hello Vuejs
- Vue列表展示
- 案例:计数器
- Vuejs的MVVM
- Vue中的MVVM
(附:Vue官网)
- <!-- 开发环境版本,包含了有帮助的命令行警告 -->
- <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
- <!-- 生产环境版本,优化了尺寸和速度 -->
- <script src="https://cdn.jsdelivr.net/npm/vue"></script>
(开发环境:源码没有经过压缩,可以直接查看源码,学习阶段使用CDN更慢)
代码:
-
- <body>
-
- <div id="app">
- <h2>{{message}}</h2>
- <h1>{{name}}</h1>
- </div>
-
- <div>{{message}}</div>
-
- <script src="../js/vue.js"></script>
- <script>
- // 源码里面有类似于这样的东西 有一个Vue的类 可以往里面传一些参数 Vue的参数是对象类型
- function Vue(){
-
- }
- </script>
- <script>
- // let(变量)/const(常量)
-
- // 编程范式: 声明式编程 实例管理div时,只需声明显示什么东西
- const app = new Vue({
- el: '#app', // 用于挂载要管理的元素
- data: { // 定义数据
- message: '你好啊,李银河!',
- name: 'coderwhy'
- }
- })
-
- // 原始js的做法(编程范式: 命令式编程) 明确告诉一步步该如何做
- // 1.创建div元素,设置id属性
-
- // 2.定义一个变量叫message
-
- // 3.将message变量放在前面的div元素中显示
-
- // 4.修改message的数据: 今天天气不错!
-
- // 5.将修改后的数据再次替换到div元素
-
-
- // Vue的响应式 --> 可以在打印台修改 app.name='yyy'
- </script>
-
- </body>
代码:
-
- <div id="app">
- <ul>
- <li v-for="item in movies">{{item}}</li>
- </ul>
- </div>
-
- <script src="../js/vue.js"></script>
- <script>
- const app = new Vue({
- el: '#app',
- data: {
- message: '你好啊',
- movies: ['星际穿越', '大话西游', '少年派', '盗梦空间']
- }
- })
- </script>
响应式:vue如何监听data的属性变化
模板解析:vue的模板是如何被解析的
渲染:vue模板是如何被渲染成HTML的
代码:
- <!-- Vue中的MVVM -->
-
- <!----1.这是我们的View---->
- <div id="app">
- <h2>当前计数: {{counter}}</h2>
- <!--<button v-on:click="counter++">+</button>-->
- <!--<button v-on:click="counter--;">-</button>-->
- <button v-on:click="add">+</button>
- <button v-on:click="sub">-</button>
- <!--下面是语法糖写法-->
- <!--<button @click="sub">-</button>-->
- </div>
-
- <script src="../js/vue.js"></script>
- <script>
- // 语法糖: 简写
- // proxy
-
- /* ---2.这是我们的Model--- */
- const obj = {
- counter: 0,
- message: 'abc'
- }
-
- new Vue()
-
- /*
- 3.创建一个 Vue 实例或 "ViewModel"
- 它连接 View 与 Model
- ViewModel层的核心是Vue中的双向数据绑定
- */
- const app = new Vue({
- el: '#app',
- data: obj,
- methods: {
- add: function () {
- console.log('add被执行');
- this.counter++
- },
- sub: function () {
- console.log('sub被执行');
- this.counter--
- }
- },
- beforeCreate: function () {
-
- },
- created: function () {
- console.log('created');
- },
- mounted: function () {
- console.log('mounted');
- }
- })
-
- // 1.拿button元素
-
- // 2.添加监听事件
- </script>
生命周期: 事物从诞生到消亡的整个过程
Vue的生命周期图示
- 插值操作
- 绑定属性
- 计算属性
- 事件监听
- 条件判断
- 循环遍历
- 阶段案例
- v-model
创建
使用(回车即可出现定义的template)
代码:
-
- <div id="app">
- <h2>{{message}}</h2>
- <h2>{{message}}, 李银河!</h2>
- <!-- Mustache: 胡子/胡须 -->
- <!--mustache语法中,不仅仅可以直接写变量,也可以写简单的表达式-->
- <h2>{{firstName + lastName}}</h2>
- <h2>{{firstName + ' ' + lastName}}</h2>
- <h2>{{firstName}} {{lastName}}</h2>
- <h2>{{counter * 2}}</h2>
- </div>
-
- <script src="../js/vue.js"></script>
- <script>
- const app = new Vue({
- el: '#app',
- data: {
- message: '你好啊',
- firstName: 'kobe',
- lastName: 'bryant',
- counter: 100
- },
- })
-
- // 模板语法指的就是:写代码时,按照规定好的方式来
-
- <div id="app">
- <h2>{{message}}</h2>
- <h2 v-once>{{message}}</h2>
- </div>
- <!-- v-once:
- 该指令后面不需要跟任何表达式(比如之前的v-for后面是由跟表达式的)
- 该指令表示元素和组件(组件后面才会学习)只渲染一次,不会随着数据的改变而改变 -->
- <script src="../js/vue.js"></script>
- <script>
- const app = new Vue({
- el: '#app',
- data: {
- message: '你好啊'
- }
- })
- // 指令的本质就是自定义属性
- </script>
-
- <div id="app">
- <h2>{{url}}</h2>
- <h2 v-html="url"></h2>
- </div>
- <!-- v-html指令
- 该指令后面往往会跟上一个string类型
- 会将string的html解析出来并且进行渲染 -->
- <script src="../js/vue.js"></script>
- <script>
- const app = new Vue({
- el: '#app',
- data: {
- message: '你好啊',
- url: '<a href="http://www.baidu.com">百度一下</a>'
- }
- })
- </script>
-
- <div id="app">
- <h2>{{message}}, 李银河!</h2>
- <h2 v-text="message">, 李银河!</h2>
- </div>
- <!--
- v-text作用和Mustache比较相似:都是用于将数据显示在界面中
- v-text通常情况下,接受一个string类型
- -->
- <script src="../js/vue.js"></script>
- <script>
- const app = new Vue({
- el: '#app',
- data: {
- message: '你好啊'
- }
- })
- </script>
-
- <div id="app">
- <h2>{{message}}</h2>
- <h2 v-pre>{{message}}</h2>
- </div>
- <!--
- v-pre用于跳过这个元素和它子元素的编译过程,用于显示原本的Mustache语法。
- -->
- <script src="../js/vue.js"></script>
- <script>
- const app = new Vue({
- el: '#app',
- data: {
- message: '你好啊'
- }
- })
- </script>
- <style>
- [v-cloak] {
- display: none;
- }
- </style>
-
- <div id="app" v-cloak>
- <h2>{{message}}</h2>
- </div>
- <!--
- 在某些情况下,我们浏览器可能会直接显然出未编译的Mustache标签。
- cloak: 斗篷
- 需要和css一起搭配使用
- v-cloak 指令用法
- (1)插值表达式存在的问题:“闪动”
- (2)如何解决该问题:使用v-cloak指令
- (3)解决该问题的原理:先隐藏,替换好值之后再显示最终的值
- -->
- <script src="../js/vue.js"></script>
- <script>
- // 在vue解析之前, div中有一个属性v-cloak
- // 在vue解析之后, div中没有一个属性v-cloak
- setTimeout(function () {
- const app = new Vue({
- el: '#app',
- data: {
- message: '你好啊'
- }
- })
- }, 1000)
- </script>
-
- <!--
- v-bind用于绑定一个或多个属性值,或者向另一个组件传递props值
- -->
-
- <div id="app">
- <!-- 错误的做法: 这里不可以使用mustache语法-->
- <!--<img src="{{imgURL}}" alt="">-->
-
- <!-- 正确的做法: 使用v-bind指令 -->
- <img v-bind:src="imgURL" alt="">
- <a v-bind:href="aHref">百度一下</a>
- <!--<h2>{{}}</h2>-->
-
- <!--语法糖的写法-->
- <img :src="imgURL" alt="">
- <a :href="aHref">百度一下</a>
- </div>
-
- <script src="../js/vue.js"></script>
- <script>
- const app = new Vue({
- el: '#app',
- data: {
- message: '你好啊',
- imgURL: 'https://img11.360buyimg.com/mobilecms/s350x250_jfs/t1/20559/1/1424/73138/5c125595E3cbaa3c8/74fc2f84e53a9c23.jpg!q90!cc_350x250.webp',
- aHref: 'http://www.baidu.com'
- }
- })
- </script>
- 用法一:直接通过{}绑定一个类
- <h2 :class="{'active': isActive}">Hello World</h2>
-
- 用法二:也可以通过判断,传入多个值
- <h2 :class="{'active': isActive, 'line': isLine}">Hello World</h2>
-
- 用法三:和普通的类同时存在,并不冲突
- 注:如果isActive和isLine都为true,那么会有title/active/line三个类
- <h2 class="title" :class="{'active': isActive, 'line': isLine}">Hello World</h2>
-
- 用法四:如果过于复杂,可以放在一个methods或者computed中
- 注:classes是一个计算属性
- <h2 class="title" :class="classes">Hello World</h2>
代码:
- <!--
- 绑定class有两种方式:->和普通的类同时存在,并不冲突
- 对象语法
- 数组语法
- 都对象.数组内的属性不用加引号
- -->
-
- <div id="app">
- <!--<h2 class="active">{{message}}</h2>-->
- <!-- 普通用法:这种属于多此一举 -->
- <!--<h2 :class="active">{{message}}</h2>-->
-
- <!-- 对象语法 -->
- <!--<h2 v-bind:class="{key1: value1, key2: value2}">{{message}}</h2>-->
- <!--<h2 v-bind:class="{类名1: true, 类名2: boolean}">{{message}}</h2>-->
- <h2 class="title" v-bind:class="{active: isActive, line: isLine}">{{message}}</h2>
- <h2 class="title" v-bind:class="getClasses()">{{message}}</h2>
- <button v-on:click="btnClick">按钮</button>
- </div>
-
- <script src="../js/vue.js"></script>
- <script>
- const app = new Vue({
- el: '#app',
- data: {
- message: '你好啊',
- isActive: true,
- isLine: true
- },
- methods: {
- btnClick: function () {
- this.isActive = !this.isActive
- },
- getClasses: function () {
- return {
- active: this.isActive,
- line: this.isLine
- }
- }
- }
- })
- </script>
- 用法一:直接通过[]绑定一个类
- <h2 :class="['active']">Hello World</h2>
-
- 用法二:也可以传入多个值
- <h2 :class=“[‘active’, 'line']">Hello World</h2>
-
- 用法三:和普通的类同时存在,并不冲突
- 注:会有title/active/line三个类
- <h2 class="title" :class=“[‘active’, 'line']">Hello World</h2>
-
- 用法四:如果过于复杂,可以放在一个methods或者computed中
- 注:classes是一个计算属性
- <h2 class="title" :class="classes">Hello World</h2>
-
- <head>
- <meta charset="UTF-8">
- <title>Title</title>
- <style>
- .active {
- color: red;
- }
- </style>
- </head>
-
- <body>
-
- <!--作业需求: 点击列表中的哪一项, 那么该项的文字变成红色-->
- <div id="app">
- <ul>
- <li v-for="(m, index) in movies"
- :class="{active:index==currentIndex}"
- @click="itemClick(index)">
- {{index}}-{{m}}
- </li>
- </ul>
- </div>
-
- <script src="../js/vue.js"></script>
- <script>
- const app = new Vue({
- el: '#app',
- data: {
- movies: ['海王', '海尔兄弟', '火影忍者', '进击的巨人'],
- currentIndex: 0
- },
- methods: {
- itemClick(index) {
- this.currentIndex = index;
- }
- }
- })
- </script>
-
- </body>
:style="{color: currentColor, fontSize: fontSize + 'px'}"
-
- <div id="app">
- <!--<h2 :style="{key(属性名): value(属性值)}">{{message}}</h2>-->
-
- <!--'50px'必须加上单引号, 否则是当做一个变量去解析-->
- <h2 :style="{fontSize: '50px'}">{{message}}</h2>
-
- <!--finalSize当成一个变量使用-->
- <!--<h2 :style="{fontSize: finalSize}">{{message}}</h2>-->
- <h2 :style="{fontSize: finalSize + 'px', backgroundColor: finalColor}">{{message}}</h2>
- <h2 :style="getStyles()">{{message}}</h2>
- </div>
-
- <script src="../js/vue.js"></script>
- <script>
- const app = new Vue({
- el: '#app',
- data: {
- message: '你好啊',
- finalSize: 100,
- finalColor: 'red',
- },
- methods: {
- getStyles: function () {
- return {fontSize: this.finalSize + 'px', backgroundColor: this.finalColor}
- }
- }
- })
- </script>
<div v-bind:style="[baseStyles, overridingStyles]"></div>
-
- <div id="app">
- <h2 :style="[baseStyle, baseStyle1]">{{message}}</h2>
- </div>
-
- <script src="../js/vue.js"></script>
- <script>
- const app = new Vue({
- el: '#app',
- data: {
- message: '你好啊',
- baseStyle: {backgroundColor: 'red'},
- baseStyle1: {fontSize: '100px'},
- }
- })
- </script>
代码:
-
- <div id="app">
- <h2>{{firstName + ' ' + lastName}}</h2>
- <h2>{{firstName}} {{lastName}}</h2>
- <!-- {{}} 里面也可以调用方法,需要加() -->
- <h2>{{getFullName()}}</h2>
-
- <!-- {{}} 里面一般用的是变量名,方法有个() 可能有点别扭,这时候就能使用计算属性 -->
- <!-- !!计算属性不用加括号 -->
- <h2>{{fullName}}</h2>
- </div>
-
- <script src="../js/vue.js"></script>
- <script>
- const app = new Vue({
- el: '#app',
- data: {
- firstName: 'Lebron',
- lastName: 'James'
- },
- // computed: 计算属性()
- computed: {
- // computed里面定义的也是函数,但是函数名一般不加类似于get的动词
- // 但是它叫计算属性,所以一般起类似于属性的名字
-
- fullName: function () { // 这样写其实也是一个语法糖 里面有setter和getter 这个是getter
- return this.firstName + ' ' + this.lastName
- }
- },
- methods: {
- getFullName() {
- return this.firstName + ' ' + this.lastName
- }
- }
- })
- </script>
代码:
-
- <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: 105},
- {id: 112, name: '深入理解计算机原理', price: 98},
- {id: 113, name: '现代操作系统', price: 87},
- ]
- },
- computed: {
- totalPrice: function () {
- let result = 0;
- for (let i=0; i < this.books.length; i++) {
- result += this.books[i].price
- }
- return result;
-
- // 1.第一种方式
- /*
- let total = 0
- this.books.forEach(book => {
- total += book.price * book.count
- })
- return total
- */
-
- // 2.第二种方式
- // let total = 0
- // for (let i in this.books) {
- // const book = this.books[i]
- // total += book.price * book.count
- // }
- // return total
-
- // 3.第三种方式
- // 高阶函数 filter/reduce/map
- return this.books.reduce((preValue, book) => {
- return preValue + book.price * book.count
- }, 0)
-
- // reduce的补充
- // https://www.cnblogs.com/amujoe/p/11376940.html
- }
- }
- })
- </script>
用到了set
代码:
-
- <div id="app">
- <h2>{{fullName}}</h2>
- </div>
-
- <script src="../js/vue.js"></script>
- <script>
- const app = new Vue({
- el: '#app',
- data: {
- firstName: 'Kobe',
- lastName: 'Bryant'
- },
- computed: { // computed本质是一个对象 里面可以有属性,里面的属性又是一个对象,里面又可以写方法
- // 简写
- // fullName: function () {
- // return this.firstName + ' ' + this.lastName
- // }
- // name: 'coderwhy'
-
-
- // 完整写法
- // 计算属性一般是没有set方法, 只读属性.
-
- // 计算属性一般实现get方法,没有实现set方法,一般不希望别人给计算属性设置值,一般直接删除set
- // 所以调用计算属性不需要加() 本质是调用属性fullname 里面的get
- fullName: { // 对象
- set: function(newValue) { // 如果想实现set方法,这里是有一个参数的
- // 可以在控制台试试 app.fullName="yang yanyan" 就会调用set
- console.log('-----', newValue);
- const names = newValue.split(' ');
- this.firstName = names[0];// 赋值
- this.lastName = names[1];
- },
- get: function () {
- return this.firstName + ' ' + this.lastName
- }
- },
-
- // fullName: function () { // 这个函数就是get方法
- // return this.firstName + ' ' + this.lastName
- // }
- }
- })
- </script>
在浏览器控制台查看缓存:
(fullName没有变化,就调用了一次)
(fullName有变化,重新调用)
代码:
-
- <div id="app">
- <!--1.直接拼接: 语法过于繁琐-->
- <h2>{{firstName}} {{lastName}}</h2>
-
- <!--2.通过定义methods-->
- <h2>{{getFullName()}}</h2>
- <h2>{{getFullName()}}</h2>
- <h2>{{getFullName()}}</h2>
- <h2>{{getFullName()}}</h2>
-
- <!--3.通过computed-->
- <h2>{{fullName}}</h2>
- <h2>{{fullName}}</h2>
- <h2>{{fullName}}</h2>
- <h2>{{fullName}}</h2>
- </div>
-
- <script src="../js/vue.js"></script>
- <script>
- // angular -> google
- // TypeScript(microsoft) -> ts(类型检测)
- // flow(facebook) ->
- const app = new Vue({
- el: '#app',
- data: {
- firstName: 'Kobe',
- lastName: 'Bryant'
- },
- methods: {
- getFullName: function () {
- console.log('getFullName');
- return this.firstName + ' ' + this.lastName
- }
- },
- computed: {
- fullName: function () {
- console.log('fullName');
- // 会观察有没有变化 没有变化就直接返回原来结果 而不是重新计算 有变化就重新调用一次
- // 浏览器控制台 app.fullName='why' 会再调用一次
- return this.firstName + ' ' + this.lastName
- }
- }
- })
-
- </script>
1.变量作用域: 变量在什么范围内是可用
- // 下面是一个代码块。{} 就是一个代码块,有没有{}对于定义变量来说没任何意义 内外都可以使用name
- {
- var name = 'why';
- console.log(name);
- }
- console.log(name); // 可以使用name
2.没有块级作用域引起的问题: if的块级
- if (true) {
- var name = 'why';
- }
- console.log(name);// 可以打印
- if (true) {
- var name = 'why';
- }
- console.log(name);// 可以打印
-
- var func;
- if (true) {
- var name = 'why';
- func = function () { // 这个变量是为了打印这里的name
- console.log(name);
- }
- // func();// 可以打印
- }
- name = 'kobe'; // 这里把变量改掉了,不应该能改
-
- func(); // 依然可以打印
- // console.log(name);
3.没有块级作用域引起的问题: for的块级
监听按钮的点击
-
- <button>按钮1</button>
- <button>按钮2</button>
- <button>按钮3</button>
- <button>按钮4</button>
- <button>按钮5</button>
-
- <script>
- var btns = document.getElementsByTagName('button');
- for (var i = 0; i < btns.length; i++) {
- btns[i].addEventListener('click', function () {
- console.log('第' + i + '个按钮被点击');
- // 点击了第1个,打印却是第5个,点击其他按钮也是打印第5个
- // 与上面的那个有点像,打印的i是在一个函数里面,在点击之前,这个i已经被改掉了,进行了5次循环
- })
- }
- </script>
综上,if和for里面没有块级
闭包:内部函数总是可以访问其所在的外部函数中声明的参数和变量,即使在其外部函数被返回(寿命终结)了之后。
- var btns = document.getElementsByTagName('button');
- for (var i = 0; i < btns.length; i++) {
- (function (num) { // 0
- btns[i].addEventListener('click', function () {
- console.log('第' + num + '个按钮被点击');
- })
- })(i)
- }
补充:立即执行函数
- // 立即执行函数
- (function () {
-
- }())
- (function () {
-
- })()
-
- var name = "yyyy";
-
- function abc(name) {
- console.log(name);
- }
- name="why";
- abc('aaaaaa');// 无论外部怎么改变name,打印的还是aaaa
- var name = 'why'
-
- function abc(bbb) { // bbb = 'why'
- console.log(bbb);
- }
- abc(name);// 也不会有任何冲突 name还是why
- name = 'kobe'
补充:关于一些闭包的文章
总之,记住
ES5中的var是没有块级作用域的(if/for)
ES6中的let是由块级作用的(if/for)
- // es6写法
- const btns = document.getElementsByTagName('button')
- for (let i = 0; i < btns.length; i++) {
- btns[i].addEventListener('click', function () {
- console.log('第' + i + '个按钮被点击');
- })
- }
- { i = 0
- btns[i].addEventListener('click', function () {
- console.log('第' + i + '个按钮被点击');
- })
- }
-
- { i = 1
- btns[i].addEventListener('click', function () {
- console.log('第' + i + '个按钮被点击');
- })
- }
- { i = 2
- btns[i].addEventListener('click', function () {
- console.log('第' + i + '个按钮被点击');
- })
- }
- { i = 3
- btns[i].addEventListener('click', function () {
- console.log('第' + i + '个按钮被点击');
- })
- }
- { i = 4
- btns[i].addEventListener('click', function () {
- console.log('第' + i + '个按钮被点击');
- })
- }
- // ES5
- var i = 5
- {
- btns[i].addEventListener('click', function () {
- console.log('第' + i + '个按钮被点击');
- })
- }
-
- {
- btns[i].addEventListener('click', function () {
- console.log('第' + i + '个按钮被点击');
- })
- }
-
-
- {
- btns[i].addEventListener('click', function () {
- console.log('第' + i + '个按钮被点击');
- })
- }
-
-
- {
- btns[i].addEventListener('click', function () {
- console.log('第' + i + '个按钮被点击');
- })
- }
-
- {
- btns[i].addEventListener('click', function () {
- console.log('第' + i + '个按钮被点击');
- })
- }
-
-
- <button>按钮1</button>
- <button>按钮2</button>
- <button>按钮3</button>
-
- <script>
- // 1.没有块级作用域引起的问题: for的块级
- // 为什么闭包可以解决问题: 函数是一个作用域.
- var btns = document.getElementsByTagName('button');
- for (var i = 0; i < btns.length; i++) {
- btns[i].addEventListener('click', function () {
- console.log('第' + i + '个按钮被点击');
- })
- }
-
- // 伪代码:
- // 1.情况一: ES5中没有使用闭包(错误的方式)
- i = 2
- { // 在里面定义在外面定义都是一样的
- // i = 0
- btns[i].addEventListener('click', function () {
- console.log('第' + i + '个按钮被点击');
- })
- }
-
- {
- i = 1
- btns[i].addEventListener('click', function () {
- console.log('第' + i + '个按钮被点击');
- })
- }
-
- {
- // i = 2
- btns[i].addEventListener('click', function () {
- console.log('第' + i + '个按钮被点击');
- })
- }
-
- // 2.情况二: ES5中使用闭包
- var btns = document.getElementsByTagName('button');
- for (var i = 0; i < btns.length; i++) {
- (function (i) { // 0
- btns[i].addEventListener('click', function () {
- console.log('第' + i + '个按钮被点击');
- })
- })(i)
- }
-
- i = 100000000
-
- function (i) { // i = 0
- btns[i].addEventListener('click', function () {
- console.log('第' + i + '个按钮被点击');
- })
- }(0)
-
- function (i) { // i = 1
- btns[i].addEventListener('click', function () {
- console.log('第' + i + '个按钮被点击');
- })
- }(1)
-
- function (i) { // i = 2
- btns[i].addEventListener('click', function () {
- console.log('第' + i + '个按钮被点击');
- })
- }(2)
-
- // ES6中的let
- const btns = document.getElementsByTagName('button')
- for (let i = 0; i < btns.length; i++) {
- btns[i].addEventListener('click', function () {
- console.log('第' + i + '个按钮被点击');
- })
- }
- i = 10000000 {
- i = 0
- btns[i].addEventListener('click', function () {
- console.log('第' + i + '个按钮被点击');
- })
- }
-
- {
- i = 1
- btns[i].addEventListener('click', function () {
- console.log('第' + i + '个按钮被点击');
- })
- }
-
- {
- i = 2
- btns[i].addEventListener('click', function () {
- console.log('第' + i + '个按钮被点击');
- })
- }
- </script>
- const a=20;
- a=30;// 错误:不可以修改
const name; // 错误:const修饰的标识符必须赋值
-
- // 1.注意一: 一旦给const修饰的标识符被赋值之后, 不能修改
- // const name = 'why';
- // name = 'abc';
-
- // 2.注意二: 在使用const定义标识符,必须进行赋值
- // const name;
-
- // 3.注意三: 常量的含义是指向的对象不能修改, 但是可以改变对象内部的属性.
- const obj = {
- name: 'why',
- age: 18,
- height: 1.88
- }
- // obj = {}
- console.log(obj);
-
- obj.name = 'kobe';
- obj.age = 40;
- obj.height = 1.87;
-
- console.log(obj);
- const obj = new Object()
-
- const obj = { // 这个{} 就是对象的字面量
- name: 'why',
- age: 18,
- run: function () {
- console.log('在奔跑');
- },
- eat: function () {
- console.log('在次东西');
- }
- }
1.属性的增强写法
- const name = 'why';
- const age = 18;
- const height = 1.88
ES5的写法:
- // ES5的写法
- const obj = {
- name: name,
- age: age,
- height: height
- }
- console.log(obj);
ES6的写法:
- // ES6的写法
- const obj = {
- name,
- age,
- height,
- }
-
- console.log(obj);
ES5的写法
- // ES5的写法
- const obj = {
- run: function () {
-
- },
- eat: function () {
-
- }
- }
ES6的写法
- // ES6
- const obj = {
- run() {
-
- },
- eat() {
-
- }
- }
代码:
-
- <!--
- v-on介绍
- 作用:绑定事件监听器
- 缩写:@
- -->
- <div id="app">
- <h2>{{counter}}</h2>
- <!--<h2 v-bind:title></h2>-->
- <!--<h2 :title></h2>-->
-
- <!--<button v-on:click="counter++">+</button>-->
- <!--<button v-on:click="counter--">-</button>-->
-
- <!--<button v-on:click="increment">+</button>-->
- <!--<button v-on:click="decrement">-</button>-->
- <button @click="increment">+</button>
- <button @click="decrement">-</button>
- </div>
-
- <script src="../js/vue.js"></script>
- <script>
- const app = new Vue({
- el: '#app',
- data: {
- counter: 0
- },
- methods: {
- increment() {
- this.counter++
- },
- decrement() {
- this.counter--
- }
- }
- })
- </script>
代码:
-
- <div id="app">
- <!--1.事件调用的方法没有参数 ()可以不添加-->
- <button @click="btn1Click()">按钮1</button>
-
- <button @click="btn1Click">按钮1</button>
-
- <!--2.在事件定义时, 写方法时省略了小括号,
- 但是方法本身是需要一个参数的, 这个时候, Vue会默认将浏览器生产的event事件对象作为参数传入到方法-->
- <!--<button @click="btn2Click(123)">按钮2</button>-->
-
- <!--调用时不传入参数,那么参数为undefined-->
- <!--<button @click="btn2Click()">按钮2</button>-->
- <button @click="btn2Click">按钮2</button>
-
- <!--3.方法定义时, 我们需要event对象, 同时又需要其他参数-->
- <!-- 在调用方式, 如何手动的获取到浏览器参数的event对象: $event-->
- <button @click="btn3Click(abc, $event)">按钮3</button>
- </div>
-
- <script src="../js/vue.js"></script>
- <script>
- const app = new Vue({
- el: '#app',
- data: {
- message: '你好啊',
- abc: 123
- },
- methods: {
- btn1Click() {
- console.log("btn1Click");
- },
- btn2Click(event) {
- console.log('--------', event);
- },
- btn3Click(abc, event) {
- console.log('++++++++', abc, event);
- }
- }
- })
-
- // 如果函数需要参数,但是没有传入, 那么函数的形参为undefined
- // function abc(name) {
- // console.log(name);
- // }
- //
- // abc()
-
- <div id="app">
- <!--1. .stop修饰符的使用 停止冒泡-->
- <div @click="divClick">
- aaaaaaa
- <button @click.stop="btnClick">按钮</button>
- </div>
-
- <!--2. .prevent修饰符的使用 阻止默认行为-->
- <br>
- <form action="baidu">
- <input type="submit" value="提交" @click.prevent="submitClick">
- </form>
-
- <!--3. .监听某个键盘的键帽-->
- <input type="text" @keyup.enter="keyUp">
-
- <!--4. .once修饰符的使用 点击回调只会触发一次-->
- <button @click.once="btn2Click">按钮2</button>
- </div>
-
- <script src="../js/vue.js"></script>
- <script>
- const app = new Vue({
- el: '#app',
- data: {
- message: '你好啊'
- },
- methods: {
- btnClick() {
- console.log("btnClick");
- },
- divClick() {
- console.log("divClick");
- },
- submitClick() {
- console.log('submitClick');
- },
- keyUp() {
- console.log('keyUp');
- },
- btn2Click() {
- console.log('btn2Click');
- }
- }
- })
- </script>
代码:
○ v-if的使用
-
- <div id="app">
- <h2 v-if="isShow">
- <div>abc</div>
- <div>abc</div>
- <div>abc</div>
- <div>abc</div>
- <div>abc</div>
- {{message}}
- </h2>
- </div>
-
- <script src="../js/vue.js"></script>
- <script>
- const app = new Vue({
- el: '#app',
- data: {
- message: '你好啊',
- isShow: true
- }
- })
- </script>
○ v-if 和v-else 的使用
-
-
- <div id="app">
- <h2 v-if="isShow">
- <div>abc</div>
- <div>abc</div>
- <div>abc</div>
- <div>abc</div>
- <div>abc</div>
- {{message}}
- </h2>
- <h1 v-else>isShow为false时, 显示我</h1>
- </div>
-
- <script src="../js/vue.js"></script>
- <script>
- const app = new Vue({
- el: '#app',
- data: {
- message: '你好啊',
- isShow: true
- }
- })
- </script>
○ v-if 、v-else-if和v-else 的使用
-
-
- <div id="app">
- <h2 v-if="score>=90">优秀</h2>
- <h2 v-else-if="score>=80">良好</h2>
- <h2 v-else-if="score>=60">及格</h2>
- <h2 v-else>不及格</h2>
-
- <h1>{{result}}</h1>
- </div>
-
- <script src="../js/vue.js"></script>
- <script>
- const app = new Vue({
- el: '#app',
- data: {
- score: 99
- },
- computed: {
- result() {
- let showMessage = '';
- if (this.score >= 90) {
- showMessage = '优秀'
- } else if (this.score >= 80) {
- showMessage = '良好'
- }
- // ...
- return showMessage
- }
- }
- })
- </script>
代码:
-
- <div id="app">
- <span v-if="isUser">
- <label for="username">用户账号</label>
- <input type="text" id="username" placeholder="用户账号">
- </span>
-
- <span v-else>
- <label for="email">用户邮箱</label>
- <input type="text" id="email" placeholder="用户邮箱">
- </span>
- <button @click="isUser = !isUser">切换类型</button>
- </div>
-
- <script src="../js/vue.js"></script>
- <script>
- const app = new Vue({
- el: '#app',
- data: {
- isUser: true
- }
- })
- </script>
这是因为Vue在进行DOM渲染时,出于性能考虑,会尽可能的复用已经存在的元素,而不是重新创建新的元素。
在上面的案例中,Vue内部会发现原来的input元素不再使用,直接作为else中的input来使用了
解决方案
如果我们不希望Vue出现类似重复利用的问题,可以给对应的input添加key
并且我们需要保证key的不同
代码:
-
- <div id="app">
- <span v-if="isUser">
- <label for="username">用户账号</label>
- <input type="text" id="username" placeholder="用户账号" key="username">
- </span>
- <span v-else>
- <label for="email">用户邮箱</label>
- <input type="text" id="email" placeholder="用户邮箱" key="email">
- </span>
- <button @click="isUser = !isUser">切换类型</button>
- </div>
-
- <script src="../js/vue.js"></script>
- <script>
- const app = new Vue({
- el: '#app',
- data: {
- isUser: true
- }
- })
- </script>
代码:
-
- <div id="app">
- <!--v-if: 当条件为false时, 包含v-if指令的元素, 根本就不会存在dom中-->
- <h2 v-if="isShow" id="aaa">{{message}}</h2>
-
- <!--v-show: 当条件为false时, v-show只是给我们的元素添加一个行内样式: display: none-->
- <h2 v-show="isShow" id="bbb">{{message}}</h2>
- </div>
- <!--
- 当需要在显示与隐藏之间切片很频繁时,使用v-show
- 当只有一次切换时,通过使用v-if
- -->
-
- <script src="../js/vue.js"></script>
- <script>
- const app = new Vue({
- el: '#app',
- data: {
- message: '你好啊',
- isShow: true
- }
- })
- </script>
代码:
-
- <div id="app">
- <!--1.在遍历的过程中,没有使用索引值(下标值)-->
- <ul>
- <li v-for="item in names">{{item}}</li>
- </ul>
-
- <!--2.在遍历的过程中, 获取索引值-->
- <ul>
- <li v-for="(item, index) in names">
- {{index+1}}.{{item}}
- </li>
- </ul>
- </div>
-
- <script src="../js/vue.js"></script>
- <script>
- const app = new Vue({
- el: '#app',
- data: {
- names: ['why', 'kobe', 'james', 'curry']
- }
- })
- </script>
代码:
-
- <div id="app">
- <!--1.在遍历对象的过程中, 如果只是获取一个值, 那么获取到的是value-->
- <ul>
- <li v-for="item in info">{{item}}</li>
- </ul>
-
-
- <!--2.获取key和value 格式: (value, key) -->
- <ul>
- <li v-for="(value, key) in info">{{value}}-{{key}}</li>
- </ul>
-
-
- <!--3.获取key和value和index 格式: (value, key, index) -->
- <ul>
- <li v-for="(value, key, index) in info">{{value}}-{{key}}-{{index}}</li>
- </ul>
- </div>
-
- <script src="../js/vue.js"></script>
- <script>
- const app = new Vue({
- el: '#app',
- data: {
- info: {
- name: 'why',
- age: 18,
- height: 1.88
- }
- }
- })
- </script>
代码:
-
-
- <div id="app">
- <ul>
- <li v-for="item in letters">{{item}}</li>
- </ul>
- <button @click="btnClick">按钮</button>
- </div>
-
- <script src="../js/vue.js"></script>
- <script>
- const app = new Vue({
- el: '#app',
- data: {
- letters: ['a', 'b', 'c', 'd']
- },
- methods: {
- btnClick() {
- // 1.push方法
- // this.letters.push('aaa')
- // this.letters.push('aaaa', 'bbbb', 'cccc')
-
- // 2.pop(): 删除数组中的最后一个元素
- // this.letters.pop();
-
- // 3.shift(): 删除数组中的第一个元素
- // this.letters.shift();
-
- // 4.unshift(): 在数组最前面添加元素
- // this.letters.unshift()
- // this.letters.unshift('aaa', 'bbb', 'ccc')
-
- // 5.splice作用: 删除元素/插入元素/替换元素
- // 删除元素: 第二个参数传入你要删除几个元素(如果没有传,就删除后面所有的元素)
- // 替换元素: 第二个参数, 表示我们要替换几个元素, 后面是用于替换前面的元素
- // 插入元素: 第二个参数, 传入0, 并且后面跟上要插入的元素
- // splice(start)
- // splice(start):
- this.letters.splice(1, 3, 'm', 'n', 'l', 'x')
- // this.letters.splice(1, 0, 'x', 'y', 'z')
-
- // 5.sort() 排序
- // this.letters.sort()
-
- // 6.reverse() 反转
- // this.letters.reverse()
-
- // **注意: 通过索引值修改数组中的元素
- // Vue内部没有监听这种方式 不是响应式 数组有变化,界面无更新
- // this.letters[0] = 'bbbbbb';
-
- // 用其他方法
- // 法1
- // this.letters.splice(0, 1, 'bbbbbb')
-
- // 法2
- // set(要修改的对象, 索引值, 修改后的值)
- // Vue.set(this.letters, 0, 'bbbbbb')
- }
- }
- })
-
-
- // function sum(num1, num2) {
- // return num1 + num2
- // }
- //
-
- // function sum(num1, num2, num3) {
- // return num1 + num2 + num3
- // }
-
- // function sum(...num) { // 可变参数
- // console.log(num);
- // }
- //
- // sum(20, 30, 40, 50, 601, 111, 122, 33)
- </script>
补充:
HTML代码:
-
- <div id="app">
- <div v-if="books.length">
- <table>
- <thead>
- <tr>
- <th></th>
- <th>书籍名称</th>
- <th>出版日期</th>
- <th>价格</th>
- <th>购买数量</th>
- <th>操作</th>
- </tr>
- </thead>
- <tbody>
- <tr v-for="(item, index) in books">
- <td>{{item.id}}</td>
- <td>{{item.name}}</td>
- <td>{{item.date}}</td>
-
- <td>
- <!-- 价格 保留两位小数 拼接 ¥ -->
- <!-- 法1 总价格那里也需要这个 所以这样写不太好 -->
- <!-- {{item.price.toFixed(2)}} -->
-
- <!-- 法2 调用方法 -->
- <!-- {{getFinalPrice(item.price)}} -->
-
- <!-- 法3 过滤器 -->
- {{item.price | showPrice}}
-
- </td>
- <td>
- <!-- v-bind动态绑定属性如果为true就表示有这个属性 v-bind:disabled="true" 渲染出来就是disabled 所以这里只需要一个布尔值就行 -->
- <button @click="decrement(index)" v-bind:disabled="item.count <= 1">-</button>
- {{item.count}}
- <button @click="increment(index)">+</button>
- </td>
- <td><button @click="removeHandle(index)">移除</button></td>
- </tr>
- </tbody>
- </table>
- <h2>总价格: {{totalPrice | showPrice}}</h2>
- </div>
- <h2 v-else>购物车为空</h2>
-
- </div>
-
- <script src="../js/vue.js"></script>
- <script src="main.js"></script>
CSS代码:
- table {
- border: 1px solid #e9e9e9;
- border-collapse: collapse;
- border-spacing: 0;
- }
-
- th, td {
- padding: 8px 16px;
- border: 1px solid #e9e9e9;
- text-align: left;
- }
-
- th {
- background-color: #f7f7f7;
- color: #5c6b77;
- font-weight: 600;
- }
JS代码:
- const app = new Vue({
- el: '#app',
- data: {
- books: [
- {
- id: 1,
- name: '《算法导论》',
- date: '2006-9',
- price: 85.00,
- count: 1
- },
- {
- id: 2,
- name: '《UNIX编程艺术》',
- date: '2006-2',
- price: 59.00,
- count: 1
- },
- {
- id: 3,
- name: '《编程珠玑》',
- date: '2008-10',
- price: 39.00,
- count: 1
- },
- {
- id: 4,
- name: '《代码大全》',
- date: '2006-3',
- price: 128.00,
- count: 1
- },
- ]
- },
- methods: {
- // getFinalPrice(price) {
- // return '¥' + price.toFixed(2)
- // }
-
- increment(index) {
- this.books[index].count++
- },
- decrement(index) {
- this.books[index].count--
- },
- removeHandle(index) {
- this.books.splice(index, 1)
- }
- },
- computed: {
- totalPrice() {
- let totalPrice = 0
- for (let i = 0; i < this.books.length; i++) {
- totalPrice += this.books[i].price * this.books[i].count
- }
- return totalPrice
-
- // 其他计算总价格方法
- // for (let i in/of this.books)
- // reduce
- }
- },
- filters: { // 过滤器
- showPrice(price) { // 参数是你要过滤的东西
- // toFixed 保留两位小数
- return '¥' + price.toFixed(2)
- }
- }
- })
计算总价格其他方法 :
-
- computed: {
- totalPrice() {
- // 1.普通的for循环
- // let totalPrice = 0
- // 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)
- // let totalPrice = 0
- // for (let i in this.books) {
- // const book = this.books[i]
- // totalPrice += book.price * book.count
- // }
- //
- // return totalPrice
-
- // 3.for (let i of this.books)
- // let totalPrice = 0
- // 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)
- }
- },
也可以使用高阶函数reduce,下面介绍高阶函数
- // 编程范式: 命令式编程/声明式编程
- // 编程范式: 面向对象编程(第一公民:对象)/函数式编程(第一公民:函数)
-
- // filter/map/reduce
-
- // filter中的回调函数有一个要求: 必须返回一个boolean值
- // true: 当返回true时, 函数内部会自动将这次回调的n加入到新的数组中
- // false: 当返回false时, 函数内部会过滤掉这次的n
- const nums = [10, 20, 111, 222, 444, 40, 50]
-
- // 高阶函数 本身参数也是一个函数
- // let total = nums.filter(n => n < 100).map(n => n * 2).reduce((pre, n) => pre + n);
- // console.log(total);
-
- let total = nums.filter(function (n) {
- return n < 100
- }).map(function (n) {
- return n * 2
- }).reduce(function (prevValue, n) {
- return prevValue + n
- }, 0)
- console.log(total);
-
- // 1.filter函数的使用
- // 10, 20, 40, 50
- let newNums = nums.filter(function (n) {
- return n < 100
- })
- // console.log(newNums);
-
- // 2.map函数的使用
- // 20, 40, 80, 100
- let new2Nums = newNums.map(function (n) { // 20
- return n * 2
- })
- console.log(new2Nums);
-
- // 3.reduce函数的使用
- // reduce 作用对数组中所有的内容进行汇总
- let total = new2Nums.reduce(function (preValue, n) {
- return preValue + n
- }, 0)
- console.log(total);
-
- // 第一次: preValue 0 n 20
- // 第二次: preValue 20 n 40
- // 第二次: preValue 60 n 80
- // 第二次: preValue 140 n 100
- // 240
-
-
- // 普通写法
- // 1.需求: 取出所有小于100的数字
- let newNums = []
- for (let n of nums) {
- if (n < 100) {
- newNums.push(n)
- }
- }
-
- // 2.需求:将所有小于100的数字进行转化: 全部*2
- let new2Nums = []
- for (let n of newNums) {
- new2Nums.push(n * 2)
- }
-
- console.log(new2Nums);
-
-
- // 3.需求:将所有new2Nums数字相加,得到最终的记过
- let total = 0
- for (let n of new2Nums) {
- total += n
- }
-
- console.log(total);
-
- <div id="app">
- <input type="text" v-model="message">
- {{message}}
- </div>
-
- <script src="../js/vue.js"></script>
- <script>
- const app = new Vue({
- el: '#app',
- data: {
- message: '你好啊'
- }
- })
- </script>
<input type="text" v-model="message">
<input type="text" v-bind:value="message" v-on:input="message = $event.target.value">
-
- <div id="app">
- <!--<input type="text" v-model="message">-->
-
- <!-- 上面等同于 -->
- <!--<input type="text" :value="message" @input="valueChange">-->
-
- <!-- 也就是 -->
- <input type="text" :value="message" @input="message = $event.target.value">
- <h2>{{message}}</h2>
- </div>
-
- <script src="../js/vue.js"></script>
- <script>
- const app = new Vue({
- el: '#app',
- data: {
- message: '你好啊'
- },
- methods: {
- valueChange(event) {
- this.message = event.target.value;
- }
- }
- })
- </script>
单选按钮radio的value会影响v-model的值(input得有value属性,value是什么获取到的就是什么)
-
- <div id="app">
- <label for="male">
- <!-- 需要加相同的name 否则可以多选 -->
- <!-- <input type="radio" id="male" value="男" name="sex">男 -->
- <!-- 一旦v-moddel绑定的是同一个变量,name可以不用写 -->
- <input type="radio" id="male" value="男" v-model="sex">男
- </label>
- <label for="female">
- <input type="radio" id="female" value="女" v-model="sex">女
- </label>
- <label for="other">
- <input type="radio" id="other" value="其他" v-model="sex">其他
- </label>
- <h2>您选择的性别是: {{sex}}</h2>
- </div>
-
- <script src="../js/vue.js"></script>
- <script>
- const app = new Vue({
- el: '#app',
- data: {
- message: '你好啊',
- sex: '女' // 可以给radio默认值
- }
- })
- </script>
代码:
-
- <div id="app">
- <!--1.checkbox单选框 -->
- <!--
- v-model即为布尔值true/false。
- 此时input的value并不影响v-model的值
- -->
- <label for="agree">
- <input type="checkbox" id="agree" v-model="isAgree">同意协议
- </label>
- <h2>您选择的是: {{isAgree}}</h2>
- <button :disabled="!isAgree">下一步</button>
-
- <!--2.checkbox多选框-->
- <!--
- 当是多个复选框时,因为可以选中多个,所以对应的data中属性是一个数组。
- 当选中某一个时,就会将input的value添加到数组中。
- -->
- <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">羽毛球
- <h2>您的爱好是: {{hobbies}}</h2>
-
- <!-- 值绑定 动态的给value赋值 -->
- <label v-for="item in originHobbies" :for="item">
- <input type="checkbox" :value="item" :id="item" v-model="hobbies">{{item}}
- </label>
- </div>
-
- <script src="../js/vue.js"></script>
- <script>
- const app = new Vue({
- el: '#app',
- data: {
- message: '你好啊',
- isAgree: false, // 单选框
-
- hobbies: [], // 多选框,
- originHobbies: ['篮球', '足球', '乒乓球', '羽毛球', '台球', '高尔夫球']
- }
- })
- </script>
代码:
-
- <div id="app">
- <!--1.选择一个-->
- <!--
- 单选:只能选中一个值。
- v-model绑定的是一个值。
- 当我们选中option中的一个时,会将它对应的value赋值到mySelect中
- -->
- <!-- v-model绑定在select标签 -->
- <select name="abc" v-model="fruit">
- <option value="苹果">苹果</option>
- <option value="香蕉">香蕉</option>
- <option value="榴莲">榴莲</option>
- <option value="葡萄">葡萄</option>
- </select>
- <h2>您选择的水果是: {{fruit}}</h2>
-
- <!--2.选择多个-->
- <!--
- v-model绑定的是一个数组。
- 当选中多个值时,就会将选中的option对应的value添加到数组mySelects中
- -->
- <!-- 加上multiple属性就可以多选 要按ctrl才能多选 -->
- <select name="abc" v-model="fruits" multiple>
- <option value="苹果">苹果</option>
- <option value="香蕉">香蕉</option>
- <option value="榴莲">榴莲</option>
- <option value="葡萄">葡萄</option>
- </select>
- <h2>您选择的水果是: {{fruits}}</h2>
- </div>
-
- <script src="../js/vue.js"></script>
- <script>
- const app = new Vue({
- el: '#app',
- data: {
- message: '你好啊',
- fruit: '香蕉',
- fruits: []
- }
- })
- </script>
代码:
-
- <div id="app">
- <!--1.修饰符: lazy 让数据在失去焦点或者回车时才会更新-->
- <input type="text" v-model.lazy="message">
- <h2>{{message}}</h2>
-
-
- <!--2.修饰符: number 让在输入框中输入的内容自动转成数字类型-->
- <input type="number" v-model.number="age">
- <h2>{{age}}-{{typeof age}}</h2>
-
- <!--3.修饰符: trim 过滤内容左右两边的空格-->
- <input type="text" v-model.trim="name">
- <h2>您输入的名字:{{name}}</h2>
- </div>
-
- <script src="../js/vue.js"></script>
- <script>
- const app = new Vue({
- el: '#app',
- data: {
- message: '你好啊',
- age: 0,
- name: ''
- }
- })
-
- var age = 0
- age = '1111'
- age = '222'
- </script>
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。