vue 的最重要的 技术点(本章):
数据的 响应式 -> 即 数据 发生了改变,则 视图 自动跟随改变。
{{ 表达式 }} 的用法
v-bind 的各种用法(包括: class 和 style)
01_JS和三阶段的关系
<script>
// https://gitee.com/
// JS - 在整个前端 中,绝对基础且重要的 知识领域。
// JS 类比为 内功。
// 三阶段 - vue/react 更多的算「招式」。
// JS 基础,一定要 好好掌握:
// 函数、数组、ES6相关...
</script>
02_vue前置知识
就是框架,飞法法提高开发效率,原生js有时还要考虑浏览器兼容性阻止冒泡写一堆代码
JS => JQuery =>框架时代(React、Vue)
- JS:原生 JS 直接操作DOM元素
- JQuery库:(流行事件2005年~2015年):提供的大量的函数简化操作DOM 并且解决DOM操作的浏览器兼容性问题。
- 框架:(Angular-谷歌出品-现在国内几乎不使用了、React- Facebook 出品、Vue):提供了一整套全新的、高效的前端开发方案:
<head>
<style>
.box {
width: 100px;
height: 100px;
background-color: pink;
}
</style>
</head>
<body>
<div class="box"></div>
</body>
</html>
<script>
/* JS 开发的缺点:DOM操作麻烦,且 需要考虑兼容性
const box = document.querySelector(".box");
// 考虑 浏览器的兼容性
box.addEventListener("click", (e) => {
// 事件对象 的 兼容性 写法:
e = e || window.event;
// 阻止 冒泡 - 阻止事件冒泡也 需要兼容性写法:
e.stopPropagation(); // 阻止事件冒泡
e.cancelBubble = true; // 阻止事件冒泡 的 兼容性写法
console.log("点击了 box...");
});
*/
/* 框架 所 提供的 功能 / 框架的优势:
- ** 数据的响应式(数据驱动视图)
- 组件化
- 渐进式
*/
</script>
1.3 前端框架与库的区别?
- 功能层面
jquery库:操作DOM+网络请求后端数据
框架:提供全方位功能,齐全
如果把库比作肯德基的小套餐的话,框架就类似于KFC的全家桶级别的
- 代码层面
库:是为了实现某个页面功能,而调用某个函数:
框架:在框架提供的语法和规则下完成页面功能的开发
- 总结
库:在JS的基础上,引入和使用库的各种函数,
框架:大而沉,有自己完整的语法,相比库的学习成本更高,但开发效率也更高。
框架所提供的重要功能和特性:
- 如 数据的响应式(数据驱动视图)
- 组件化
- 渐进式
03-JS案例:手动执行绘制render
<body>
<div id="app">//我这个地方给你了一个div?
<!-- 人家规定 : h1 标签 必须 渲染在 #app 的 div 下面 -->
</div>
</body>
</html>
<script>
// render - 渲染/绘制
// 后端返回的数据:
const model = {
content: "欢迎来到页面",
};
// 思路:写一个 render 函数,通过 执行 render 函数,将 后台返回的数据 绘制在页面中
function render() {
document.querySelector("#app").innerHTML = ` //拿到人家写好的div
<h1>${model.content}</h1> //在div绘制到h1标签
`;
}
// 页面刷新, 要执行一次 render()
render();
</script>
<script>
// 思考2:若 model 的数据发生改变,如何 将改变后的数据,更新至 视图(页面)中
// ->再执行一次 render 函数,(render 函数的 作用:根据 model 绘制页面)
const model ={// 注: model 表示数据(data)
content:'数据被改变...'
</script>
<div id="app'>
<h1>${model.content}</h1>
</div>
//思考:上述]S操作缺点是什么?
->数据被改变了,需要 人工/手动 执行 render 函数。
- ->不能自动执行,所以 非常麻烦。
// 理想状态,应该怎样?
//-> 数据被改变,自动 执行 render 函数;
-> 上述的自动化的过程,即数据的响应式(数据驱动视图)
MVVM 架构模式(Vue 实现 数据响应式 的 设计模式)
M,Moder就是数据
V,View就是render()函数当中html代码就是view
VM,(ViewModer)就是vue
MVVM 其实是指三部分:
M 指的是:Model层是数据模型,即用来存储后端返回的数据;
V 指的是:View层 是视图层(即浏览器页面),展示Model后端数据层的数据,
VM 指的是:ViewModel(视图模型),其同时监测Model层和Vew层,只要一方发生变化,
则VM便会自动更改另一方、最终使两方的内容保持一致。
特性:
1,数据驱动视图
好处:当Model层发生数据变化时,页面会自动重新渲染。开发人员只维护好数据的变化,页面结构被VM会自动渲染出来。
2,双向数据绑定
举个栗子:当视图中有<input />若其值发生变化,则 vm 会自动把最新的值取出来,更新到数据。
好处:开发人员不再需要手动操作DOM元素,来获取表单元索输入的最新值;is数据的变化,会被自动染到页面
Vue.js 是一个提供了 MVVM 风格的双向数据绑定的 Javascript 库,专注于View 层。
它的核心是 MVVM 中的 VM,也就是 ViewModel.
VewModel负责连接 Vew 和 Model,保证视图和数据的一致性,这种轻量级的架构让前端开发更加高效、便捷。
04-vue介绍
简介:
Vue 是一个国产框架,
之前所学的JQuery库、Bootstrap,基本都诞生于国外。像Vue这种优秀的国产框架少之又少
它的作者是国内大神一尤雨溪。
这人学的是艺术设计,并非科班出身,
Vue (读音 /vju:/,类似于 giew)是一套用于构建用户界面的渐进式框架(一点加功能/不一定都下载全家桶)。与其它大型框架不同的是,vue 被设计为可以自底向上逐层应用。Vue 的核心库只关注视图层,不仅易于上手,还便于与第三方库或既有项目整合。另一方面,当与现代化的工具链以及各种支持类库结合使用时,Vue 也完全能够为复杂的单页应用提供驱动。
兼容性:Vue 不支持 IE8,及以下版本,因为 Vue 使用了 IE8 无法模拟的 ECMAScript5 特性。但它支持所有兼容ECMAScript 5 的浏览器。
IE:它是一个用来下载其他浏览器的好工具
市场地位
Vue.js 是前端的主流框架之一,和Angular.js、React.js 一起,并成为前端三大主流框架!
React 和 Vue 有许多相似之处,它们都有:
使用 Virtual DOM
提供了 嗞应式(Reactive) 和 组件化(Composable)的视图组件
将注意力集中保持在核心库,而将其他功能如路由和全局状态管理交给相关的库。
Vue.js的优点:
1.体积小,压缩后只有33kb
2.更高的运行效率,基于虚拟dom原理。
一种可以预先通过JavaScript进行各种计算,把最终的DOM操作计算出来并优化的技术,由于这个DOM操作属于预处理操作,并没有真实的操作DOM,所以叫做虚拟DOM。
3.双向数据绑定原理。
让开发者不用再去操作dom对象,把更多精力投入到业务逻辑上
4.生态丰富、学习成本低。
市面上成熟、稳重的基于vue.js的UI框架、常用组件多。
基于以上原因,Vue.is对初学者友好,容易上手。国内中小企业用的较多
vue2和vue3
Virtual DOM - 虚拟DOM
-> vue 和 react 都有 虚拟DOM
vue 现在有两个 大的版本:
vue2
和
vue3
vue3 几乎兼容 vue2;
我们节奏是 先讲 vue2,再讲 vue3。
Vue2 的编程范式(风格):典型够 面向对象-->new 构造函数()
Vue3 的编程范式(风格):面向对象 + 面向函数
05-vue初体验
Vue引用方式
- 方式一:直接CDN引入
以选择引入开发环境版本还是生产环境版本
<!-- 开发环境版本,包含了有帮助的命令行警告-->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<!--生产环境版本,优化了尺寸和速度 -->
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
- 方式二:下载并引入(==初学者推荐==)
开发环境: https://v2.cn.vuejs.org/js/vue.js
生产环境: https://v2.cn.vuejs.org/js/vue.min.js (min是最小的版本)
Vue 使用
<!--
MVVM -
Model -> 数据层 -> data 中的属性,是「数据层」
View -> 视图层 -> <div id="app"> 内部的 代码,被称为「视图层」
VM -> 可以认为 VM就是 vue 的实例对象。
-->
Vue.js 的html代码写法,是一个允许采用简洁的 模板语法 来声明式地将数据渲染进 DOM 的系统
<!-- View 层 -->
<!-- 注意: vue 写 html 代码, 有一个特性 - 双花括号 - {{ JS代码 }}-->
<!-- content 即 data 对象属性的 content -->
<div id="app
h1>{{content}}</h1> //就是将后端数据渲染到vue提供的页面
</div>
<!-- vue层 -->
可以写 vue 代码
console.log(Vue);
el DOM元素 #app 是DOM元素的id
model数据
data 中的属性,会被直接挂载到 vm模型 中,称为 vm模型的一个属性
<body>
<!-- View 层 -->
<div id="app">//渲染点
<h1>{{content}}</h1>
</div>
</body>
</html>
<!-- vue层 -->
<script src="./vue.js"></script>
<script>
const vm = new Vue({//创建vm
el: "#app", //挂载点
data: {// model数据挂载
content: "欢迎来到页面",
},
});
</script>
el: "#app", // 将 vue 的代码 生效的「挂载点」
0607-vue模板语法+常见指令
- 开发者工具
在使用 Vue 时,我们推荐在你的浏览器上安装 Vue Devtools
它允许你在一个更友好的界面中审査和调试 Vue 应用
安装chrome插件的方式:
https://juejin.cn/post/6966106927990308872#Volar VSCode插件
模板语法
Vue.js 使用了基于 HTML的模板语法 ->“Mustache”语法,胡须-被俗称为「大胡子」
模板语法的作用: new Vue 下很多 JS 数据可以直接在 模板语法中被使用->如 data 中的属性,且 模板语法中的数据具有响应性。
数据绑定最常见的形式就是使用“Mustache"语法(双大括号) 的文本插值:
<div id="app"
{{ message }}
</div>
<div id="app"
{{content}} - {{message}} //挂载到
</div>
const vm = new Vue({//VM
el: "#app", // VM挂载
data: {//数据
content: "欢迎来到页面",
message: "Hello Vue!",
},
});
{ } 可以放什么?
- data 中的 任意数据类型
- 数组
- 对象
- 表达式
什么是 表达式?
["a", "b", "c"].map(d => d + '1')
<body>
<div id="app">
<h1>{{content}} - {{message}}</h1>
<p>数组:{{arr}}</p>
<p>对象:{{obj}}</p>
<p>表达式 - 数组的map方法:{{arr.map(d => d + '1')}}</p>
<p>数字相加的表达式 {{11 + 22}}</p>
</div>
</body>
</html>
<script src="./vue.js"></script>
<script>
const vm = new Vue({
el: "#app",
data: {
content: "欢迎来到页面",
message: "Hello Vue!",
arr: ["a", "b", "c"],
obj: {
name: "姓名",
age: 33,
},
},
});
</script>
指令语法
// 概念约定
标签的属性:属性名、 标签的属性值 分别的英文 和 简写
<div title="xxx">
title 被称为:「属性名」
英文 和 简写: attributr
attrName
'xxx’ 被称为:「属性值」
英文 和 简写: attrValue
</div>
vue中定义好的一些以"v-"开头+具体的名称的 属性,这些属性都有特定的功能。
- 说明
指令加在标签,在Vue中凡是以 v-开头的通通都叫做指令,加上就会有特定的功能。
- 常见用法
<div v-xx></div>
<div v-xx='表达式 或 data中的属性'></div>
<div v-xx:yy='表达式'> </div>
- 注意
指令分:自定义指令和内置指令(Vue自带)
内置指令: Vue自带 的,能直接使用的 指令
自定义指令: 就是用户自己定义的。扩展功能
下述列举 常用的 内置指令:
文本绑定
v-html、v-text
v-html、v-text
双大括号会将数据解释为普通文本,而非HTML代码。为了输出真正的 HTML,需要用到v-html
<p>Using mustaches: f{ rawHtml }}</p>
<p>Using v-html directive: <span v-html="rawHtml"></span></p>
<!-- v-text -->
<p>Using v-text directive: <span v-text="rawHtml"></span></p>
<!-- 注: {{}} 需要被 vue 解析,所以 刷新的 瞬间 `{{}}` 会闪现,因为 vue 还没将 {{}} 解析完成 -->
<!-- 注:v-cloak 作用:解决 刷新时的 闪现问题 -->
<!-- v-pre 的作用:组织 vue 解析 大胡子中的 表达式 -->
<!-- v-html 其作用 等价于 `innerHTML` -->
<!-- v-text 其作用 等价于 `innerText` -->
v-cloak
cloak:[kleuk]笼罩,覆盖;隐藏,掩饰的意思
用于隐藏尚未完成编译的 DOM 模板。{}
当使用直接在 DOM 中书写的模板时,可能会出现一种叫做“未编译模板闪现”的情况:用户可能先看到的是还没编译完成的双大括号标签,直到挂载的组件将它们替换为实际渲染的内容。
v-cloak 会保留在所绑定的元素上,直到相关组件实例被挂载后才移除。配合像[v-cloak]{display:none } 这样的 CSS 规则,它可以在组件编译完毕前隐藏原始模板。
<style>
[v-cloak]{
display: none;
}
</style>
<!-- 直到编译完成前,`<div>' 将不可见-->
<div v-cloak>
{{ message }}
</div>
v-pre
元素内具有 v-pre,所有 Vue 模板语法按原样渲染(不解析)。
<div v-pre{{ rawHTML }}</div>
<style>
[v-cloak] {
display: none;
}
</style>
</head>
<body>
<div id="app">
<h1 v-cloak>{{content}} - {{message}}</h1>
<h1 v-pre>{{content}} - {{message}}</h1>
<div v-html="rawHtml"></div>
<div v-text="rawHtml"></div>
</div>
</body>
</html>
<script src="./vue.js"></script>
<script>
const vm = new Vue({
el: "#app",
data: {
content: "后台登录页面",
message: "Hello Vue!",
rawHtml: `<p>我是 字符串的 p 文本</p>`,
},
});
</script>
08+09-class+style属性绑定
写法 | 适用情况 | 示例 |
---|---|---|
字符串 | 绑定单个 class | :class="'active'" |
对象 | 绑定多个 class(动态) | :class="{ active: isActive, 'text-danger': hasError }" |
数组 | 绑定多个 class(混合) | :class="['active', 'text-danger']" |
对象(style) | 绑定多个样式(动态) | :style="{ color: textColor, fontSize: fontSize + 'px' }" |
数组(style) | 组合多个样式对象 | :style="[baseStyle, additionalStyle]" |
为什么绑定?
绑定(v-bind
)的作用就是让 HTML 里的 class
或 style
变得 动态可变,而不是固定不变的
这个绑定其实很简单,就是根据原生的html css js各种标签写法。在前面加个冒号: 和语法填充就可以了。
1. 如果不用 v-bind
,只能手写固定的 class
和 style
html
<div class="active" style="color: red;">Hello Vue</div>
这种方式是 固定的,无法根据数据的变化自动修改。
2. 用 v-bind
,可以根据数据自动修改 class
或 style
vue
<div :class="{ active: isActive }" :style="{ color: textColor }">Hello Vue</div>
js
data() {
return {
isActive: false,
textColor: 'blue'
};
}
如果 isActive
是 false
,那么 class="active"
不会被添加,颜色也会变成 blue
。
如果 isActive = true
,Vue 就会自动给 div
加上 class="active"
,让样式生效。
实际应用场景
动态高亮选中项
vue
<li v-for="item in items" :key="item.id" :class="{ active: selectedItem === item }">
{{ item.name }}
</li>
当 selectedItem
变化时,对应的 li
会自动加上 active
这个 class
,比如点击时变色。
- 切换暗黑模式
vue
<div :class="{ darkMode: isDark }">切换模式</div>
<button @click="isDark = !isDark">切换</button>
当 isDark = true
时,class="darkMode"
会被加上,页面样式会变暗。
- 根据状态改变颜色
vue
<div :style="{ color: isError ? 'red' : 'green' }">状态信息</div>
总结
如果 class
和 style
是固定的,你可以直接写在 HTML 里,但如果需要根据数据变化,就要用 v-bind
来绑定,让 Vue 自动控制样式,减少手写 CSS 的麻烦。
这样写的代码更灵活,维护起来也更简单!💡
属性绑定- v-bind
思考: 若 给标签内的 属性值 也能像`{{ 表达式 }}`一样,具有响应性,岂不美哉..
->而 v-bind:attrName-"表达式”就是 为了 实现 标签属性的 响应性的
v-bind
(简写为:
)可以用于绑定class
和style
,并支持对象数组计算属性等不同写法- a标签举例:<a href='xxxxxxx'>百度一下</a>
<div id="app">
<a v-bind:href="link">{{title}}</a>
</div>
<script>
new Vue({
el:'#app',
data: {
link: "http://mww.baidu.com',
title:'百度一下',
}
})
</script>
</head>
<body>
<div id="app">
<!-- 注: 使用 `v-bind` 指定,可以使得 attrValue 也能使用「表达式」 -->
<a v-bind:href="link">{{title}}</a>
<h1 :title="title">{{title}}</h1>
</div>
</body>
</html>
<script src="./vue.js"></script>
<script>
const vm = new Vue({
el: "#app", // 将 vue 的代码 生效的「挂载点」
data: {
link: "http://www.baidu.com",
title: "百度一下",
},
});
</script>
动态绑定class属性
操作元素的 class 列表和联样式是数据绑定的一个常见需求。
但字符串拼接 class 和 style,操作麻烦且容易出错
因此,在将v-bind 用于 class 和 style 时,Vue.js 做了专门的增强。
表达式结果的类型除了字符串之外,还可以是对象或数组
Vue 允许动态绑定 class
,可以使用字符串、对象或数组的形式。
(1)字符串写法
<div :class="'active'">Hello Vue</div>
相当于:
<div class="active">Hello Vue</div>
(2)对象写法
<div :class="{ active: isActive, 'text-danger': hasError }">Hello Vue</div>
如果 isActive
为 true
,则 class="active"
; 如果 hasError
为 true
,则 class="text-danger"
(3)数组写法
<div :class="['active', 'text-danger']">Hello Vue</div>
或者:
<div :class="['active', { 'text-danger': hasError }]">Hello Vue</div>
当 hasError
为 true
时,会额外添加 text-danger
。
<style>
.box {
width: 100px;
height: 100px;
background-color: pink;
}
.bold {
font-weight: 900;
}
</style>
<div id="app">
<!-- 注意:在vue 当中 静态class和动态绑定class可以同时存在 -->
<div class="" v-bind:class="{box:flag}">对象方式</div>
<!-- 简写: -->
<div class="bold" :class="{box:flag}">对象方式</div>
<!--第二种:数组方式 active:是个变量,它的值是类名-->
<div v-bind:class="[active, {bold: flag}]">数组方式</div>
</div>
注意:
==>在vue 当中 静态class和 动态绑定clas 可以同时存在==
注意:在vue 当中 静态class和动态绑定class可以同时存在-->
<div class="title" v-bind:class="{box:flag,size:3>2}">对象方式</div>
动态绑定style属性
- 对象语法
v-bind:style 的对象语法十分直观--看着非常像 CSS,但其实是一个JavaScript对象。
CSS property 名可以
用驼峰式(cameICase)或短横线分隔(kebab-case,记得用引号括起来) 来命名:
v-bind:style
允许动态绑定内联样式,可以使用对象或数组的形式。
(1)对象写法
vue
<div :style="{ color: textColor, fontSize: fontSize + 'px' }">Hello Vue</div>
js
data() {
return {
textColor: 'red',
fontSize: 20
}
}
会被解析为:
html
<div style="color: red; font-size: 20px;">Hello Vue</div>
(2)数组写法
vue
<div :style="[baseStyle, additionalStyle]">Hello Vue</div>
js
data() {
return {
baseStyle: { color: 'blue', fontSize: '18px' },
additionalStyle: { backgroundColor: 'yellow' }
}
}
最终渲染:
html
<div style="color: blue; font-size: 18px; background-color: yellow;">Hello Vue</div>
(3)自动加前缀
Vue 会自动为某些 CSS 属性添加浏览器前缀:
vue
<div :style="{ transform: 'rotate(30deg)' }"></div>
Vue 会自动添加 -webkit-transform
、-ms-transform
等前缀以兼容不同浏览器。
结合 computed
计算属性
如果 class
或 style
需要根据更复杂的逻辑计算,可以使用 computed
:
vue
<template>
<div :class="classObject" :style="styleObject">Hello Vue</div>
</template>
<script>
export default {
data() {
return {
isActive: true,
hasError: false,
textColor: 'green',
fontSize: '16px'
};
},
computed: {
classObject() {
return {
active: this.isActive,
'text-danger': this.hasError
};
},
styleObject() {
return {
color: this.textColor,
fontSize: this.fontSize
};
}
}
};
</script>
讲
<div v-bind:style_"{ color: activeColor, fontSize: fontSize + 'px’ }"></div>
data:{
activeColor: 'red'
fontSize: 30
}
- 数组语法
v-bind:style 的数组语法==可以将多个样式对象==应用到同一个元素上:
<div v-bind:style="[baseStyles, overridingstyles]"></div>
<body>
<div id="app">
<div v-bind:style="{ color: 'red', fontSize }">对象写法</div>
<div :style="[baseStyles, overridingStyles]">数组写法</div>
</div>
</body>
</html>
<script src="./vue.js"></script>
<script>
const vm = new Vue({
el: "#app", // 将 vue 的代码 生效的「挂载点」
data: {
fontSize: "100px",
baseStyles: {
color: "blue",
fontSize:300
},
overridingStyles: {
background: "black",
color: "pink", //覆盖
},
},
});
</script>