概念
vue是MVVM的框架
MVVM,一种软件架构模式,决定了写代码的方式。
- M:model数据模型(ajax获取到的数据)
- V:view视图(页面)
- VM:ViewModel 视图模型
MVVM通过数据双向绑定
让数据自动地双向同步 不需要操作DOM
- V(修改视图) -> M(数据自动同步)
- M(修改数据) -> V(视图自动同步)
组件化思想
模块化:一个独立的js文件就是一个模块(.js)
组件化:一个组件会包含(HTML+CSS+JS) 把一个完整的页面拆分成多个组件构成。(.vue)
组件 (Component) 是 Vue.js 最强大的功能之一。
在vue中都是组件化开发的,组件化开发就是把一个完整的页面分割成一个一个的小组件。
组件树:
组件优点:
- 容易维护
- 易复用
开发vue
在webpack
环境中开发。
vue-cli的使用
vue-cli
也叫vue脚手架,vue-cli
是vue官方提供的一个全局命令工具,这个命令可以帮助我们快速的创建一个vue项目的基础架子。
全局安装命令
npm i -g @vue/cli
查看版本
vue --version
# OR
vue -V
初始化vue项目
vue create 项目名(不能用中文,路径合法,不要有括号)
选择vue2
或者vue3
启动项目
npm run serve
npm run build
vue.config.js
可以覆盖webpack配置
const { defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({
transpileDependencies: true,
devServer: {
// 自动打开浏览器
open: true,
// 自定义端口
port: 3000,
// 自定义主机名
host: 'localhost'
}
})
目录分析
- public/index.html不用动,提供一个最基础的页面
- src/main.js不用动, 渲染了App.vue组件
- src/App.vue默认有很多的内容,可以全部删除
Vue组件
单文件组件
- template(必须) 影响组件渲染的结构 html
- 只能有一个根元素
- script 逻辑 js
- style 样式 css less scss
- style用于提供组件的样式,默认只能用css
- 可以通过
lang="less"
开启less的功能,需要安装依赖包
// template 代表组件要渲染的结构
<template>
<div id="app">hello,vue's world</div>
</template>
// script 用于提供组件的逻辑代码
<script>
console.log("你好");
</script>
// style 用于提供组件的样式
<style>
h1 {
background-color: green;
}
</style>
插值表达式
vue可以通过data提供数据,注意:data必须是一个**函数**,并且返回一个**对象**
插值表达式, 小胡子语法 mustach语法{{ }}
注意:
(1) 使用的数据在 data 中要存在
(2) 能使用表达式, 但是不能使用 if for
(3) 不能在标签属性中使用。
// 插值表达式
// template 代表组件要渲染的结构
<template>
<div id="app">
<!-- {{}} :展示data中的数据 -->
<div>姓名:{{ name }}</div>
<div>年龄:{{ age - 4 }}</div>
<!-- 不能使用if for等语句,能用表达式 -->
<div>是否成年:{{ age >= 18 ? "Y" : "N" }}</div>
<div>性别:{{ user.gender }}</div>
<!-- 不能在属性中用 -->
<!-- <div title="{{money}}"></div> -->
</div>
</template>
// script 用于提供组件的逻辑代码,需要默认导出一个对象
<script>
export default {
// 通过data提供组件数据,data必须是函数,返回一个对象
data() {
return {
name: "Tricia",
age: 22,
money: 1000000,
user: {
gender: "女",
hobby: "swim",
},
};
},
};
</script>
// style 用于提供组件的样式
<style>
h1 {
background-color: green;
}
</style>
Vue指令
vue指令, 实质上就是特殊的 html 标签属性, 特点: v- 开头
每个 v- 开头的指令, 都有着自己独立的功能, 将来vue解析时, 会根据不同的指令提供不同的功能
v-bind指令
- 描述:插值表达式不能用在html的属性上,如果想要动态的设置html元素的属性,需要使用v-bind指令
- 作用:动态的设置html的属性
- 语法:
v-bind:title="msg"
- 简写:
:title="msg"
// 插值表达式
// template 代表组件要渲染的结构
<template>
<div id="app">
<h1>v-bind的使用</h1>
<h3 v-bind:title="msg">我是三级标题</h3>
<!-- 简写 -->
<h3 :title="msg">我是另一个三级标题</h3>
<!-- 注意 -->
<!-- 只是跳转到location -->
<a href="location">百度</a>
<br />
<!-- 跳转到百度 -->
<a :href="location">baidu</a>
</div>
</template>
// script 用于提供组件的逻辑代码,需要默认导出一个对象
<script>
export default {
// 通过data提供组件数据,data必须是函数,返回一个对象
data() {
return {
msg: "h3",
location: "https://www.baidu.com/",
};
},
};
</script>
// style 用于提供组件的样式
<style>
</style>
v-on指令
注册事件
- v-on:事件名=“要执行的少量代码"
- v-on:事件名=“methods中的函数名"
- v-on:事件名=“methods中的函数名(实参)"
基本使用
// 插值表达式
// template 代表组件要渲染的结构
<template>
<div id="app">
<h1>v-on的使用</h1>
<div>金钱:{{ money }}</div>
<!-- v-on:事件名="事件函数" -->
<button v-on:click="getMoney">码代码</button>
<!-- 简写 -->
<button @click="getMoney2">种田</button>
</div>
</template>
// script 用于提供组件的逻辑代码,需要默认导出一个对象
<script>
export default {
// 通过data提供组件数据
// data必须是函数,返回一个对象
data() {
return {
money: 10000,
};
},
// methods提供方法
// 在methods提供的所有方法,都可以通过this访问到当前组件
methods: {
getMoney() {
this.money += 10000; // 注意:money是组件的,而不是data的
},
getMoney2() {
this.money += 100; // 注意:money是组件的,而不是data的
},
},
};
</script>
// style 用于提供组件的样式
<style>
h1 {
background-color: green;
}
</style>
三种语法
// 插值表达式
// template 代表组件要渲染的结构
<template>
<div id="app">
<h1>v-on的使用</h1>
<div>金钱:{{ money }}</div>
<button @click="getMoney(10000)">种田</button>
<!-- 如果逻辑足够简单,直接在里面写 -->
<!-- 注意:在template中访问组件的数据,不用this -->
<button @click="money += 100000">卖烤肠</button>
<button @click="money -= 3000000">买大house</button>
</div>
</template>
// script 用于提供组件的逻辑代码,需要默认导出一个对象
<script>
export default {
// 通过data提供组件数据
// data必须是函数,返回一个对象
data() {
return {
money: 10000,
};
},
// methods提供方法
// 在methods提供的所有方法,都可以通过this访问到当前组件
methods: {
getMoney(m) {
this.money += m; // 注意:money是组件的,而不是data的
},
},
};
</script>
// style 用于提供组件的样式
<style>
h1 {
background-color: green;
}
</style>
阻止浏览器默认行为
阻止默认行为 e.preventDefault()
vue中获取事件对象
(1) 没有传参, 通过形参接收 e
(2) 传参了, 通过$event指代事件对象 e
// 插值表达式
// template 代表组件要渲染的结构
<template>
<div id="app">
<h1>阻止浏览器默认行为</h1>
<a @click="fn" href="http://www.baidu.com">百度</a>
<a @click="fn1(100, $event)" href="http://www.baidu.com">百度2</a>
</div>
</template>
// script 用于提供组件的逻辑代码,需要默认导出一个对象
<script>
export default {
// methods提供方法
// 在methods提供的所有方法,都可以通过this访问到当前组件
methods: {
fn(e) {
e.preventDefault();
},
fn1(num, e) {
e.preventDefault();
},
},
};
</script>
// style 用于提供组件的样式
<style>
h1 {
background-color: green;
}
</style>
事件修饰符
vue中提供的事件修饰符
.prevent 阻止默认行为
.stop 阻止冒泡
// 插值表达式 // template 代表组件要渲染的结构
<template>
<div id="app">
<h1>事件修饰符</h1>
<div class="father" @click="fn2()">
<!-- stop阻止事件冒泡 prevent 阻止浏览器默认行为 -->
<div class="son" @click.stop="fn1()">100</div>
</div>
</div>
</template>
// script 用于提供组件的逻辑代码,需要默认导出一个对象
<script>
export default {
// methods提供方法
// 在methods提供的所有方法,都可以通过this访问到当前组件
methods: {
fn1() {
console.log('son被点击了')
},
fn2() {
console.log('father被点击了')
}
}
}
</script>
// style 用于提供组件的样式
<style>
h1 {
background-color: green;
}
.father {
width: 200px;
height: 200px;
border: 1px solid black;
}
.son {
width: 100px;
height: 100px;
border: 1px solid rebeccapurple;
}
</style>
按键修饰符
@keyup.按键
// 插值表达式 // template 代表组件要渲染的结构
<template>
<div id="app">
<input class="one" type="text" @keyup.space="fn1" />
<hr />
<input class="two" type="text" @keyup.enter="fn2" />
</div>
</template>
// script 用于提供组件的逻辑代码,需要默认导出一个对象
<script>
export default {
// methods提供方法
// 在methods提供的所有方法,都可以通过this访问到当前组件
methods: {
fn1() {
let one = document.querySelector('.one')
console.log(one.value)
},
fn2() {
let two = document.querySelector('.two')
console.log(two.value)
}
}
}
</script>
// style 用于提供组件的样式
<style>
.one {
background-color: pink;
}
.two {
background-color: blue;
}
</style>
v-if 和 v-show
v-show 和 v-if 功能: 控制盒子的显示隐藏
-
v-show
语法: v-show=“布尔值” (true显示, false隐藏)
原理: 实质是在控制元素的 css 样式,
display: none;
-
v-if
语法: v-if=“布尔值” (true显示, false隐藏)
原理: 实质是在动态的
创建
或者删除
元素节点
应用场景:
-
如果是频繁的切换显示隐藏, 用 v-show
v-if, 频繁切换会大量的创建和删除元素, 消耗性能
-
如果是不用频繁切换, 要么显示, 要么隐藏的情况, 适合于用 v-if
v-if 是惰性的, 如果初始值为 false, 那么这些元素就直接不创建了, 节省一些初始渲染开销
// 插值表达式 // template 代表组件要渲染的结构
<template>
<div id="app">
<!-- 实质是在动态的创建 或者 删除元素节点 -->
<div class="one" v-if="false"></div>
<!-- 实质是在控制元素的 css 样式, display: none; -->
<div class="two" v-show="false"></div>
</div>
</template>
// script 用于提供组件的逻辑代码,需要默认导出一个对象
<script>
export default {
// methods提供方法
// 在methods提供的所有方法,都可以通过this访问到当前组件
}
</script>
// style 用于提供组件的样式
<style>
.one {
width: 100px;
height: 100px;
background-color: pink;
}
.two {
width: 100px;
height: 100px;
background-color: blue;
}
</style>
v-if v-else 和 v-else-if
表示
- if
- else if
- else
// 插值表达式 // template 代表组件要渲染的结构
<template>
<div id="app">
<h1 v-if="isLogin">尊敬的超级vip, 你好</h1>
<h1 v-else>你谁呀, 赶紧登陆~</h1>
<hr />
<h1 v-if="age >= 60">60岁以上, 广场舞</h1>
<h1 v-else-if="age >= 30">30岁以上, 搓麻将</h1>
<h1 v-else-if="age >= 20">20岁以上, 蹦迪</h1>
<h1 v-else>20岁以下, 唱跳rap篮球</h1>
</div>
</template>
// script 用于提供组件的逻辑代码,需要默认导出一个对象
<script>
export default {
data() {
return {
isLogin: true,
age: 39
}
}
}
</script>
// style 用于提供组件的样式
<style>
.one {
width: 100px;
height: 100px;
background-color: pink;
}
.two {
width: 100px;
height: 100px;
background-color: blue;
}
</style>
v-model
给表单元素或者组件使用, 双向数据绑定.
-
数据变化了, 视图会跟着变
-
视图变化了, 数据要跟着变
输入框内容变化了(监听用户的输入, 监听input事件), 数据要跟着变
在表单使用v-model
// 插值表达式 // template 代表组件要渲染的结构
<template>
<div id="app">
<input type="text" v-model.lazy="msg" @input="fn()" />
</div>
</template>
// script 用于提供组件的逻辑代码,需要默认导出一个对象
<script>
export default {
data() {
return {
msg: 11
}
},
methods: {
fn() {
console.log(this.msg)
}
}
}
</script>
// style 用于提供组件的样式
<style></style>
在组件使用v-model
注意:如果在组件使用v-model,子组件内部接收必须使用value,子传父发布的自定义事件必须是input
在子组件
<template>
<div style="border: 1px solid #333; padding: 10px">
我是子组件 ---- {{ value }}
<button @click="changeStr">改数据</button>
</div>
</template>
<script>
export default {
props: {
value: {
type: String,
default: ''
}
},
methods: {
changeStr() {
// 子传父
this.$emit('input', '嘿嘿')
}
}
}
</script>
<style>
</style>
在父组件
<template>
<div class="salarys-container">
<div class="app-container">
<h2>
{{ msg }}
</h2>
<MySon v-model="msg" />
</div>
</div>
</template>
<script>
import MySon from './MySon.vue'
export default {
name: 'Salarys',
components: { MySon },
data() {
return {
msg: 'haha'
}
}
}
</script>
<style>
</style>
v-model 修饰符
-
number
如果想自动将用户的输入值, 用parseFloat转成数字类型, ,可以给
v-model
添加number
修饰符:<input v-model.number="age" type="number">
如果这个值如果这个值无法转数字,则会返回原始的值。
-
trim
如果要自动过滤用户输入的首尾空白字符,可以给
v-model
添加trim
修饰符:<input v-model.trim="msg">
-
lazy
在
change
时而非input
时更新,可以给v-model
添加lazy
修饰符:<input v-model.lazy="msg">
v-text 和 v-html
// 插值表达式 // template 代表组件要渲染的结构
<template>
<div id="app">
<!-- 不解析标签 -->
<div v-text="str"></div>
<!-- 解析标签 -->
<div v-html="str"></div>
</div>
</template>
// script 用于提供组件的逻辑代码,需要默认导出一个对象
<script>
export default {
data() {
return {
str: '<h2>一个字符串</h2>'
}
}
}
</script>
// style 用于提供组件的样式
<style></style>
v-for
v-for 作用: 遍历对象和数组
注意
- 第一项是值 第二项是下标
- 需要提供key,且key唯一
遍历数组
// 插值表达式 // template 代表组件要渲染的结构
<template>
<div id="app">
<ul>
<li v-for="item in arr" :key="item">{{ item }}</li>
<li v-for="(item, index) in arr" :key="item">{{ index }},{{ item }}</li>
</ul>
</div>
</template>
// script 用于提供组件的逻辑代码,需要默认导出一个对象
<script>
export default {
data() {
return {
arr: ['赵', '钱', '孙', '李']
}
}
}
</script>
// style 用于提供组件的样式
<style></style>
遍历对象和数字
// 插值表达式 // template 代表组件要渲染的结构
<template>
<div id="app">
<ul>
<!-- 遍历对象 -->
<li v-for="(value, key) in obj" :key="key">{{ key }},{{ value }}</li>
<!-- 遍历数字 -->
<li v-for="(item, index) in 10" :key="item">{{ index }},{{ item }}</li>
</ul>
</div>
</template>
// script 用于提供组件的逻辑代码,需要默认导出一个对象
<script>
export default {
data() {
return {
obj: {
name: 'Tricia',
age: 18
}
}
}
}
</script>
// style 用于提供组件的样式
<style></style>