1. vue基本概念
尤雨溪:Vue.js的创建者
- 2014年2月,Vue.js正式发布
- 2015年10月27日,正式发布1.0.0
- 2016年4月27日,发布2.0的预览版本
Vue:渐进式JavaScript框架
声明式渲染→组件系统→客户端路由→集中式状态管理→项目构建
官网地址: cn.vuejs.org/ (作者: 尤雨溪)
- 易用:熟悉HTML、CSS、JavaScript知识后,可快速上手Vue
- 灵活:在一个库和一套完整框架之间自如伸缩
- 高效:20kB运行大小,超快虚拟 DOM
Vue渐进式: Vue从基础开始, 会循序渐进向前学习, 如下知识点可能你现在不明白, 但是学完整个vue回过头来看, 会很有帮助
1.1 Vue是什么?
- Vue是一个javaScript渐进式框架
1.2 渐进式的理解
- 渐进式就是按需逐渐集成功能使用
1.3 库和框架的理解
- 1.库:本质上是一些方法的集合。每次调用方法,实现一个特定的功能。 工具箱
- 如:moment axios
- 框架:是一套完整的解决方案。框架实现了大部分的功能,我们需要按照框架的规则写代码。 如:vue react angular ... (虽然需要遵循规则,但是带来了高效)
vue是什么?
一个渐进式的javascript框架
什么是渐进式呢?
逐渐增强, 通过逐步学习,集成更多的功能
什么是库和框架呢?
库是方法的集合
框架是一整套完整的项目解决方案
1.4 Vue是一个MVVM的框架 (MVVM:一种软件架构模式)
- M:model数据模型(ajax获取到的数据)
- V:view视图(页面)
- VM:ViewModel 视图模型 (操作视图+模型)
- MVVM通过 数据双向绑定 让数据自动地双向同步
- V(修改视图) -> M(数据自动同步)
- M(修改数据) -> V(视图自动同步)
- 之前的思想,原生 dom驱动。无论修改什么页面内容,先找对象,操作dom。
- 现在的思想,vue 数据驱动。想更新视图,直接操作数据即可。数据变化,视图自动更新
什么是 MVVM ?
一种软件架构模式,决定了写代码的方式。
M、V、VM 分别是什么?
M:model 数据模型
V:view 视图
VM: viewModel 视图模型
原生 和 vue 修改视图的思想分别是什么?
原生:dom驱动,修改视图,操作dom
vue:数据驱动,修改数据,操作数据即可
1.5 vue组件化思想
- 组件化:一个组件会包含(HTML+CSS+JS) ,完整的页面可以拆分成多个组件。
- 组件化的优点:
- 1.容易维护
- 2.便于复用(HTML+CSS+JS)
1. 什么是组件化?
将一个页面,拆分成一个个小组件的过程,就是组件化。
每个组件包含自己的 html+css+js
2. 组件化的好处是什么?
便于维护,便于复用
2. Vue基本使用
2.1 开发方式
传统开发模式:基于html/css/js文件开发Vue
工程化(脚手架)开发方式:在webpack环境中开发Vue,这是最推荐, 企业常用的方式
3.@vue/cli脚手架
3.1 @vue/cli和脚手架介绍
@vue/cli 也叫 vue脚手架, @vue/cli 是vue官方提供的一个全局命令工具 这个命令可以帮助我们快速的创建一个vue项目的基础架子。
脚手架: 为了保证各施工过程顺利进行而搭设的工作平台
vue脚手架的好处:
- 开箱即用
- 0配置webpack
- babel支持
- css, less支持
- 开发服务器支持
3.2 vue脚手架的基本使用:
- 全局安装:
-
npm i @vue/cli -g 或 yarn global add @vue/cli
- 查看vue版本:
-
vue --version
- 初始化一个vue项目:
-
vue create 项目名(不能用中文)
- 启动项目, 打包项目:
-
yarn serve -
yarn build
3.3 脚手架-创建项目-启动服务
创建脚手架步骤
- 创建项目(注意: 项目名不能带大写字母, 中文和特殊符号)
//vue和create是命令, vuecli-demo是自己的文件夹名
vue create vuecli-demo
// 1. 基于 交互式命令行 的方式,创建 新版 vue 项目
vue create my-project
// 2. 基于 图形化界面 的方式,创建 新版 vue 项目
vue ui
// 3. 基于 2.x 的旧模板,创建 旧版 vue 项目
npm install -g @vue/cli-init
vue init webpack my-project
复制代码
- 选择模板 可以上下箭头选择, 回车确定, 弄错了ctrl+c从第1步来
3. 选择包管理器
4. 等待下载脚手架项目, 需要的依赖包
5. 终端切换脚手架项目下, 启动内置的==webpack热更新开发服务器
cd vuecil-demo
yarn serve
# 或 npm run serve
3.4 脚手架-目录分析
脚手架里主要文件和作用
- node_modules - 都是下载的包
- public/index.html - 浏览器运行的网页
- src/main.js - webpack打包的入口
- src/App.vue - Vue页面入口
- package.json - 项目描述信息
3.5 脚手架-代码和结构分析
一切从main.js开始, 到index.html结束
main.js和App.vue以及index.html作用和关系?
- main.js - 项目打包入口 - Vue初始化
- App.vue - Vue页面入口
- index.html - 浏览器运行的文件
- App.vue => main.js => index.html
3.6 脚手架-自定义配置
1. 通过 package.json 配置项目
// 必须是符合规范的json语法
"vue": {
"devServer": {
"port": "8888",
"open" : true
}
},
复制代码
注意:不推荐使用这种配置方式。因为 package.json 主要用来管理包的配置信息;为了方便维护,推荐将 vue 脚手架相关的配置,单独定义到 vue.config.js 配置文件中。
2. 通过单独的配置文件配置项目
- 在项目的跟目录创建文件 vue.config.js
- 在该文件中进行相关配置,从而覆盖默认配置
// vue.config.js
module.exports = {
devServer: {
port: 8888;
}
}
复制代码
3.8 脚手架-单vue文件
- template里只能有一个根标签
- vue文件-独立模块-作用域互不影响
- style配合scoped属性, 保证样式只针对当前template内标签生效
- vue文件配合webpack, 把他们打包起来插入到index.html
<!-- template必须, 只能有一个根标签, 影响渲染到页面的标签结构 -->
<template>
<div>欢迎使用vue</div>
</template>
<!-- js相关 -->
<script>
export default {
name: 'App'
}
</script>
<!-- 当前组件的样式, 设置scoped, 可以保证样式只对当前页面有效 -->
<style scoped>
</style>
复制代码
小结
1. 单vue文件的好处?
- 独立作用域,不再担心变量重名问题
2. 单vue文件使用注意事项?
- template里只能有一个根标签
3. 单vue文件里标签和样式最后怎么显示到页面?
- webpack打包后, 插入到index.html显示
4. vue插值表达式
4.1 vue如何提供数据
- 通过 data 属性可以提供数据, data属性必须是一个函数
- 这个函数需要返回一个对象,这个对象就代表vue提供的数据
使用插值表达式,可以在模板中渲染数据:
4.2 插值表达式: 小胡子语法 {{ }}
- 作用: 使用 data 中的数据渲染视图(模板)
- 支持基本语法, 支持三元运算符
- 注意点: (1)使用数据在 data 中必须存在 (2)能使用表达式,但是不能使用语句 if for ... (3)不能在标签属性中使用 {{ }} 插值
<template>
<div id="app">
<!-- 插值表达式 -->
<!-- 作用:把内容插入到指定的位置 -->
<!--张三{ 表达式 }} -->
<!-- 表达式中如果有变量,要声明在data函数的返回对象里 -->
<!-- 插值表达式调用函数,函数要声明在data同级的methods对象里 -->
<h1>博仔老师:{{ age >= 18 ? "成年" : "未成年" }}</h1>
<h2>标语:{{ hello() }}</h2>
</div>
</template>
<script>
export default {
name: "App",
data() {
return {
age: 8,
};
},
methods: {
hello() {
return "Hello World!";
},
},
};
</script>
<style lang="less">
</style>
小结
- 插值表达式的作用是什么?
- 使用 data 中的数据渲染视图(模板)
- 插值表达式的注意点是什么?
- (1)使用数据在 data 中必须存在
- (2)能使用表达式,但是不能使用语句 if for ...
- (3)不能在标签属性中使用 {{ }} 插值
4.3 安装vue开发者工具:我们要调试vue应用,需要装插件。
- 直接通过谷歌应用商店安装 需要梯子
- 通过极简插件下载插件,本地拖拽到chrome 扩展程序列表中,安装即可。 chrome.zzzmh.cn/index
打开vue运行的页面,调试工具中Vue栏,即可查看修改数据,进行调试。
5. vue指令
vue指令: 特殊的 html 标签属性, 特点: v- 开头
每个 v- 开头的指令, 都有着自己独立的功能, 将来vue解析时, 会根据不同的指令提供不同的功能
5.1 vue指令-v-bind
- 说明:插值表达式不能用在html的属性上,想要动态的设置html元素属性,需要使用v-bind指令
- 作用: 动态的设置html的标签属性
- 语法: v-bind:属性名="值"
- 简写: :属性名="值"
<template>
<div>
<!-- v-bind是一个指令,指令是一类特殊的标签属性 -->
<!-- 指令都以v-开头 -->
<!-- v-bind作用是给标签绑定属性 -->
<!-- 语法:v-bind:属性名="表达式" -->
<a v-bind:href="url">百度</a>
<br>
<a :href="url">简写百度</a>
</div>
</template>
<script>
export default {
data() {
return {
url: "https://www.baidu.com/",
};
},
};
</script>
<style>
</style>
5.2 vue指令-v-on
- 作用:注册事件
- 语法:
- 1.v-on:事件名=“要执行的少量代码"
- 2.v-on:事件名=“methods中的函数名"
- 3.v-on:事件名=“methods中的函数名(实参)"
- 注意:事件处理函数在methods中提供
- 简写:v-on 可以 简写 成 @
<template>
<div>
<!-- v-on指令,作用:给标签绑定事件 -->
<!-- v-on语法 -->
<!-- 语法1: @事件名="少量代码" -->
<!-- 语法2: @事件名="fn",fn声明在methods对象里 -->
<!-- 语法3:@事件名="fn(100)",函数传参数 -->
<h3>工资:{{ money }}</h3>
<button @click="money = money + 10">涨10块</button>
<button @click="add50">加50</button>
<button @click="addFn(100)">加100</button>
<button @click="addFn(1000)">加1000</button>
</div>
</template>
<script>
export default {
data() {
return {
money: 200,
age: 18,
};
},
methods: {
add50() {
// 函数内使用data里的数据,需要通过this引用
this.money += 50;
},
addFn(param) {
this.money += param;
}
}
};
</script>
<style>
</style>
5.3 vue中获取事件对象(了解)
- vue中获取事件对象:
- (1) 没有传参, 通过形参接收 e
- (2) 传参了, 通过$event指代事件对象 e
<template>
<div>
<a href="https://www.baidu.com" @click="fn">可以跳转</a>
<br>
<a href="https://www.baidu.com" @click="fn2(10, $event)">可以跳转</a>
</div>
</template>
<script>
export default {
methods: {
fn(event) {
event.preventDefault();
console.log('fn调用');
},
fn2(arg, e) {
e.preventDefault();
console.log('fn2调用');
}
}
}
</script>
<style>
</style>
5.4 事件修饰符
事件修饰符:vue提供事件修饰符,可以快速阻止默认行为或阻止冒泡
- .prevent 阻止默认行为, .stop 阻止冒泡
<template>
<div>
<!-- v-on修饰符,作用:增强事件绑定能力 -->
<!-- 语法:@事件名.修饰符="代码" -->
<!-- .prevent修饰符:阻止默认行为 -->
<!-- .stop修饰符,阻止事件冒泡 -->
<a @click.prevent="fn" href="https://www.baidu.com">去百度</a>
<div class="parent" @click="fn2">
父级内容
<div class="child" @click.stop="fn">子级内容</div>
</div>
</div>
</template>
<script>
export default {
methods: {
fn() {
console.log("子级点击");
},
fn2() {
console.log("父级点击");
},
},
};
</script>
<style>
</style>
5.5 按键修饰符
- 在监听键盘事件时,我们经常需要判断详细的按键。可用按键修饰符。
- 需求: 用户输入内容, 回车时, 打印输入的内容。
- @keyup.enter 监听回车键
- @keyup.esc 监听返回键
<template>
<div>
<input type="text" placeholder="请输入用户名">
<br>
<input type="text" placeholder="请输入密码" @keyup.esc="login">
</div>
</template>
<script>
export default {
methods: {
login() {
console.log("调用接口,登录成功");
},
}
}
</script>
<style>
</style>
- vue内置的按键修饰符列表:
- .enter
- .tab
- .delete(捕获"删除"和"退格"键)
- .esc
- .space
- .up
- .down
- .left
- .right
5.6 翻转世界
<template>
<div>
<!-- 字符串拆成数组,string.split("") -->
<!-- "abc".split("") -> ["a", "b", "c"] -->
<!-- 数组倒转方法: array.reverse(),作用是倒转数组 -->
<!-- 数组拼接方法:array.join("") -->
<h1>{{ message }}</h1>
<button @click="reverseWorld">逆转世界</button>
</div>
</template>
<script>
export default {
data() {
return {
message: "Hello, World",
};
},
methods: {
reverseWorld() {
// 第一步,先把message拆分成数组
const array = this.message.split("");
// 第二步,数组倒转过来
// reverse会修改原始数组
array.reverse();
// 第三步,把数组拼接为字符串
this.message = array.join("");
},
},
};
</script>
<style>
</style>
5.7 v-show 和 v-if
功能: 控制盒子的显示隐藏
1. v-show
语法: v-show="布尔值" (true显示, false隐藏)
原理: 实质是在控制元素的 css 样式, `display: none;`
2. v-if
语法: v-if="布尔值" (true显示, false隐藏)
原理: 实质是在动态的创建 或者 删除元素节点
应用场景:
1. 如果是频繁的切换显示隐藏, 用 v-show
(v-show, 只是控制css样式,而v-if, 频繁切换会大量的创建和删除元素, 消耗性能)
2. 如果是不用频繁切换, 要么显示, 要么隐藏的情况, 适合于用 v-if
(v-if 是惰性的, 如果初始值为 false, 那么这些元素就直接不创建了, 节省一些初始渲染开销)
<template>
<div>
<!-- v-show,作用:控制标签显示或者隐藏 -->
<!-- v-show原理,通过控制display样式来显示或者隐藏 -->
<p v-show="age < 18">未成年才能看的内容</p>
<!-- v-if,作用:控制标签显示或者隐藏 -->
<!-- v-if原理,通过创建或者删除标签来显示或者隐藏 -->
<p v-if="age2 >= 18">成年人才能看</p>
</div>
</template>
<script>
export default {
data() {
return {
age: 28,
age2: 8,
};
},
};
</script>
<style>
</style>
5.8 v-if和v-else-if以及v-else
<template>
<div>
<!-- v-if可以和v-else搭配使用,实现if else的条件控制 -->
<!-- v-if和v-else必须是相邻的标签 -->
<p v-if="age < 18">未成年</p>
<p v-else>成年人</p>
<!-- v-if可以和多个v-else-if搭配使用,实现多条件控制 -->
<!-- 这时候,可选使用v-else结尾,表示剩余条件 -->
<h1>发礼品</h1>
<h2 v-if="age < 18">甜甜圈</h2>
<h2 v-else-if="age < 30">快乐水</h2>
<h2 v-else-if="age < 60">冬虫夏草</h2>
<h2 v-else>脑白金</h2>
</div>
</template>
<script>
export default {
data() {
return {
age: 180,
};
},
};
</script>
<style>
</style>
折叠面板
<template>
<div>
<h1>
芙蓉楼送辛渐
<button @click="showPoem = !showPoem">
{{ showPoem === false ? "展开" : "收起" }}
</button>
</h1>
<div v-show="showPoem">
<p>寒雨连江夜入吴</p>
<p>平明送客楚山孤</p>
<p>洛阳亲友如相问</p>
<p>一片冰心在玉壶`</p>
</div>
</div>
</template>
<script>
export default {
data() {
return {
showPoem: true,
};
},
};
</script>
<style>
</style>
5.9 v-model
- 作用:给表单元素使用, 双向数据绑定
- 什么是双向数据绑定?
- 数据变化了, 视图会跟着变
- 视图变化了, 数据要跟着变
- 语法: v-model='值'
<template>
<div>
<!-- v-model作用:实现表单内容和Vue变量的双向绑定 -->
<!-- 语法v-model="变量",变量要声明在data函数的返回对象 -->
<!-- 否则会报错 -->
<input type="text" placeholder="用户名" v-model="username" />
<br />
<input type="text" placeholder="密码" v-model="password" />
<br />
<button @click="login">登录</button>
</div>
</template>
<script>
export default {
data() {
return {
username: "",
password: "",
};
},
methods: {
login() {
// 一般登录是获取用户输入的用户名和密码,发给服务器实现登录
console.log(this.username, this.password);
},
},
};
</script>
<style>
</style>
5.10 v-model修饰符
<template>
<div>
<!-- 用户注册 -->
<input type="text" placeholder="用户名" v-model.trim="user.username" />
<br />
<!-- v-model修饰符,作用:增强v-model的数据绑定 -->
<!-- 语法:v-model.修饰符="变量" -->
<!-- .number修饰符,作用是:把内容转换成数字再赋值给变量 -->
<!-- .trim修饰符作用是:去掉内容首尾的空白符 -->
<!-- .lazy作用:对于input来说,是失去焦点的时候更新数据(change事件触发的时候) -->
<input type="number" placeholder="年龄" v-model.number="user.age" />
<br />
<h1>密码:{{user.password}}</h1>
<input type="text" placeholder="密码" v-model.lazy="user.password" />
<br />
<button @click="login">登录</button>
</div>
</template>
<script>
export default {
data() {
return {
user: {
username: "",
age: "",
password: "",
},
};
},
methods: {
login() {
// 一般登录是获取用户输入的用户名和密码,发给服务器实现登录
console.log(this.user);
},
},
};
</script>
<style>
</style>
5.11 vue指令 - v-model - 处理其他表单元素(了解)
- 例如:
- select
- checkbox
- textarea
- ...
- 注意:v-model 会忽略掉表单元素原本的value, checked等初始值
<template>
<div>
爱好:<select v-model="hobby">
<option value="音乐">音乐</option>
<option value="敲代码">敲代码</option>
<option value="美食">美食</option>
</select>
<h3>{{ hobby }}</h3>
<input type="checkbox" v-model="agree" />
同意该协议才能继续
<br>
<textarea cols="30" rows="10" v-model="content"></textarea>
<h3>{{content}}</h3>
</div>
</template>
<script>
export default {
data() {
return {
hobby: "",
agree: false,
content: "",
};
},
};
</script>
<style>
</style>
5.12 vue指令-v-text和v-html
- 作用:更新元素的innerText/innerHTML
- 语法:
- v-text="值"
- v-html="值"
- 区别:
- v-text 不解析标签
- v-html 解析标签
5.13 Vue指令-v-for
- 作用:可以遍历 数组 或者 对象,用于渲染结构
- 遍历数组语法:
- v-for="item in 数组名"
- v-for="(item, index) in 数组名"
- 遍历对象语法:
- v-for = "(value, key) in 对象名"
- 遍历数字
- v-for = "item in 数字"
v-for遍历数组
<template>
<div>
<ul>
<!-- v-for指令作用:遍历数据,循环生成标签 -->
<!-- 语法: v-for="变量名 in 数据" -->
<!-- 如果数据是数据,怎么获取下标 -->
<!-- v-for="(变量名, 下标名) in 数据" -->
<li v-for="(i, index) in list" :key="i.id">
<h1>排名:{{index + 1}}</h1>
<h1>名字:{{i.name}}</h1>
<h2>年龄:{{i.age}}</h2>
</li>
</ul>
</div>
</template>
<script>
export default {
data() {
return {
list: [
{
id: 3,
name: "五湖",
age: 8,
},
{
id: 1,
name: "叶良辰",
age: 18,
},
{
id: 2,
name: "龙傲天",
age: 20,
},
],
};
},
};
</script>
<style>
</style>
v-for遍历对象和数字
<template>
<div>
<ul>
<!-- v-for遍历对象 -->
<!-- v-for="(值变量, 键变量) in 对象" -->
<li v-for="(value, key) in student" :key="key">
<h3>key: {{ key }}</h3>
<h3>value: {{ value }}</h3>
</li>
</ul>
<!-- 遍历数字 -->
<!-- v-for="item in 数字",从1开始到数字(包含数字) -->
<ul>
<!-- 1到10 -->
<li v-for="item in 10">{{item}}</li>
</ul>
</div>
</template>
<script>
export default {
data() {
return {
student: {
name: "五湖",
age: 18,
gender: "女",
},
};
},
};
</script>
<style>
</style>
6. 虚拟DOM
vue的就地复用策略
思考:数组改变后,DOM是如何更新的呢?
- 什么是 vue 的就地复用策略呢
- 就地复用:Vue会尽可能的就地(同层级,同位置)
- 对比虚拟dom,复用旧dom结构,进行差异化更新。
- 就地复用的好处是什么?
- 可以复用旧的dom结构,更新高效!
明确1:页面dom结构 是一个 树形结构
html 渲染出来的 真实dom树,是个树形结构(复杂)。每个标签,都只是树的某个节点。
明确2: 每个小真实dom节点很复杂
每个标签,虽然只是树形结构的一个小节点,但属性也非常多。=> 遍历真实dom找差异,非常费时!
真实DOM属性过多, 有很多无用的属性 ,无需遍历对比。
如何优化呢?对比属性少的虚拟dom!
6.1 虚拟dom - 是什么
虚拟dom:本质就是 保存节点信息, 描述真实dom的 JS 对象
虚拟dom(一个个js对象):可以用最少的属性结构,描述真实的dom
虚拟dom - 对比更新
面试常问:
虚拟DOM
- 为什么使用虚拟DOM
- 虚拟DOM是内存对象,对比效率高
- 使用虚拟DOM可以对比出DOM变化的部分,只更新变化的部分减少DOM操作,提升性能
7. diff算法
- 策略1:先同层级根元素比较。 => 如果根元素变化,那么不考虑复用,整个dom树删除重建
- 策略1:先同层级根元素比较。 => 如果根元素不变,对比出属性的变化更新,并考虑往下递归复用。
- 策略2:对比同级兄弟元素时,默认按照下标进行对比复用。
diff算法如何比较新旧虚拟DOM的呢?
1. 同层级根元素先比较
(1)如果根元素变了,删除重建dom树
(2)如果根元素没变,对比属性。并考虑往下递归复用。
2. 兄弟元素比较
(1)默认按照下标,进行对比复用
(2)如果设置了key,就会按照相同key的元素进行复用
key的作用 - 无 key 的情况 (按照下标对比)
key的作用 - 有 key 的情况
- 有key的情况:根据diff更新算法,同级兄弟元素,在设置了key后,会让相同key的元素进行对比。
- key的要求:必须是字符串 或者 数字,且要保证唯一性!(标准的key需要指定成 id)
key的作用
- 列表循环加:key="唯一标识",可以标识元素的唯一性,可以更好地区别各个元素。
- key的作用:提高虚拟DOM的对比复用性能
小结
1. 设置 和 不设置 key 有什么区别?
不设置 key, 默认同级兄弟元素 按照下标 进行比较。
设置了key,按照 相同key 的新旧元素比较。
2. key值要求是?
字符串或者数值,唯一不重复
有 id 用 id, 有唯一值用唯一值,实在都没有,才用索引
4. key的好处?
key的作用:提高虚拟DOM的对比复用性能
vue就地复用策略?
对比虚拟dom的差异,就地(同层级,同位置)复用结构
为什么要对比虚拟dom呢? 什么是虚拟dom呢?
真实dom太复杂。虚拟dom就是一个描述真实dom的对象。
diff算法如何比较新旧虚拟DOM?
1 先对比根元素
根元素改变 – 删除当前DOM树重新建
根元素未变 - 对比属性 – 更新属性,并考虑向下递归对比复用
2 同级兄弟元素,对比更新:
无key – 就地按下标更新 / 有key – 按key比较
8. 用 v-bind 动态设置标签的 class 类名
- 语法 :class="对象/数组"
- 对象:如果键值对的值为true,那么就有这个类,否则没有这个类
- 数组:数组中所有的类,都会添加到盒子上
- v-bind 对于类名操作的增强, 注意点 :class 不会影响到原来的 class 属性
<template>
<div>
<!-- 修改样式:style和class -->
<!-- 动态绑定class -->
<!-- 语法, :class="{ 类名: 布尔值, 类名2: 布尔值 }" -->
<!-- 新类不会影响现有的类 -->
<!-- 如果类名有横线,使用单引号包起来 -->
<h1 :class="{ red: isRed, huge: isHuge, 'text-center': true }">
hello world
</h1>
<button @click="isRed = !isRed">变红</button>
<button @click="isHuge = !isHuge">变大</button>
</div>
</template>
<script>
export default {
data() {
return {
isRed: false,
isHuge: false,
};
},
};
</script>
<style>
.red {
color: red;
}
.huge {
font-size: 100px;
}
</style>
9. 用 v-bind 动态设置标签的 style 行内样式
语法 :style="对象/数组"
<template>
<div>
<!-- :style="{ 样式属性名: 样式的值 }" -->
<!-- 如果样式名带横线,有两个选择:1. 小驼峰,例如fontSize;2. 使用引号,'font-size' -->
<!-- 任何场景下,优先使用class,主要是方便复用和维护 -->
<!-- style什么时候用,一般来说样式是不固定的比如接口下发的时候,一般用style绑定 -->
<h1 :style="{ color: textColor }">hello world</h1>
<button @click="textColor = 'red'">变红</button>
<button @click="textColor = 'green'">变成功</button>
</div>
</template>
<script>
export default {
data() {
return {
textColor: '',
}
}
};
</script>
<style>
.huge {
}
.red {
color: red;
}
</style>