内容的视频链接点击此处可进入
这套笔记是按照视频和视频笔记总结的笔记,主要是方便vue的学习或温习,基本抛弃css样式的添加,专注于vue的使用。
利用表达式
进行插值,渲染到页面中
(表达式
:是可以被求值的代码,JS引擎会将其计算出一个结果)
作用:设置元素的 innerHTML
语法:v-html = "表达式 "
key作用:
给元素添加的唯一标识,便于Vue进行列表项的正确排序复用。
注意点:
<template>
<div>
<div v-html="htmlContent">div>
<div v-show="showElement">这是一个可显示的元素div>
<div v-if="condition">条件为真时显示这个div>
<div v-else>条件为假时显示这个div>
<button @click="handleClick">点击我button>
<a :href="link">点击跳转a>
<ul>
<li v-for="(item, index) in items" :key="index">{{ item }}li>
ul>
<input v-model="message" placeholder="输入消息">
<p>您输入的消息是: {{ message }}p>
div>
template>
<script>
export default {
data() {
return {
htmlContent: '这是一段HTML内容',
showElement: true,
condition: true,
link: 'https://www.example.com',
items: ['项1', '项2', '项3'],
message: ''
};
},
methods: {
handleClick() {
alert('按钮被点击了!');
}
}
};
script>
列表渲染 / 删除功能 / 添加功能 / 底部统计 / 清空
功能总结:
① 列表渲染:
v-for
key
的设置 {{ }}
插值表达式
② 删除功能
v-on
调用传参 filter
过滤 覆盖修改原数组
③ 添加功能
v-model
绑定 unshift
修改原数组添加
④ 底部统计 和 清空
数组.length
累计长度
覆盖数组清空列表
v-show
控制隐藏
通过 .
指明一些指令 后缀,不同 后缀 封装了不同的处理操作 → 简化代码
① 按键修饰符
@keyup.enter → 键盘回车监听
② v-model修饰符
v-model.trim → 去除首尾空格
v-model.number → 转数字
③ 事件修饰符
@事件名.stop → 阻止冒泡
@事件名.prevent → 阻止默认行为
为了方便开发者进行样式控制, Vue 扩展了 v-bind 的语法,可以针对 class 类名
和 style 行内样式
进行控制 。
语法 :class = “对象/数组”
① 对象 → 键就是类名,值是布尔值。如果值为 true,有这个类,否则没有这个类
<div class="box" :class="{ 类名1: 布尔值, 类名2: 布尔值 }">div>
适用场景:一个类名,来回切换
② 数组 → 数组中所有的类,都会添加到盒子上,本质就是一个 class 列表
v-bind 对于样式控制的增强 - 操作class
<div class="box" :class="[ 类名1, 类名2, 类名3 ]">div>
适用场景:批量添加或删除类 e.g.
:class="['pink', 'big']"
语法 :style = “样式对象”
<div class="box" :style="{ CSS属性名1: CSS属性值, CSS属性名2: CSS属性值 }">div>
适用场景:某个具体属性的动态设置
常见的表单元素都可以用 v-model 绑定关联 → 快速 获取 或 设置 表单元素的值
它会根据 控件类型 自动选取 正确的方法 来更新元素
输入框 input:text→ value
文本域 textarea→ value
复选框 input:checkbox→ checked
单选框 input:radio→ checked
下拉菜单 select→ value
…
<template>
<div>
<h2>部分 1: 指令修饰符h2>
<button @click.once="handleClick">点击一次button>
<p v-show="showElement">这个元素通过 v-show 显示p>
<input v-model.trim="inputText" placeholder="去除输入内容两边的空格" />
<h2>部分 2: v-bind 对于样式控制的增强 - 操作classh2>
<div :class="{ active: isActive, error: hasError }">样式由v-bind:class动态绑定div>
<h2>部分 3: v-bind 对于样式控制的增强 - 操作styleh2>
<div :style="dynamicStyles">样式由v-bind:style动态绑定div>
<h2>部分 4: v-model应用于其他表单元素h2>
<input type="checkbox" v-model="isChecked" /> 是否选中: {{ isChecked }}
div>
template>
<script>
export default {
data() {
return {
// 部分 1: 指令修饰符
inputText: '',
showElement: true,
// 部分 2: v-bind 对于样式控制的增强 - 操作class
isActive: true,
hasError: false,
// 部分 3: v-bind 对于样式控制的增强 - 操作style
dynamicStyles: {
color: 'blue',
fontSize: '20px'
},
// 部分 4: v-model应用于其他表单元素
isChecked: false
};
},
methods: {
// 部分 1: 指令修饰符
handleClick() {
alert('按钮被点击了!');
}
}
};
script>
<style>
/* 部分 2: v-bind 对于样式控制的增强 - 操作class */
.active {
background-color: lightgreen;
}
.error {
color: red;
font-weight: bold;
}
style>
概念:基于现有的数据,计算出来的新属性。 依赖的数据变化,自动重新计算。
语法:
① 声明在 computed
配置项中,一个计算属性对应一个函数
② 使用起来和普通属性一样使用 {{ 计算属性名 }}
计算属性 → 可以将一段 求值的代码 进行封装
computed 计算属性:
作用:封装了一段对于数据的处理,求得一个结果。
语法:
① 写在 computed
配置项中
② 作为属性,直接使用 → this.计算属性
{{ 计算属性 }}
缓存特性(提升性能):
计算属性会对计算出来的结果缓存,再次使用直接读取缓存,
依赖项变化了,会自动重新计算 → 并再次缓存
methods 方法:
作用:给实例提供一个方法,调用以处理业务逻辑。
语法:
① 写在 methods
配置项中
② 作为方法,需要调用 → this.方法名( )
{{ 方法名() }}
@事件名="方法名"
计算属性默认的简写,只能读取访问,不能 “修改”。
如果要 “修改” → 需要写计算属性的完整写法。
作用:监视数据变化,执行一些 业务逻辑 或 异步操作。
语法:
① 简单写法 → 简单类型数据,直接监视
② 完整写法 → 添加额外配置项
<template>
<div>
<input v-model="inputText" placeholder="输入内容" />
<p>翻译结果: {{ translatedText }}p>
div>
template>
<script>
export default {
data() {
return {
inputText: '',
translatedText: ''
};
},
watch: {
inputText(newText) {
// 在输入内容变化时触发翻译操作
this.translatedText = this.translate(newText);
}
},
methods: {
translate(text) {
// 实现翻译逻辑的函数
// 这里可以调用翻译服务或实现自定义翻译逻辑
// 返回翻译后的文本
return text.toUpperCase(); // 示例:将输入的文本转为大写
}
}
};
script>
② 完整写法 → 添加额外配置项
(1) deep: true 对复杂类型深度监视
(2) immediate: true 初始化立刻执行一次handler方法
<template>
<div>
<input v-model="inputText" placeholder="输入内容" />
<select v-model="selectedLanguage">
<option value="en">英语option>
<option value="fr">法语option>
<option value="es">西班牙语option>
select>
<p>翻译结果: {{ translatedText }}p>
div>
template>
<script>
export default {
data() {
return {
inputText: '',
selectedLanguage: 'en', // 默认语言为英语
translatedText: ''
};
},
watch: {
inputText(newText) {
// 在输入内容或语言选择变化时触发翻译操作
this.translatedText = this.translate(newText, this.selectedLanguage);
},
selectedLanguage(newLanguage) {
// 在语言选择变化时触发翻译操作
this.translatedText = this.translate(this.inputText, newLanguage);
}
},
methods: {
translate(text, language) {
// 实现翻译逻辑的函数
// 根据选择的语言调用翻译服务或实现自定义翻译逻辑
// 返回翻译后的文本
// 这里需要根据language参数选择不同的翻译方式
return text.toUpperCase() + ' (' + language + ')'; // 示例:将输入的文本转为大写,并附加语言标识
}
}
};
script>
<template>
<div>
<input v-model="inputText" placeholder="输入内容" />
<select v-model="selectedLanguage">
<option value="en">英语option>
<option value="fr">法语option>
<option value="es">西班牙语option>
select>
<p>默认文本: {{ defaultText }}p>
<p>翻译结果: {{ translatedText }}p>
div>
template>
<script>
export default {
data() {
return {
inputText: '',
selectedLanguage: 'en', // 默认语言为英语
defaultText: 'Hello, World!', // 默认文本
translatedText: ''
};
},
watch: {
inputText(newText) {
// 在输入内容或语言选择变化时触发翻译操作
this.translatedText = this.translate(newText, this.selectedLanguage);
},
selectedLanguage(newLanguage) {
// 在语言选择变化时触发翻译操作
this.translatedText = this.translate(this.inputText, newLanguage);
}
},
mounted() {
// 在页面加载后立即触发翻译操作
this.translatedText = this.translate(this.defaultText, this.selectedLanguage);
},
methods: {
translate(text, language) {
// 实现翻译逻辑的函数
// 根据选择的语言调用翻译服务或实现自定义翻译逻辑
// 返回翻译后的文本
// 这里需要根据language参数选择不同的翻译方式
return text.toUpperCase() + ' (' + language + ')'; // 示例:将输入的文本转为大写,并附加语言标识
}
}
};
script>
渲染 / 删除 / 修改数量 / 全选反选 / 统计总价 / 持久化
<template>
<div class="app-container">
<div class="banner-box"><img src="http://autumnfish.cn/static/fruit.jpg" alt="" />div>
<div class="breadcrumb">
<span>span> /
<span>购物车span>
div>
<div class="main" v-if="fruitList.length > 0">
<div class="table">
<div class="thead">
<div class="tr">
<div class="th">选中div>
<div class="th th-pic">图片div>
<div class="th">单价div>
<div class="th num-th">个数div>
<div class="th">小计div>
<div class="th">操作div>
div>
div>
<div class="tbody">
<div v-for="(item, index) in fruitList" :key="item.id" class="tr" :class="{ active: item.isChecked }">
<div class="td"><input type="checkbox" v-model="item.isChecked" />div>
<div class="td"><img :src="item.icon" alt="" />div>
<div class="td">{{ item.price }}div>
<div class="td">
<div class="my-input-number">
<button :disabled="item.num <= 1" class="decrease" @click="sub(item.id)"> - button>
<span class="my-input__inner">{{ item.num }}span>
<button class="increase" @click="add(item.id)"> + button>
div>
div>
<div class="td">{{ item.num * item.price }}div>
<div class="td"><button @click="del(item.id)">删除button>div>
div>
div>
div>
<div class="bottom">
<label class="check-all">
<input type="checkbox" v-model="isAll" />
全选
label>
<div class="right-box">
<span class="price-box">总价 : ¥ <span class="price">{{ totalPrice }}span>span>
<button class="pay">结算( {{ totalCount }} )button>
div>
div>
div>
<div class="empty" v-else>空空如也div>
div>
template>
<script>
export default {
data() {
return {
fruitList: [
{
id: 1,
icon: 'http://autumnfish.cn/static/火龙果.png',
isChecked: true,
num: 2,
price: 6,
},
{
id: 2,
icon: 'http://autumnfish.cn/static/荔枝.png',
isChecked: false,
num: 7,
price: 20,
},
{
id: 3,
icon: 'http://autumnfish.cn/static/榴莲.png',
isChecked: false,
num: 3,
price: 40,
},
{
id: 4,
icon: 'http://autumnfish.cn/static/鸭梨.png',
isChecked: true,
num: 10,
price: 3,
},
{
id: 5,
icon: 'http://autumnfish.cn/static/樱桃.png',
isChecked: false,
num: 20,
price: 34,
},
],
};
},
computed: {
isAll: {
get() {
return this.fruitList.every(item => item.isChecked);
},
set(value) {
this.fruitList.forEach(item => (item.isChecked = value));
},
},
totalCount() {
return this.fruitList.reduce((sum, item) => (item.isChecked ? sum + item.num : sum), 0);
},
totalPrice() {
return this.fruitList.reduce((sum, item) => (item.isChecked ? sum + item.num * item.price : sum), 0);
},
},
methods: {
del(id) {
this.fruitList = this.fruitList.filter(item => item.id !== id);
},
add(id) {
const fruit = this.fruitList.find(item => item.id === id);
fruit.num++;
},
sub(id) {
const fruit = this.fruitList.find(item => item.id === id);
if (fruit.num > 1) {
fruit.num--;
}
},
},
};
script>
<style scoped>
/* 样式放在这里 */
@import "../css/inputnumber.css";
@import "../css/index.css";
style>
Vue生命周期:一个Vue实例从 创建 到 销毁 的整个过程。
生命周期四个阶段:① 创建 ② 挂载 ③ 更新 ④ 销毁
Vue生命周期过程中,会自动运行一些函数,被称为【生命周期钩子】→ 让开发者可以在【特定阶段】运行自己的代码。
基本介绍:
Vue CLI 是 Vue 官方提供的一个全局命令工具。
可以帮助我们快速创建一个开发 Vue 项目的标准化基础架子。【集成了 webpack 配置】
使用步骤:
① 组件化:一个页面可以拆分成一个个组件,每个组件有着自己独立的结构、样式、行为。
好处:便于维护,利于复用 → 提升开发效率。
组件分类:普通组件、根组件。
② 根组件:整个应用最上层的组件,包裹所有普通小组件。
一个根组件App.vue,包含的三个部分:
1.template 结构 (只能有一个根节点)
2.style 样式 (style标签,lang="less"
开启less功能,需要装包 less 和 less-loader )yarn add less less-loader
3.script 行为
组件注册的两种方式:
步骤:
① 创建 .vue 文件 (三个组成部分)
② 在使用的组件内导入并注册
使用:
◆ 当成 html 标签使用 <组件名>组件名>
注意:
◆ 组件名规范 → 大驼峰命名法,如:HmHeader
步骤:
① 创建 .vue 文件 (三个组成部分)
② main.js 中进行全局注册
使用:
◆ 当成 html 标签使用 <组件名>组件名>
注意:
◆ 组件名规范 → 大驼峰命名法,如:HmHeader
技巧:
◆ 一般都用局部注册,如果发现确实是通用组件,再定义到全局。
拆分模块-局部注册 / 结构样式完善 / 拆分组件 – 全局注册
默认情况:写在组件中的样式会 全局生效 → 因此很容易造成多个组件之间的样式冲突问题。
scoped原理?
一个组件的 data 选项必须是一个函数。→ 保证每个组件实例,维护独立的一份数据对象。
每次创建新的组件实例,都会新执行一次 data 函数,得到一个新对象。
组件通信, 就是指 组件与组件 之间的数据传递。
⚫ 组件的数据是独立的,无法直接访问其他组件的数据。
⚫ 想用其他组件的数据 → 组件通信
组件关系分类:
Prop 定义:组件上 注册的一些 自定义属性
Prop 作用:向子组件传递数据
特点:
⚫ 可以 传递 任意数量 的prop
⚫ 可以 传递 任意类型 的prop
作用:为组件的 prop 指定验证要求,不符合要求,控制台就会有错误提示 → 帮助开发者,快速发现错误
语法:
① 类型校验
② 非空校验
③ 默认值
④ 自定义校验
共同点:都可以给组件提供数据。
区别:
⚫ data 的数据是自己的 → 随便改
⚫ prop 的数据是外部的 → 不能直接改,要遵循 单向数据流
单向数据流:父级 prop 的数据更新,会向下流动,影响子组件。这个数据流动是单向的。
拆分组件 / 渲染 / 添加 / 删除 / 统计 / 清空 / 持久化
作用:可以实现 子组件 与 父组件数据 的 双向绑定,简化代码
特点:prop属性名,可以自定义,非固定为 value
场景:封装弹框类的基础组件, visible属性 true显示 false隐藏
本质:就是 :属性名 和 @update:属性名 合写