深圳营销型网站策划,当前网站开发用什么软件,o2o的代表平台有哪些,开发小程序商城的费用文章目录 前言一、Vue框架#xff08;简化DOM操作的一个前端框架#xff09;#xff1a;基础入门1 Vue基本概念2 快速入门#xff1a;创建Vue实例#xff0c;初始化渲染#xff08;1#xff09;创建一个入门Vue实例#xff08;2#xff09;插值表达式#xff1a;{{表… 文章目录 前言一、Vue框架简化DOM操作的一个前端框架基础入门1 Vue基本概念2 快速入门创建Vue实例初始化渲染1创建一个入门Vue实例2插值表达式{{表达式}}3Vue实例中的传入的对象中键的解释重要---- 数据模型data---- 定义方法methods---- mounted()钩子方法 挂载完成 4Vue响应式特性 二、Vue常用指令1 v-html指令设置元素的innerHTML2 v-on指令为html标签绑定事件1v-on:事件名内联语句2v-on:事件名 methods中的函数名---- 不传参---- 传参 3 v-model指令在表单元素上创建双向数据绑定1v-model 应用于输入框 input:text2v-model 应用于其他各种表单组件 4 条件指令v-if , v-else-if, v-else根据if条件渲染某元素标签判定为true展示标签否则不展示5 v-show指令和v-if效果完全一样根据条件渲染某元素标签判定为true展示标签否则不展示6 v-for指令: 基于数据循环多次渲染整个元素1基本用法2扩展v-for 遍历渲染列表中 key属性的使用 7 v-bind指令动态的设置html的标签属性→ src url title...如设置 hrefcss样式等超级灵活这个指令1基本使用动态的设置html的标签属性→ src url title...2进阶用法v-bind 对于样式控制的增强---- v-bind 对于样式控制的增强-操作class---- v-bind 对于样式控制的增强-操作style 9 指令修饰符简化代码1按键修饰符用于v-on键盘事件2鼠标修饰符用于v-on鼠标事件3表单修饰符用于 v-model4事件修饰符用于 v-on---- 事件名.stop阻止冒泡---- 事件名.prevent阻止默认行为 8 案例练习1案例1图片切换波仔的学习之旅2案例2图书管理案例小黑的书架3案例3综合案例小黑记事本---- step1: 使用AI生成ui布局---- step2: 在ai生成的ui的html架构上面进一步开发 4案例4通过Vue完成表格数据的渲染展示 三、计算属性和监视器1 计算属性1基本概念2使用计算属性和methods的区别---- 使用 计算属性 computed---- 使用methods3计算属性的完整写法了解即可 2 watch 侦听器(监视器)监视数据模型中数据的变化待定下面的案例建议先将ajox技术学好再回来重新学习1watch 侦听器(监视器)简写语法2watch 侦听器(监视器)完整语法进阶 3 案例综合案例1成绩表格 三 Vue生命周期和Vue中发送请求的位置1Vue对象的生命周期2mounted阶段发送请求的时刻 四、Ajax技术从服务端获取数据发送各种请求0 接口文档管理使用apipost等接口测试软件创建接口便于前端后端分离测试1 基本概念2 原生Ajax几年前的早期用法3 Axios(对原生的Ajax进行了封装)4 案例练习AxiosVue,基于Vue及Axios完成数据的动态加载展示重要 前言 一、Vue框架简化DOM操作的一个前端框架基础入门
Vue的使用在前端想学习深入还是有很多要学习的但我们重点不在前端。我们快速入门一下能够简单使用就可以了如果想深入了解这个十分重要的前端框架就需要专门去找Vue这门课好好学习一下了。
1 Vue基本概念 Vue 是一套前端框架免除原生JavaScript中的DOM操作简化书写。 前面学DOM操作会发现相当繁琐方法属性一大堆不方便。因此就衍生出了Vue这么一个框架可以帮助我们简化DOM操作的书写。 优点:大大提升开发效率(70%个)缺点︰需要理解记忆规则→官网 使用框架就要遵守框架中的一些人为规定的规则 基于MVVM(Model-View-ViewModel)思想实现数据的双向绑定将编程的关注点放在数据上 Vue的学习其实关注一点 数据模型 前端界面展示 这二者是相互影响的 1数据模型里面对应的数据值发生了变化前端展示中所有应用这个数据值都会同时发生变化 2前端展示的所有数据值只要有一个地方修改了这个值就会导致数据模型中对应的值发生变化进而导致前端其他引用这个数据值的地方也发生变化 官网: https://v2.cn.vuejs.org/ 框架:是一个半成品软件是一套可重用的、通用的、软件基础代码模型。基于框架进行开发更加快捷、更加高效。
问题来了数据模型是什么下面通过一个Vue的快速入门来了解上述这些概念。
2 快速入门创建Vue实例初始化渲染
1创建一个入门Vue实例
参考视频
Vue的基本使用只有三步 1新建HTML页面引入Vue.js文件引包 官网: https://v2.cn.vuejs.org/提供了两种模式的Vue.js文件 开发版本包含完整的警告和调试模式更加适合我们开发者。如果产品上线了换成生产环境版本对用户更加友好出现报错屏蔽了报错信息。 !-- 开发环境版本包含了有帮助的命令行警告 -- script src“https://cdn.jsdelivr.net/npm/vue2/dist/vue.js”/script!-- 生产环境版本优化了尺寸和速度 -- script src“https://cdn.jsdelivr.net/npm/vue2”/script 2在JS代码区域创建Vue核心对象定义数据模型 知识点JS中的自定义类自定义对象、JSON知识参考上一篇JS博客代码解释 new Vue( JS对象 ) 这里是new出来一个 Vue对象里面传参传一个自定义的对象这个对象就是数据模型数据模型可以发现是一个JS对象键值对 el 指定挂载点要控制渲染的是哪一个容器 用于规定这个 Vue 能控制html中的哪些元素标签等里面的语法类似CSS选择器 例如这里 el: #app就是表示能控制idapp的这个元素data : 数据模型值是一个{ }也就是一个JSON对象里面的键值对可以放各种前端要展示的数据甚至是css样式可能还有更加高级的用法 3编写视图准备容器要渲染的标签一般我们都是使用一个div标签容器 {{ }} 插值表达式语法可以直接获取数据模型中的数据用于展示
示例
!DOCTYPE html
html langen
headmeta charsetUTF-8meta nameviewport contentwidthdevice-width, initial-scale1.0titleDocument/titlescript srchttps://cdn.jsdelivr.net/npm/vue2/dist/vue.js/script !-- 引入Vue.js --
/head
body!-- 定义要渲染的容器 --div idapp{{ message }} !-- 使用双大括号(插值表达式)绑定数据 --/div
/body
script// 定义Vue对象new Vue({el: #app, // 挂载点,绑定id为app的元素data: {message: Hello Vue.js! // 数据}})
/script
/html渲染结果
2插值表达式{{表达式}}
参考视频 插值表达式是一种Vue的模板语法
作用: 利用表达式进行插值访问data数据模型中数据渲染到页面中 表达式: 是可以被求值的代码JS引擎会将其计算出一个结果语法: {{表达式}} 注意点 使用的数据必须存在( data )支持的是表达式理解成能够求出一个值的js代码即可而非语句比如:if for …不能在标签属性中使用{{}}插值 标签属性中访问data数据模型中数据必须使用v-bind指令
示例
!DOCTYPE html
html langen
headmeta charsetUTF-8meta nameviewport contentwidthdevice-width, initial-scale1.0titleDocument/titlescript srchttps://cdn.jsdelivr.net/npm/vue2/dist/vue.js/script !-- 引入Vue.js --
/headbody!-- 插值表达式: {{ }} !-- 插值表达式,用于输出数据 --!-- 里面的表达式可以是任意的JavaScript表达式,可以是变量,也可以是函数,也可以是运算符等等只要最终能够返回一个值即可 --div idapp{{ nickname }} br !-- 输出 tony --{{nickname.toUpperCase()}} br !-- 输出 TONY --{{nickname.length}} br !-- 输出 4 --{{nickname.split().reverse().join()}} br !-- 输出 ynot --{{age 2}} br !-- 输出 20 --{{age 18 ? 成年人 : 未成年人}} br !-- 输出 未成年人 --!-- 拿到对象的属性: --{{friend.name}} br !-- 输出 jack --{{friend.age}} br !-- 输出 18 --/div/bodyscript// 定义Vue对象const app new Vue({el: #app, // 挂载点,绑定id为app的元素data: {nickname: tony,age : 16,friend : {name : jack,age : 18}}})/script
/html渲染结果
3Vue实例中的传入的对象中键的解释重要
new Vue() 实例化时除了 el 和 data 之外Vue 还支持许多其他属性来配置组件的行为。这些属性可以帮助你定义组件的生命周期、计算属性、方法、监听器、子组件等。下面会列出比较常见的几种
常见属性 el string 指定挂载点CSS 选择器将 Vue 实例挂载到 DOM 元素上。data Object 数据模型定义组件的初始数据必须是函数形式返回一个对象。methods Object 定义组件的方法可以在模板或逻辑中调用。 钩子方法 mounted() 挂载完成。
---- 数据模型data
data中的数据, 最终会被添加到对应的Vue实例上 访问数据: “实例.属性名”修改数据: “实例.属性名”“值”在Vue内部修改data里面的数据可以直接使用this.属性名访问到 例如在methods中我们如果有方法需要修改data里面的数据直接this.属性名就可以进行修改或者其他操作了
先记住这几条规则后面会频繁用到
script srchttps://cdn.jsdelivr.net/npm/vue2/dist/vue.js/script !-- 引入Vue.js --
bodydiv idapp{{nickname}} !-- 渲染结果 张三 --/div/bodyscript// 定义Vue对象const app new Vue({el: #app, // 挂载点,绑定id为app的元素data: {nickname: tony}})app.nickname 张三 // 修改数据/script---- 定义方法methods
具体使用见下面的【v-on:事件名 “methods中的函数名”】
---- mounted()钩子方法 挂载完成
具体使用见下面【案例练习AxiosVue,基于Vue及Axios完成数据的动态加载展示】
4Vue响应式特性
Vue核心特性: 响应式
我们已经掌握了基础的模板渲染其实除了基本的模板渲染Vue背后还做了大量工作。 比如: 数据的响应式处理 → 响应式: 数据模型里面数据发生变化对应的渲染视图自动更新聚焦于数据 → 数据驱动视图使用Vue开发关注业务的核心逻辑根据业务修改数据即可 示例 下面这个还是上面的插值表达式的示例代码我们在浏览器的控制台上面修改数据模型data里面的数据 更加具体清晰反映这种Vue核心特性: 响应式的例子见下面的【v-model指令在表单元素上创建双向数据绑定】
二、Vue常用指令 学习Vue指令建议先看v-on 这个给标签绑定事件的指令再学习其他指令会更加轻松。 Vue会根据不同的【指令】针对标签实现不同的【功能】。
通过Vue的各种指定就可以实现各种数据模型和前端展示相互依赖的效果下面我们就要来学习一些常用指令
指令: HTML标签上带有v-前缀 的特殊标签属性不同指令具有不同含义。例如:v-ifv-for…常用指令
1 v-html指令设置元素的innerHTML
作用: 设置元素的innerHTML 很显然和传统的DOM操作中Element对象的属性 ---- innerHTML属性 获取或设置元素的 HTML 内容的作用是一样的语法: v-html “表达式”
script srchttps://cdn.jsdelivr.net/npm/vue2/dist/vue.js/script !-- 引入Vue.js --
bodydiv idappdiv v-htmlmsg/div !-- 使用v-html指令插入 html --/div
/bodyscript// 定义Vue对象const app new Vue({el: #app, // 挂载点,绑定id为app的元素data: {msg:a hrefhttps://www.bilibili.com/哔哩哔哩/a}})
/script渲染结果
2 v-on指令为html标签绑定事件 作用: 注册事件 添加监听 提供处理逻辑 语法 v-on:事件名“内联语句” 内联语句理解成一段可执行的代码v-on:事件名 “methods中的函数名” 简写v-on:事件名 :事件名 例如v-on:click 监听按钮的点击事件触发 handleClick 方法。 可以简写为 click“handleClick”。 v-on 可以监听任何 DOM 事件例如 input输入事件keyup键盘按键松开事件submit表单提交事件mouseover鼠标悬停事件等等事件都可以上网去搜索一般会结合指令修饰符一起使用
1v-on:事件名“内联语句”
直接将要执行的代码写成字符串就可以执行了
script srchttps://cdn.jsdelivr.net/npm/vue2/dist/vue.js/script !-- 引入Vue.js --
bodydiv idappbutton click count count - 1-/buttonspan{{ count }}/spanbutton click count count 1/button/div
/bodyscript// 定义Vue对象const app new Vue({el: #app, // 挂载点,绑定id为app的元素data: {count : 100}})
/script渲染结果
2v-on:事件名 “methods中的函数名”
Vue示例中的 methods中可以定义各种事件触发的方法
---- 不传参
示例1
script srchttps://cdn.jsdelivr.net/npm/vue2/dist/vue.js/script
bodydiv idappinput typebutton value按钮 click handle()/div
/body
scriptnew Vue({el: #app,data: {message : 我被点击了},methods: {// methods中的所有函数this都指向当前实例handle(){alert(this.message); // 这个this语法下面会解释}/* 完整写法上面是简写handle : function(){alert(this.message); // 这个this语法下面会解释} */}});
/scriptthis 在 Vue 实例的方法中指向当前 Vue 实例。 通过 this 可以访问 data中的键。典型错误在 Vue.js 中this.data.message 是错误的写法。 在 Vue 中data 是一个函数它返回一个对象。Vue 会将 data 返回的对象中的属性直接挂载到 Vue 实例上而不是保留在 data 对象中。Vue 会将 message 直接挂载到实例上而不是保留在 data 对象中。因此你可以通过 this.message 访问 message而不是 this.data.message。总结一下我们传人的对象到Vue中Vue会将data下一级的键直接挂载在上面而不是直接挂载data。其余的也可以按照这个逻辑类比推导。
示例2
script srchttps://cdn.jsdelivr.net/npm/vue2/dist/vue.js/script
bodydiv idappbutton click fn切换显示隐藏/buttonh1 v-showisShow黑马程序员/h1/div
/body
scriptnew Vue({el: #app,data: {isShow: true},methods: {fn(){this.isShow !this.isShow; // 点击按钮时切换显示隐藏}}});
/script渲染结果
---- 传参
基本语法
script srchttps://cdn.jsdelivr.net/npm/vue2/dist/vue.js/script
bodydiv idappdiv classboxh3小黑自动售货机/h3button click buy(5)可乐5元/buttonbutton click buy(10)雪碧10元/button/divp银行卡余额{{money}}元/p/div
/body
scriptnew Vue({el: #app,data: {money: 100},methods: {buy(price){this.money - price;}}});
/script渲染结果
3 v-model指令在表单元素上创建双向数据绑定
作用: 给 表单元素 使用双向数据绑定 → 可以快速 获取 或 设置 表单元素内容 ① 数据变化 → 视图自动更新 ② 视图变化 → 数据自动更新语法:v-model‘变量’
1v-model 应用于输入框 input:text
这个指令就简单多了用处也比较单一只能用在表单元素上。 v-model 是 Vue.js 中用于实现表单输入元素和 Vue 实例数据之间双向绑定的指令。它主要用于 input、textarea、select 等表单元素能够自动同步用户输入的值和 Vue 实例中的数据。
示例1
v-model 将输入框的值与 Vue 实例中的 message 数据绑定。当用户输入内容时message 会自动更新反之如果 message 的值发生变化输入框的内容也会同步更新。
bodydiv id appinput typetext v-modelmessage !-- v-model指令用于在表单控件元素上创建双向数据绑定 --p{{ message }}/p !-- {{}}用于输出数据 --/div
/body
script srchttps://cdn.jsdelivr.net/npm/vue2/dist/vue.js/script !-- 引入Vue.js --
script// 定义Vue对象new Vue({el: #app, // 挂载点,绑定id为app的元素data: {message: Hello Vue.js! // 数据}})/script下面就演示什么叫数据模型与前端展示视图相互依赖 原始界面 将input输入框里面文字改成曹潇潇我喜欢你会发现下面的段落文字也会同步改变这就是相互依赖十分强大这个功能我们压根不需要去在操作DOM就能实现这样的同步效果。 示例2
script srchttps://cdn.jsdelivr.net/npm/vue2/dist/vue.js/script
bodydiv idapp账户input typetext v-modelusername brbr密码input typepassword v-modelpassword brbrbutton click login登录/buttonbutton click reset重置/button/div/bodyscriptnew Vue({el: #app,data: { username: ,password: },methods: {login() {// 登录的逻辑直接就可以通过 this.username 和 this.password 快速获取到输入框的值console.log(账户 this.username)console.log(密码 this.password)alert(用户this.username登录成功)},reset() {// 重置的逻辑this.username this.password } }})
/script渲染结果
2v-model 应用于其他各种表单组件
参考视频 常见的表单元素都可以用 v-model 绑定关联 → 快速 获取 或 设置 表单元素的值 它会根据 控件类型 自动选取 正确的方法 来更新元素 输入框 input:text 文本域 textarea 复选框 input:checkbox 单选框 input:radio 下拉菜单 select 案例通过这个案例将上述所有组件都演示一下使用
!DOCTYPE html
html langzh-CN
headmeta charsetUTF-8meta nameviewport contentwidthdevice-width, initial-scale1.0title小黑记事本/titlestyletextarea {display: block;width: 240px;height: 100px;margin: 10px 0;}/style
/head
bodydiv idapph3小黑学习网/h3!-- 输入框 --姓名input typetext v-modelusername !-- 输入框绑定是是 字符串类型 --brbr!-- 复选框 --是否单身input typecheckbox v-modelisSingle !-- 复选框绑定是是 布尔类型 --brbr!-- 前置理解1. name: 给单选框加上 name 属性 可以分组 → 同一组互相会互斥2. value: 给单选框加上 value 属性用于提交给后台的数据结合 Vue 使用 → v-model--!-- 单选框 --性别: input typeradio namegender value1 v-modelgender男 !-- 单选框绑定是是 字符串类型和你设置的value值一样 -- input typeradio namegender value2 v-modelgender女brbr!-- 前置理解1. option 需要设置 value 值提交给后台 ,假设 101 代表北京102 代表上海...2. select 的 value 值关联了选中的 option 的 value 值结合 Vue 使用 → v-model--!-- 下拉框 --所在城市:select v-modelcity_idoption value101北京/optionoption value102上海/optionoption value103成都/optionoption value104南京/option/selectbrbr!-- 文本域 --自我描述textarea v-modeldesc/textarea button立即注册/button/div/bodyscript srchttps://cdn.jsdelivr.net/npm/vue2/dist/vue.js/scriptscriptconst app new Vue({el: #app,data: {username: ,isSingle: true,gender : 1,city_id: 103,desc: }})/script
/html4 条件指令v-if , v-else-if, v-else根据if条件渲染某元素标签判定为true展示标签否则不展示 v-if if 作用: 控制元素显示隐藏条件渲染)语法: v-if “表达式”表达式值true显示 false隐藏 v-else-ifelse if 语法v-else-if “表达式”注意: 需要紧挨着v-if 一起使用 v-else: else 语法v-else注意: 需要紧挨着v-if 一起使用 等价于if(条件){}else if(条件){}else{}
script srchttps://cdn.jsdelivr.net/npm/vue2/dist/vue.js/script
bodydiv idapp年龄input typetext v-modelage经判定为span v-if age 35年轻人35及以下/span !-- if条件成立展示这条标签不成立就不展示 --span v-else-if age35 age60中年人35-60/span !-- else-if --span v-else老年人60以上/span !-- else --/div
/body
scriptnew Vue({el: #app,data: {age : 20},methods: {}});
/script5 v-show指令和v-if效果完全一样根据条件渲染某元素标签判定为true展示标签否则不展示
作用: 控制元素显示隐藏语法: v-show 表达式” 表达式值true显示 false隐藏v-show、v-if控制元素显示隐藏底层原理 v-show底层原理: 切换css 的display : none 来控制显示隐藏 适用于频繁切换显示隐藏的场景v-if底层原理: 根据判断条件控制DOM元素的创建和移除 适用于要么显示要么隐藏不频繁切换的场景具体的二者的使用场景有什么不同 参考视频
script srchttps://cdn.jsdelivr.net/npm/vue2/dist/vue.js/script
bodydiv idapp年龄input typetext v-modelage经判定为span v-show age 35年轻人35及以下/span span v-show age35 age60中年人35-60/span span v-show age 60老年人60以上/span /div
/body
scriptnew Vue({el: #app,data: {age : 20},methods: {}});
/script和v-if区别 v-if: 实际上浏览器界面中的html如果v-if条件不成立连标签都不会在html中 v-show: 实际上再浏览器中是通过设置 display为none来不展示这条标签的但是标签还是在html中
6 v-for指令: 基于数据循环多次渲染整个元素
1基本用法
作用: 基于数据循环多次渲染整个元素 遍历的可以是数组、对象、数字等 遍历的数组对象数字都是来源与数据模型data遍历数组语法
script srchttps://cdn.jsdelivr.net/npm/vue2/dist/vue.js/script
bodydiv idapp!-- 多次渲染div --div v-for(item, index) in addrs{{index1}}{{item}}/div /div
/bodyscriptnew Vue({el: #app,data: {addrs : [北京, 上海, 广州, 深圳]},methods: {}});
/script2扩展v-for 遍历渲染列表中 key属性的使用
参考视频1 参考视频2 语法: key属性“唯一标识” 这个唯一标识我们无论是数据库建表还是实体都会有这么一个唯一标识 作用: 给列表项添加的唯一标识。便于Vue进行列表项的正确排序复用 key 的作用是给每个节点一个唯一标识类似数据库优化中给字段加上索引帮助 Vue 快速判断 哪些节点是新增的哪些节点是被删除的哪些节点只是位置发生了变化 举一个例子没有 key 的问题 假设有一个列表 [A, B, C] 变为 [B, C, A] 没有 keyVue 会认为“第一个节点从 A 变成了 B”导致所有子节点被重新渲染性能差。 有 keyVue 发现节点只是顺序变化直接移动 DOM 元素位置即可性能高。 通常情况下不加上key属性功能也能正确实现只是效率低。部分特殊情况下进行了增删改查操作可以导致顺序混乱 所以我们使用v-for渲染列表开发规范是要求加上的 最佳实践必须使用唯一且稳定的标识符如 id不要用数组索引index 错误用法v-for“(item, index) in list” :key“index” 当列表顺序变化时index 会变化导致 key 不稳定失去优化意义。正确用法v-for“item in list” :key“item.id” 注意事项 key 的值只能是 字符串 或 数字类型key 的值必须具有 唯一性推荐使用 id 作为 key(唯一)不推荐使用 index作为 key(会变化不对应)
具体demo演示可以参考【案例2图书管理案例小黑的书架】
7 v-bind指令动态的设置html的标签属性→ src url title…如设置 hrefcss样式等超级灵活这个指令
之前我们学习插值表达式中讲过标签属性里面是不能使用插值表达式的这样标签属性就不能访问数据模型里面的数据了 只能通过指令v-bind,v-show等等这些指令可以解决这个问题 通过 v-bind你可以将 Vue 实例中的数据与 DOM 元素的属性关联起来实现动态更新。 作用: 动态的设置html的标签属性→ src url title… 基本语法 v-bind 的基本语法是 v-bind:属性名“表达式” 也可以简写为 :属性名“表达式”
1基本使用动态的设置html的标签属性→ src url title…
script srchttps://cdn.jsdelivr.net/npm/vue2/dist/vue.js/script
bodydiv idapp!-- a href{{url_1}}/a 这里是错误的写法,插值表达式不能作用于属性我们必须使用v-bind指令 --a :hrefurl_1百度/a !-- 动态绑定数据模型中的url_1到a标签的href属性上 --bra :hrefurl_2哔哩哔哩/a !-- 动态绑定数据模型中的url_2到a标签的href属性上 --/div/bodyscriptnew Vue({el: #app,data: { url_1: https://www.baidu.com,url_2: https://www.bilibili.com}})/script渲染结果
2进阶用法v-bind 对于样式控制的增强
对应样式的控制无非是class 类名 和 style 行内样式 这两种方法
为了方便开发者进行样式控制Vue 扩展了 v-bind 的语法可以针对 class 类名 和 style 行内样式 进行控制 。
---- v-bind 对于样式控制的增强-操作class
参考视频
语法:class对象/数组” ① 对象 → 键就是类名值是布尔值。如果值为 true有这个类否则没有这个类 ② 数组 →数组中所有的类都会添加到盒子上本质就是一个 class 列表
案例1 1动态绑定两个 classactive 和 large active 控制背景颜色和文字颜色 large 控制按钮的大小 2点击按钮时切换 active 和 large 的状态
!DOCTYPE html
html langen
headmeta charsetUTF-8meta nameviewport contentwidthdevice-width, initial-scale1.0titleVue 动态 Class 示例/titlescript srchttps://cdn.jsdelivr.net/npm/vue2/dist/vue.js/scriptstyle/* 定义 active 类的样式 */.active {background-color: green; /* 背景颜色变为绿色 */color: white; /* 文字颜色变为白色 */}/* 定义 large 类的样式 */.large {font-size: 20px; /* 文字大小变大 */padding: 15px 30px; /* 按钮内边距变大 */}/style
/head
bodydiv idapp!-- 动态绑定多个 class --button :class{ active: isActive, large: isLarge } clicktoggleClasses点击我/button/divscriptnew Vue({el: #app,data: {isActive: false, // 初始状态为 falseisLarge: false // 初始状态为 false},methods: {toggleClasses() {this.isActive !this.isActive; // 切换 active 状态this.isLarge !this.isLarge; // 切换 large 状态}}});/script
/body
/html运行效果 1初始状态 按钮没有 active 和 large 类样式为默认样式 2点击按钮后 按钮的背景颜色变成绿色文字颜色变成白色active 类生效 按钮的文字大小变大内边距变大large 类生效 3再次点击按钮 按钮恢复默认样式
案例2京东秒杀导航tab高亮
!DOCTYPE html
html langzh-CN
headmeta charsetUTF-8meta nameviewport contentwidthdevice-width, initial-scale1.0title小黑记事本/titlestyle* {margin: 0;padding: 0;}ul {display: flex;border-bottom: 2px solid #e01222;padding: 0 10px;}li {width: 100px;height: 50px;line-height: 50px;list-style: none;text-align: center;}li a {display: block;text-decoration: none;font-weight: bold;color: #333333;}li a.active {background-color: #e01222;color: #fff;}/style
/head
bodydiv idappulli v-for(item,index) in list :keyitem.id clickactivate_index index !-- clickactivate_index index // 点击事件点击时将当前索引赋值给activate_index --a :class{active:index activate_index} href# !-- :class{active:index activate_index} // 根据当前索引是否等于activate_index来判断是否添加active类 --{{item.name}}/a/li/ul/div/bodyscript srchttps://cdn.jsdelivr.net/npm/vue2/dist/vue.js/script
script
const app new Vue({el: #app,data: {activate_index: 0, // 记录当前激活的索引要高亮的tablist: [{ id: 1, name: 京东秒杀 },{ id: 2, name: 每日特价 },{ id: 3, name: 品类秒杀 }]}
})
/script
/html渲染结果
---- v-bind 对于样式控制的增强-操作style
参考视频
语法: style“样式对象”适用场景: 某个具体属性的动态设置
功能点击按钮时按钮的背景颜色和文字大小会动态变化。
!DOCTYPE html
html langen
headmeta charsetUTF-8meta nameviewport contentwidthdevice-width, initial-scale1.0titleVue 动态 Class 示例/titlescript srchttps://cdn.jsdelivr.net/npm/vue2/dist/vue.js/script/head
bodydiv idapp!-- 动态绑定 style --button :style{ backgroundColor: buttonColor, fontSize: fontSize px } clicktoggleStyle点击我/button/divscriptnew Vue({el: #app,data: {buttonColor: blue, // 初始背景颜色fontSize: 16 // 初始文字大小},methods: {toggleStyle() {this.buttonColor this.buttonColor blue ? green : blue; // 切换背景颜色this.fontSize 2; // 每次点击增加文字大小}}});/script
/body
/html9 指令修饰符简化代码
通过.指明一些指令 后缀不同 后缀 封装了不同的处理操作 → 进一步简化代码
1按键修饰符用于v-on键盘事件
按键修饰符用于键盘事件 常用按键别名.enter .tab .delete .esc .space .up .down .left .right keyup表示监听键盘上任何键按下任何键都会触发这个事件 keyup.enter按下回车键时触发keyup.ctrl.enter组合修饰符Ctrl Enter
2鼠标修饰符用于v-on鼠标事件
鼠标修饰符用于鼠标事件 click.left左键点击click.right右键点击click.middle中键点击
3表单修饰符用于 v-model
表单修饰符用于 v-model v-model.trim自动去除表单中输入的文本中的首尾空格v-model.number自动将表单中输入的文本转为数值类型 注意如果用户输入是 “abc”这种无法转number的那底层不会强转在数据模型中存成字符串当然如果是“12”这种数据模型中就会转成number保存了。为了用户的体验这样也非常合理
4事件修饰符用于 v-on
参考视频
事件修饰符 事件名.stop阻止冒泡 click.stop点击事件停止冒泡事件名.prevent阻止默认行为
---- 事件名.stop阻止冒泡
在html中给元素绑定事件会触发一种事件冒泡的现象 事件冒泡是指当一个元素上的事件被触发后会按照从内到外的顺序依次触发父元素上的同类型事件例如都是点击事件。
事件冒泡Event Bubbling 是浏览器的事件传播机制之一表现为 触发顺序当子元素触发事件时事件会 从触发元素开始逐级 向上层父元素传播依次触发各级父元素的 同类型事件。 传播路径子元素 → 父元素 → 祖父元素 → … → document
例如点击一个按钮如果按钮在表单里那么按钮的点击事件会先触发然后表单的点击事件也会触发。这可能不是用户想要的行为这时候就需要阻止事件冒泡。
当点击一个嵌套在父元素中的按钮时浏览器会按照 事件冒泡 机制触发事件
div clickhandleDivClickbutton clickhandleButtonClick点击我/button
/div默认行为点击按钮时会先触发 handleButtonClick接着触发 handleDivClick
问题如果希望点击按钮时 不触发父元素的点击事件就需要阻止事件冒泡
div clickhandleDivClickbutton click.stophandleButtonClick点击我/button
/div---- 事件名.prevent阻止默认行为
浏览器为某些事件预设了 自动触发的行为例如 1表单提交submit 事件页面会刷新或跳转 当用户按下回车键时浏览器会自动触发表单的提交行为如果表单中有输入框。如果没有 form 标签这种默认行为将无法实现。 2链接点击click 事件跳转到 href 指定的 URL 3右键菜单contextmenu 事件弹出系统默认菜单 4输入框回车keydown.enter 事件可能触发表单提交 这些行为是浏览器自带的但有时会干扰我们的自定义逻辑。事件名.prevent 的作用就是禁用这些默认行为。
以右键菜单这个默认行为为例任何浏览器页面鼠标右键都会弹出浏览器菜单界面栏
如果我们在开发过程中想要讲鼠标右键绑定自定义的事件就需要阻止这个弹出默认菜单栏的事件了
示例阻止右键菜单
div contextmenu.preventshowCustomMenu右键点击我不会弹出系统菜单
/divscriptnew Vue({methods: {showCustomMenu() {// 显示自定义右键菜单console.log(显示自定义菜单);}}});
/script默认行为弹出浏览器默认右键菜单 使用 .prevent不弹出默认菜单执行自定义逻辑showCustomMenu你可以在这个里面定义自己想执行的逻辑
示例阻止默认表单提交采用自定义逻辑提交表单表单提交常用
bodydiv idappform submit.preventhandleSubmitdivinput v-modelemail typeemail required placeholder请输入邮箱button typesubmit提交/button/div/form/div!-- 引入 Vue.js --script srchttps://cdn.jsdelivr.net/npm/vue2.7.14/dist/vue.js/scriptscript// 创建 Vue 实例new Vue({el: #app, // 指定挂载点data: {email: // 用于绑定输入框的值},methods: {handleSubmit() {if (this.email) {console.log(提交的邮箱地址是, this.email);// 在这里可以执行进一步的逻辑例如发送数据到服务器} else {console.log(邮箱地址不能为空);}}}});/script
/body在form的表单提交中如果不指定submit.prevent那么表单就会安装form上面指定的urlform中的属性可以指定等直接发送请求提交如果指定了就会执行submit.preventhandleSubmit里面自定义的handleSubmit方法逻辑我们可以在这个里面发送ajox请求这样我们不需要再form属性里面指定发送的方式和url,更加灵活
8 案例练习
1案例1图片切换波仔的学习之旅
参考视频
需求有6张照片通过上一页、下一页按钮进行切换 思路分析 数组存储图片路径 [ 图片1图片2图片3… ]准备下标 index数组[下标] → v-bind 设置 src 展示图片 → 修改下标切换图片
script srchttps://cdn.jsdelivr.net/npm/vue2/dist/vue.js/script
bodydiv idappbutton v-show index 0 click index--上一页/buttondivimg :srclist[index] alt/divbutton v-show index list.length-1 click index下一页/button/div/bodyscriptnew Vue({el: #app,data: { index : 0, // 动态绑定的索引当前显示的图片在数组中的索引list : [./img/1.png,./img/2.png,./img/3.png,./img/4.png,./img/5.png,./img/6.png,] // 图片数组,都是相对路径放在img文件夹下了}})
/script渲染结果
2案例2图书管理案例小黑的书架
参考视频1 参考视频2
需求
script srchttps://cdn.jsdelivr.net/npm/vue2/dist/vue.js/script
bodydiv idapph3小黑的书架/h3ulli v-for(book,idx) in bookList :keybook.id!-- key属性的作用是为了提高Vue的性能当数据发生变化时Vue会根据key的值来判断哪些元素是新增的哪些元素是删除的从而减少页面的更新。并且key属性要使用唯一的标识不能使用index作为key因为index在增删改查时会发生变化不利于Vue的性能优化。 --span{{book.name}}/spanspan{{book.author}}/spanspan{{book.price}}/span!-- 注册点击事件通过id删除对应的书记 --button click removeBook(book.id)删除/button/li/ul/div/bodyscriptnew Vue({el: #app,data: { bookList: [{id:1, name: 《算法导论》 , author : Thomas H. Cormen , price : 85.00},{id:2, name: 《UNIX编程艺术》 , author : Eric S. Raymond , price : 59.00},{id:3, name: 《编程珠玑》 , author : Jon Bentley , price : 39.00},{id:4, name: 《代码大全》 , author : Steve McConnell , price : 128.00}]},methods: {// 删除书籍,删除功能我们只用删除数据模型中的数据即可页面会自动更新这就是Vue的响应式特性removeBook(id){// filter:根据条件保留满足条件的对应项得到一个新数组。this.bookList this.bookList.filter(item item.id ! id)}}})
/script渲染结果
3案例3综合案例小黑记事本
需求 列表渲染删除功能添加功能底部统计 和 清空
---- step1: 使用AI生成ui布局
由于我对前端的页面排版布局了解很有限所以这里借用deepseek设计生成html和css的基本布局结构 - 上传上面的ui图片提问帮我根据上传的图片生成html ui样式
ai生成结果
!DOCTYPE html
html langzh-CN
headmeta charsetUTF-8meta nameviewport contentwidthdevice-width, initial-scale1.0title小黑记事本/titlestyle* {margin: 0;padding: 0;box-sizing: border-box;}body {font-family: Microsoft YaHei, sans-serif;background-color: #f5f5f5;padding: 20px;}.container {max-width: 600px;margin: 0 auto;background-color: white;border-radius: 8px;box-shadow: 0 2px 12px rgba(0,0,0,0.1);padding: 24px;}h3 {color: #333;font-size: 24px;margin-bottom: 20px;text-align: center;}.input-group {display: flex;gap: 10px;margin-bottom: 20px;}input[typetext] {flex: 1;padding: 10px;border: 1px solid #ddd;border-radius: 4px;font-size: 16px;}button {padding: 10px 20px;border: none;border-radius: 4px;cursor: pointer;transition: 0.3s;}.add-btn {background-color: #409eff;color: white;}.add-btn:hover {background-color: #66b1ff;}.task-list {list-style: none;margin-bottom: 20px;}.task-item {display: flex;justify-content: space-between;align-items: center;padding: 12px;border-bottom: 1px solid #eee;}.task-item:last-child {border-bottom: none;}.task-content {display: flex;align-items: center;gap: 8px;}.task-index {color: #666;}.delete-btn {color: #f56c6c;background: none;padding: 4px;}.footer {display: flex;justify-content: space-between;align-items: center;padding-top: 16px;border-top: 1px solid #eee;}.total {color: #666;}.clear-btn {background-color: #f56c6c;color: white;}/style
/head
bodydiv classcontainerh3小黑记事本/h3div classinput-groupinput typetext placeholder请输入任务button classadd-btn添加任务/button/divul classtask-listli classtask-itemdiv classtask-contentspan classtask-index1./spanspan跑步锻炼20分钟/span/divbutton classdelete-btn×/button/lili classtask-itemdiv classtask-contentspan classtask-index2./spanspan复习数组语法/span/divbutton classdelete-btn×/button/li/uldiv classfooterspan classtotal合计2/spanbutton classclear-btn清空任务/button/div/div
/body
/html渲染结果 可以看到生成的UI框架可以满足我们的需求下面我们在这份框架上面进一步开发即可。
---- step2: 在ai生成的ui的html架构上面进一步开发
!DOCTYPE html
html langzh-CN
headmeta charsetUTF-8meta nameviewport contentwidthdevice-width, initial-scale1.0title小黑记事本/titlestyle* {margin: 0;padding: 0;box-sizing: border-box;}body {font-family: Microsoft YaHei, sans-serif;background-color: #f5f5f5;padding: 20px;}.container {max-width: 600px;margin: 0 auto;background-color: white;border-radius: 8px;box-shadow: 0 2px 12px rgba(0,0,0,0.1);padding: 24px;}h3 {color: #333;font-size: 24px;margin-bottom: 20px;text-align: center;}.input-group {display: flex;gap: 10px;margin-bottom: 20px;}input[typetext] {flex: 1;padding: 10px;border: 1px solid #ddd;border-radius: 4px;font-size: 16px;}button {padding: 10px 20px;border: none;border-radius: 4px;cursor: pointer;transition: 0.3s;}.add-btn {background-color: #409eff;color: white;}.add-btn:hover {background-color: #66b1ff;}.task-list {list-style: none;margin-bottom: 20px;}.task-item {display: flex;justify-content: space-between;align-items: center;padding: 12px;border-bottom: 1px solid #eee;}.task-item:last-child {border-bottom: none;}.task-content {display: flex;align-items: center;gap: 8px;}.task-index {color: #666;}.delete-btn {color: #f56c6c;background: none;padding: 4px;}.footer {display: flex;justify-content: space-between;align-items: center;padding-top: 16px;border-top: 1px solid #eee;}.total {color: #666;}.clear-btn {background-color: #f56c6c;color: white;}/style
/head
bodydiv classcontainerh3小黑记事本/h3div classinput-groupinput typetext placeholder请输入任务 v-modelto_add_task keyup.enteradd_task !-- keyup.enter:绑定键盘回车事件 --button classadd-btn clickadd_task添加任务/button/divul classtask-listli classtask-item v-for(task, index) in tasks :keytask.iddiv classtask-contentspan classtask-index{{index 1 }}/spanspan{{task.name}}/span/divbutton classdelete-btn click del(task.id)×/button/li/uldiv classfooterspan classtotal v-showtasks.length 0合计{{tasks.length}}/spanbutton classclear-btn clickclear v-showtasks.length 0清空任务/button !-- v-show 控制元素的显示和隐藏,当tasks数组长度大于0时才显示清空任务按钮 --/div/div
/bodyscript srchttps://cdn.jsdelivr.net/npm/vue2/dist/vue.js/script
scriptconst container new Vue({el: .container, // 挂载点 , id使用 # class使用 . 一般更加推荐id选择器挂载因为id选择器唯一class选择器可以有多个data: {to_add_task: ,tasks: [{ id : 1,name: 跑步锻炼20分钟 },{ id : 2 ,name: 复习数组语法 },{ id : 3 ,name: 游泳100里 }]},methods: {// 删除任务del(id){this.tasks this.tasks.filter(task task.id ! id)},// 添加任务// 1.通过 v-model 绑定 输入框 → 实时获取表单元素的内容// 2.点击按钮进行新增往数组最前面加 unshiftadd_task(){if (this.to_add_task.trim() ){alert(请输入任务内容)return}// 使用unshift方法将新任务添加到数组的最前面this.tasks.unshift({id: new Date(), // 为了保证id唯一性前端临时可以使用时间戳name: this.to_add_task})this.to_add_task },// 清空任务clear(){this.tasks []}}})/script/html渲染结果
4案例4通过Vue完成表格数据的渲染展示
需求
!DOCTYPE html
html langen
headmeta charsetUTF-8meta nameviewport contentwidthdevice-width, initial-scale1.0titleVue 动态 Class 示例/titlescript srchttps://cdn.jsdelivr.net/npm/vue2/dist/vue.js/script
/head
bodydiv idapptable border1 cellspacing0 width60%trth编号/thth姓名/thth年龄/thth性别/thth成绩/thth等级/th/trtr aligncenter v-for(user, index) in userstd{{index1}}/tdtd{{user.name}}/tdtd{{user.age}}/tdtdspan v-showuser.gender 1男/spanspan v-showuser.gender 2女/span/tdtd{{user.score}}/tdtdspan v-showuser.score85优秀/spanspan v-showuser.score60 user.score85及格/spanspan v-showuser.score60 stylecolor: red;不及格/span/td/tr/table/divscriptnew Vue({el: #app,data: { users:[{name: Tom,age: 18,gender: 1,score: 78},{name:Rose,age: 20,gender: 2,score: 86},{name: Jerry,age: 22,gender: 1,score: 90},{name: Jack,age: 19,gender: 1,score: 52}]},methods: {}})/script
/body
/html三、计算属性和监视器
1 计算属性
1基本概念
概念: 基于现有的数据计算出来的新属性。依赖的数据变化自动重新计算。语法: 1声明在 computed 配置项中一个计算属性对应一个函数 2使用起来和普通属性一样使用{{ 计算属性名 }}和data里面的插值表达式一样的语法 其实就是将methods方法里面的有返回值的函数移到了现在的computed里面 计算属性 → 可以将一段 求值的代码 进行封装
2使用计算属性和methods的区别
computed 计算属性: 作用: 封装了一段对于数据的处理求得一个结果。语法: ① 写在 computed 配置项中 ② 作为属性直接使用 → this.计算属性或者 {{ 计算属性 }}缓存特性(提升性能) 计算属性会对计算出来的结果缓存再次使用直接读取缓存 依赖项变化了会自动重新计算 →并再次缓存 methods 方法: 作用: 给实例提供一个方法调用以处理业务逻辑。语法: ① 写在 methods 配置项中 ② 作为方法需要调用 → this.方法名() 或者 {{ 方法名() }} 或者 事件名方法名
下面将用计算礼物数这个案例来展示二者的不同之处
---- 使用 计算属性 computed
!DOCTYPE html
html langen
headmeta charsetUTF-8meta http-equivX-UA-Compatible contentIEedgemeta nameviewport contentwidthdevice-width, initial-scale1.0titleDocument/titlestyletable {border: 1px solid #000;text-align: center;width: 240px;}th,td {border: 1px solid #000;}h3 {position: relative;}/style
/head
bodydiv idapph3小黑的礼物清单/h3tabletrth名字/thth数量/th/trtr v-for(item, index) in list :keyitem.idtd{{ item.name }}/tdtd{{ item.num }}个/td/tr/table!-- 目标统计求和求得礼物总数 --p礼物总数{{ totalCount }} 个/p /divscript srchttps://cdn.jsdelivr.net/npm/vue2/dist/vue.js/scriptscriptconst app new Vue({el: #app,data: {// 现有的数据list: [{ id: 1, name: 篮球, num: 1 },{ id: 2, name: 玩具, num: 2 },{ id: 3, name: 铅笔, num: 5 },]},computed: {totalCount () {// 基于现有的数据编写求值逻辑// 计算属性函数内部可以直接通过 this 访问到 app 实例// console.log(this.list)// 需求对 this.list 数组里面的 num 进行求和 → reducelet total this.list.reduce((sum, item) sum item.num, 0)return total}}})/script
/body
/html渲染结果
---- 使用methods
!DOCTYPE html
html langen
headmeta charsetUTF-8meta http-equivX-UA-Compatible contentIEedgemeta nameviewport contentwidthdevice-width, initial-scale1.0titleDocument/titlestyletable {border: 1px solid #000;text-align: center;width: 240px;}th,td {border: 1px solid #000;}h3 {position: relative;}/style
/head
bodydiv idapph3小黑的礼物清单/h3tabletrth名字/thth数量/th/trtr v-for(item, index) in list :keyitem.idtd{{ item.name }}/tdtd{{ item.num }}个/td/tr/table!-- 修改点1改用方法调用 --p礼物总数{{ totalCount() }} 个/p/divscript srchttps://cdn.jsdelivr.net/npm/vue2/dist/vue.js/scriptscriptconst app new Vue({el: #app,data: {list: [{ id: 1, name: 篮球, num: 1 },{ id: 2, name: 玩具, num: 2 },{ id: 3, name: 铅笔, num: 5 },]},methods: { // 修改点2将计算属性改为方法totalCount() {return this.list.reduce((sum, item) sum item.num, 0)}}})/script
/body
/html渲染结果
3计算属性的完整写法了解即可
参考视频
计算属性默认的简写只能读取访问不能修改如果要修改→ 需要写计算属性的完整写法 注这里这种完整写法太麻烦了特别是里面的set逻辑不如交给java后端这里我们不详细说明了几乎不可能用到。 !DOCTYPE html
html langen
headmeta charsetUTF-8meta http-equivX-UA-Compatible contentIEedgemeta nameviewport contentwidthdevice-width, initial-scale1.0titleDocument/titlestyleinput {width: 30px;}/style
/head
bodydiv idapp姓input typetext v-modelfirstName 名input typetext v-modellastName span{{ fullName }}/spanbrbrbutton clickchangeName改名卡/button/divscript srchttps://cdn.jsdelivr.net/npm/vue2/dist/vue.js/scriptscriptconst app new Vue({el: #app,data: {firstName: 刘,lastName: 备,},methods: {changeName () {this.fullName 黄忠}},computed: {// 简写 → 获取没有配置设置的逻辑// fullName () {// return this.firstName this.lastName// }// 完整写法 → 获取 设置fullName: {// (1) 当fullName计算属性被获取求值时执行get有缓存优先读缓存// 会将返回值作为求值的结果get () {return this.firstName this.lastName},// (2) 当fullName计算属性被修改赋值时执行set// 修改的值传递给set方法的形参set (value) {// console.log(value.slice(0, 1)) // console.log(value.slice(1)) this.firstName value.slice(0, 1)this.lastName value.slice(1)}}}})/script
/body
/html渲染结果
2 watch 侦听器(监视器)监视数据模型中数据的变化待定下面的案例建议先将ajox技术学好再回来重新学习 作用: 监视数据变化执行一些 业务逻辑 或 异步操作 需要注意的是watch 侦听器(监视器)监视的是数据模型里面的数据变化和我们之前的事件监视中监视点击事件这些有点区别 一个最典型的应用就是实时翻译功能 语法: ① 简单写法 → 简单类型数据直接监视 ② 完整写法 → 添加额外配置项
1watch 侦听器(监视器)简写语法
参考视频
语法 需求输入内容实时翻译
!DOCTYPE html
html langenheadmeta charsetUTF-8 /meta http-equivX-UA-Compatible contentIEedge /meta nameviewport contentwidthdevice-width, initial-scale1.0 /titleDocument/titlestyle* {margin: 0;padding: 0;box-sizing: border-box;font-size: 18px;}#app {padding: 10px 20px;}.query {margin: 10px 0;}.box {display: flex;}textarea {width: 300px;height: 160px;font-size: 18px;border: 1px solid #dedede;outline: none;resize: none;padding: 10px;}textarea:hover {border: 1px solid #1589f5;}.transbox {width: 300px;height: 160px;background-color: #f0f0f0;padding: 10px;border: none;}.tip-box {width: 300px;height: 25px;line-height: 25px;display: flex;}.tip-box span {flex: 1;text-align: center;}.query span {font-size: 18px;}.input-wrap {position: relative;}.input-wrap span {position: absolute;right: 15px;bottom: 15px;font-size: 12px;}.input-wrap i {font-size: 20px;font-style: normal;}/style/headbodydiv idapp!-- 条件选择框 --div classqueryspan翻译成的语言/spanselectoption valueitaly意大利/optionoption valueenglish英语/optionoption valuegerman德语/option/select/div!-- 翻译框 --div classboxdiv classinput-wraptextarea v-modelobj.words/textareaspani⌨️/i文档翻译/span/divdiv classoutput-wrapdiv classtransbox{{transResult}}/div/div/div/divscript srchttps://cdn.jsdelivr.net/npm/vue2/dist/vue.js/scriptscript srchttps://cdn.jsdelivr.net/npm/axios/dist/axios.min.js/scriptscript// 接口地址https://applet-base-api-t.itheima.net/api/translate// 返回 {message: ok,data: Qffo} ,接口的翻译是随机生成的字符结果// 请求方式get// 请求参数// 1words需要被翻译的文本必传// 2lang 需要被翻译成的语言可选默认值-意大利// -----------------------------------------------const app new Vue({el: #app,data: {// words: obj: {words: },// 翻译结果transResult: },// 具体讲解(1) watch语法 (2) 具体业务实现watch: {// 该方法会在数据变化时调用执行// newValue新值, oldValue老值一般不用// words (newValue) {// console.log(变化了, newValue)// }obj.words (newValue) {console.log(变化了, newValue)// 使用axios发送请求axios ({method: get,url:https://applet-base-api-t.itheima.net/api/translate,params:{words: newValue,}}).then(res {this.transResult res.data.data})}}})/script/body
/html结果
2watch 侦听器(监视器)完整语法进阶
3 案例
综合案例1成绩表格
参考视频
需求 index.css
.score-case {width: 1000px;margin: 50px auto;display: flex;
}
.score-case .table {flex: 4;
}
.score-case .table table {width: 100%;border-spacing: 0;border-top: 1px solid #ccc;border-left: 1px solid #ccc;
}
.score-case .table table th {background: #f5f5f5;
}
.score-case .table table tr:hover td {background: #f5f5f5;
}
.score-case .table table td,
.score-case .table table th {border-bottom: 1px solid #ccc;border-right: 1px solid #ccc;text-align: center;padding: 10px;
}
.score-case .table table td.red,
.score-case .table table th.red {color: red;
}
.score-case .table .none {height: 100px;line-height: 100px;color: #999;
}
.score-case .form {flex: 1;padding: 20px;
}
.score-case .form .form-item {display: flex;margin-bottom: 20px;align-items: center;
}
.score-case .form .form-item .label {width: 60px;text-align: right;font-size: 14px;
}
.score-case .form .form-item .input {flex: 1;
}
.score-case .form .form-item input,
.score-case .form .form-item select {appearance: none;outline: none;border: 1px solid #ccc;width: 200px;height: 40px;box-sizing: border-box;padding: 10px;color: #666;
}
.score-case .form .form-item input::placeholder {color: #666;
}
.score-case .form .form-item .cancel,
.score-case .form .form-item .submit {appearance: none;outline: none;border: 1px solid #ccc;border-radius: 4px;padding: 4px 10px;margin-right: 10px;font-size: 12px;background: #ccc;
}
.score-case .form .form-item .submit {border-color: #069;background: #069;color: #fff;
}静态模版
!DOCTYPE html
html langenheadmeta charsetUTF-8 /meta http-equivX-UA-Compatible contentIEedge /meta nameviewport contentwidthdevice-width, initial-scale1.0 /link relstylesheet href./index.css /titleDocument/title/headbodydiv idapp classscore-casediv classtabletabletheadtrth编号/thth科目/thth成绩/thth操作/th/tr/theadtbodytrtd1/tdtd语文/tdtd classred46/tdtda href#删除/a/td/trtrtd2/tdtd英语/tdtd80/tdtda href#删除/a/td/trtrtd3/tdtd数学/tdtd100/tdtda href#删除/a/td/tr/tbodytbodytrtd colspan5span classnone暂无数据/span/td/tr/tbodytfoottrtd colspan5span总分246/spanspan stylemargin-left: 50px平均分79/span/td/tr/tfoot/table/divdiv classformdiv classform-itemdiv classlabel科目/divdiv classinputinputtypetextplaceholder请输入科目//div/divdiv classform-itemdiv classlabel分数/divdiv classinputinputtypetextplaceholder请输入分数//div/divdiv classform-itemdiv classlabel/divdiv classinputbutton classsubmit 添加/button/div/div/div/divscript srchttps://cdn.jsdelivr.net/npm/vue2/dist/vue.js/scriptscriptconst app new Vue({el: #app,data: {list: [{ id: 1, subject: 语文, score: 20 },{ id: 7, subject: 数学, score: 99 },{ id: 12, subject: 英语, score: 70 },],subject: ,score: }})/script/body
/html最终结果
!DOCTYPE html
html langenheadmeta charsetUTF-8 /meta http-equivX-UA-Compatible contentIEedge /meta nameviewport contentwidthdevice-width, initial-scale1.0 /link relstylesheet href./index.css /titleDocument/title/headbodydiv idapp classscore-casediv classtabletabletheadtrth编号/thth科目/thth成绩/thth操作/th/tr/theadtbody v-iflist.length 0tr v-for(item,index) in list :keyitem.idtd{{index 1}}/tdtd{{item.subject}}/td!-- 需求:不及格的标红60分加上 red 类 --!-- td classred{{item.score}}/td --td :class{red : item.score 60}{{item.score}}/tdtda href# click.preventdel(item.id)删除/a/td/tr/tbodytbody v-elsetrtd colspan5span classnone暂无数据/span/td/tr/tbodytfoottrtd colspan5span总分{{total}}/span span stylemargin-left: 50px平均分{{avg}}/span/td/tr /tfoot/table/divdiv classform div classform-itemdiv classlabel科目/divdiv classinputinputtypetextplaceholder请输入科目v-model.trimsubject//div/divdiv classform-itemdiv classlabel分数/divdiv classinputinputtypetextplaceholder请输入分数v-model.numberscore//div /divdiv classform-itemdiv classlabel/divdiv classinputbutton classsubmit clickadd添加/button/div/div/div/div/bodyscript srchttps://cdn.jsdelivr.net/npm/vue2/dist/vue.js/scriptscriptconst app new Vue({el: #app,data: {list: [{ id: 1, subject: 语文, score: 20 },{ id: 7, subject: 数学, score: 99 },{ id: 12, subject: 英语, score: 70 },],subject: ,score: },methods: {del(id) {this.list this.list.filter(item item.id ! id)},add(){if(!this.subject || !this.score){alert(请输入科目和分数)return}this.list.unshift({id: new Date(),subject: this.subject,score: this.score})this.subject this.score }},computed: {total() {return this.list.reduce((prev, cur) prev cur.score, 0)},avg() {if (this.list.length 0) {return 0} return (this.total / this.list.length).toFixed(2)}},})/script
/html三 Vue生命周期和Vue中发送请求的位置
参考视频
1Vue对象的生命周期
生命周期: 指一个对象从创建到销毁的整个过程。生命周期的八个阶段: 每触发一个生命周期事件会自动执行一个生命周期方法(钩子)
对于上述生命周期的8个阶段我们作为一个Java程序员只需要知道mounted挂载完成理解成Vue彻底创建成功时这个时刻也是我们发送前端可以发送Web请求的时刻。
2mounted阶段发送请求的时刻
需要结合axios技术发送异步请求结合使用具体详细使用见【4 案例练习AxiosVue,基于Vue及Axios完成数据的动态加载展示】
生命周期的八个阶段:每触发一个生命周期事件会自动执行一个生命周期方法(钩子) mounted:挂载完成Vue初始化成功HTML页面染成功。(发送请求到服务端加载数据)
bodydiv idapp/divscriptnew Vue({el: #app,data: { },methods: {},mounted() {alert(Vue 实例已经挂载完成发送请求到服务器获取数据) /* mounted钩子函数中发送请求到服务器获取数据并且这个方法是自动执行的 */// 后面会学习怎么发送请求并且将返回的响应数据保存到data中},})/script
/body四、Ajax技术从服务端获取数据发送各种请求
参考视频 官方文档
0 接口文档管理使用apipost等接口测试软件创建接口便于前端后端分离测试
参考视频
接口文档管理 在线 apipostapifoxpostman等等 离线 wordmd
在线的apipost这些测试工具功能很多具体的后面不断深入学习慢慢了解这个测试工具这个测试工具必须会用后面无论是前端还是后端都需要频繁使用这个工具来进行测试。
下面的Ajax技术案例中的后端返回json数据都是通过这些接口工具的mock功能模拟生成的。
1 基本概念 学习本节前建议先去学习什么是GET、POST请求这些 概念: Asynchronous JavaScript And XML异步的JavaScript和XML。 Ajax技术是一个异步交互技术通过这个Ajax技术我们就可以从服务端获取数据作用: 数据交换: 通过Ajax可以给服务器发送请求并获取服务器响应的数据。异步交互: 可以在不重新加载整个页面的情况下与服务器交换数据并更新部分网页的技术如: 搜索联想、用户名是否可 用的校验等等。 同步与异步请求区别 举一个例子就好理解了 我们在点击某些页面的时候如果网络不好界面就会一直卡在转圈圈的界面我们不能进行任何操作这就是同步请求如果我们点击某些页面就算网络不好我们还是可以操作页面例如我们下载文件这个请求就是典型的异步请求。 Ajax技术就是一项发送异步请求的技术了。
2 原生Ajax几年前的早期用法 太繁琐现在已经淘汰了解一下 可以使用网页版的apifox、或者apipost个人感觉apifox更好用界面更加清晰apipost界面有点复杂好多功能要摸索生成一个get请求响应数据作为测试 使用 1准备数据地址: https://mock.apipost.net/mock/3d9177ae94de000/user/getById?apipost_id192051f4324002 用apipost先构建一个这样的mock地址 2创建XMLHttpRequest对象: 用于和服务器交换数据 3向服务器发送请求 4获取服务器响应数据
bodyinput typebutton value获取数据 onclick getData()div iddiv1/div
/bodyscriptfunction getData(){// 1 创建 XMLHttpRequest 对象var xmlHttpRequest new XMLHttpRequest();// 2 发送异步请求xmlHttpRequest.open(GET,https://mock.apipost.net/mock/3d9177ae94de000/user/getById?apipost_id192051f4324002);xmlHttpRequest.send(); // 发送请求// 3 获取服务器响应的数据xmlHttpRequest.onreadystatechange function(){if(xmlHttpRequest.readyState 4 xmlHttpRequest.status 200){ // 判断服务器是否响应成功//var data JSON.parse(xmlHttpRequest.responseText);document.getElementById(div1).innerHTML xmlHttpRequest.responseText;// xmlHttpRequest.responseText 返回服务器响应的数据以字符串形式返回}}}/script点击按钮后
代码解释 官方文档
3 Axios(对原生的Ajax进行了封装)
参考视频 介绍:Axios 对原生的Ajax进行了封装简化书写快速开发。 官网(使用文档等): https://www.axios-http.cn/ Axios 是一个基于 promise 的网络请求库可以用于浏览器和 node.js 使用 引入Axios的js文件 script src“https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js”/script 上面官网有这么引用的介绍使用Axios发送请求并获取响应结果
!DOCTYPE html
html langen
headmeta charsetUTF-8meta nameviewport contentwidthdevice-width, initial-scale1.0titleAxios基本演示/title!-- 引入axios --script srchttps://cdn.jsdelivr.net/npm/axios/dist/axios.min.js/script
/head
bodyinput typebutton value获取数据 onclick getData()div iddiv1/div
/bodyscriptfunction getData(){// 通过axios发送异步get请求axios({method: get,url: https://mock.apipost.net/mock/3d9177ae94de000/user/getById?apipost_id192051f4324002}).then(result {document.getElementById(div1).innerHTML result.data.name;// 通过 result.data 获取服务器返回的的JSON对象})// 通过axios发送异步post请求 ..... 后面有需要再补充}
/script
/html请求方式别名 axios提供了发送各种请求的别名简化调用方式后面我们也更多会使用这种进行开发 axios.get(url [, config]) axios.delete(url [, config]) axios.post(url [, data[, config]l) axios.put(url [, data[, config]])
!DOCTYPE html
html langen
headmeta charsetUTF-8meta nameviewport contentwidthdevice-width, initial-scale1.0titleAxios基本演示/title!-- 引入axios --script srchttps://cdn.jsdelivr.net/npm/axios/dist/axios.min.js/script
/head
bodyinput typebutton value获取数据 onclick getData()div iddiv1/div
/bodyscriptfunction getData(){// 通过axios发送异步get请求/* axios({method: get,url: https://mock.apipost.net/mock/3d9177ae94de000/user/getById?apipost_id192051f4324002}).then(result {document.getElementById(div1).innerHTML result.data.name;// 通过 result.data 获取服务器返回的的JSON对象}) */axios.get(https://mock.apipost.net/mock/3d9177ae94de000/user/getById?apipost_id192051f4324002).then(result {document.getElementById(div1).innerHTML ID: result.data.id br Name: result.data.name br Age: result.data.age br Gender: result.data.gender; })// 通过axios发送异步post请求 ..... 后面有需要再补充}
/script
/html注意 axios技术可以用来前端发送各种get、post请求等等这里只是简单演示了怎么发送get请求并对其返回的数据进行简单处理。后面的不断深入学习前端会不断演示各种请求的发送与处理特别是后面学习了Web请求的知识后。 4 案例练习AxiosVue,基于Vue及Axios完成数据的动态加载展示重要
参考视频 数据准备的url: https://mock.apipost.net/mock/3d9177ae94de000/user/getUsers?apipost_id1dafc1b2fc9005 在页面加载完成后自动发送异步请求加载数据渲染展示页面。 使用Vue只要在mounted阶段发送异步请求即可
!DOCTYPE html
html langen
headmeta charsetUTF-8meta nameviewport contentwidthdevice-width, initial-scale1.0titleVue axios发送请求使用/titlescript srchttps://cdn.jsdelivr.net/npm/vue2/dist/vue.js/script!-- 引入axios --script srchttps://cdn.jsdelivr.net/npm/axios/dist/axios.min.js/script
/head
bodydiv idapptable border1 cellspacing0 width60%trth编号/thth姓名/thth年龄/thth性别/thth职位/thth入职日期/thth最后操作时间/th/trtr aligncenter v-foruser in userstd{{user.id}}/tdtd{{user.name}}/tdtd{{user.age}}/tdtdspan v-showuser.gender 1男/spanspan v-showuser.gender 2女/span/tdtd{{user.job}}/tdtd{{user.entrydate}}/tdtd{{user.updatetime}}/td/tr/table/divscriptnew Vue({el: #app,data: { users: [] // 定义一个空数组用于存放请求到的数据,必须要有这个不然直接this.users会报错},mounted() {// 使用axios发送异步请求axios.get(https://mock.apipost.net/mock/3d9177ae94de000/user/getUsers?apipost_id1dafc1b2fc9005).then(result {this.users result.data // 将请求到的数据赋值给users,使用 this挂载到Vue实例上}) }})/script
/body
/html