推荐安装 VScode 中的 Vue 插件
-
Vue 3 Snippets https://marketplace.visualstudio.com/items?itemName=hollowtree.vue-snippets
-
Vetur https://marketplace.visualstudio.com/items?itemName=octref.vetur
vue优势:MVVM 在svue程序员不需要操作DOM。只需要维护数据即可
不建议在vue中安装jquery
day1
安装在项目中webpack
以下命令在终端运行,
安装webpack 两包相关:npm install webpack@5.42.1 webpack-cli@4.7.2-D
安装webpack-dev-server
在项目中安装以下命令:npm install webpack-dev-server@3.11.2-D
安装babel-loader 相关的包
安装以下命令对应的依赖包:npm i babel-loader@8.2.2@babel/core@7.14.6@babel/plugin-proposal-decorators@7.14.5-D
day2什么是 vue
- 构建用户界面
- 用 vue 往 html 填写页面上的数据非常方便
- 框架
- 框架是现成的解决方案,程序员只能遵守框架规范,编写自己的业务功能!
- 要学习 vue,就是在学习 vue 框架中规定的用法!
- vue 指令,组件(是的 UI 路由、Vuex、vue 组件库
- 只有掌握了以上老师列出的内容,才能开发 vue 项目能力!
vue 的两个特性
-
数据驱动视图:
- 数据的变化自动更新
- 好处:只要程序员维护数据,页面结构就会被维护 vue 自动渲染!
-
双向数据绑定:
在网页中,form 表单负责,Ajax 负责。
- js 数据的变化会自动渲染到页面上
- 当页面上表单收集的数据发生变化时,它将被改变 vue 自动获取并更新 js 数据中
注:数据驱动视图和双向数据绑定的基本原理是 MVVM(Mode 数据源、View 视图、ViewModel 就是 vue 的实例)
vue 指令
1. 内容渲染指令
v-text
指令的缺点:它将覆盖元素的原始内容!{ { }}
插值表达式:最常用于实际开发,只是内容的占位符,不会覆盖原内容!v-html
指令的作用:可以把带有标签的字符串,渲染成真正的 HTML 内容!
2. 属性绑定指令
注:插值表达式只能用于元素不能用于元素中!
-
在 vue 中,可用
v-bind:
指令是元素属性的动态绑定值; -
简写是英文的
:
-
在使用 v-bind 在属性绑定期间,如果绑定内容需要动态拼接,则应在字符串外包裹单引号,如:
<div :title="'box' index">这是一个 div</div>
3. 事件绑定
-
v-on:
简写是@
-
语法格式如下:
<button @click="add"></button> methods: { add() { // 若需修改方法 data 可以通过中数据 this 访问到 this.count = 1 } }
-
$event
应用场景:默认事件对象 e 如果被覆盖,可以手动传输一个 $event。例如:<button @click="add(3, $event)"></button> methods: { add(n, e) { // 若需修改方法 data 可以通过中数据 this 访问到 this.count = 1 } }
.prevent阻止默认行为例如:阻止a 连接的跳转、阻止表单的提交等)
.stop阻止事件冒泡.capture以捕获模式触发当前的事件处理函数.once绑定的事件只触发1次
.self只有在event.target是当前元素自身时触发事件处理函数
-
事件修饰符:
-
.prevent
<a @click.prevent="xxx">链接</a>
-
.stop
<button @click.stop="xxx">按钮</button>
-
4. v-model 指令
- input 输入框
- type=“radio”
- type=“checkbox”
- type=“xxxx”
- textarea
- select
.number自动将用户的输入值转为数值类型
<input v-model.number="age" />
.trim自动过滤用户输入的首尾空白字符
<input v-model.trim="msg" />
.lazy在“change”时而非“input”时更新
<input v-model.lazy="msg" />
5. 条件渲染指令
v-show
的原理是:动态为元素添加或移除display: none
样式,来实现元素的显示和隐藏- 如果要频繁的切换元素的显示状态,用 v-show 性能会更好
v-if
的原理是:每次动态创建或移除元素,实现元素的显示和隐藏- 如果刚进入页面的时候,某些元素默认不需要被展示,而且后期这个元素很可能也不需要被展示出来,此时 v-if 性能更好
在实际开发中,绝大多数情况,不用考虑性能问题,直接使用 v-if 就好了!!!
v-if 指令在使用的时候,有两种方式:
-
直接给定一个布尔值 true 或 false
<p v-if="true">被 v-if 控制的元素</p>
-
给 v-if 提供一个判断条件,根据判断的结果是 true 或 false,来控制元素的显示和隐藏
<p v-if="type === 'A'">良好</p>
<div v-if="type === 'A'">优秀</div>
<div v-else-if="type === 'B'">良好</div>
<div v-else-if="type === 'C'">一般</div>
<div v-else>差</div>
6 列表渲染
items 是待循环的数组
item 是被循环的每一项
v-for 指令还支持一个可选的第二个参数,即当前项的索引。语法格式为(item,index)in items
<div id="app">
<!-- table-bordered边框 table-hover放上变色 table-striped不同行变色-->
<table class="table table-bordered table-hover table-striped">
<thead>
<th>索引</th>
<th>Id</th>
<th>姓名</th>
</thead>
<tbody>
<!-- 官方建议:只要用到了 v-for 指令,那么一定要绑定一个 :key 属性 -->
<!-- 而且,尽量把 id 作为 key 的值 -->
<!-- 官方对 key 的值类型,是有要求的:字符串或数字类型 -->
<!-- key 的值是千万不能重复的,否则会终端报错:Duplicate keys detected -->
<tr v-for="(item, index) in list" :key="item.id">
<td>{
{ index }}</td>
<td>{
{ item.id }}</td>
<td>{
{ item.name }}</td>
</tr>
</tbody>
</table>
</div>
lab for属性
<input type="checkbox" id="cb1">
<label for="cb1">男</label>
<hr>
<input type="checkbox" id="cb2">
<label for="cb2">女</label>
day3
过滤器
过滤器的注意点
-
要定义到 filters 节点下,
-
在过滤器函数中,
-
在过滤器的形参中,可以获取到“管道符”前面待处理的那个值
-
如果全局过滤器和私有过滤器名字一致,此时按照“”,调用的是”私有过滤器“
-
<body> <div id="app"> <p>message 的值是:{ { message | capi }}</p> </div> <script src="./lib/vue-2.6.12.js"></script> <script> const vm = new Vue({ el: '#app', data: { message: 'hello vue.js' }, // 过滤器函数,必须被定义到 filters 节点之下 // 过滤器本质上是函数 filters: { // 注意:过滤器函数形参中的 val,永远都是“管道符”前面的那个值 capi(val) { // 字符串有 charAt 方法,这个方法接收索引值,表示从字符串中把索引对应的字符,获取出来 // val.charAt(0) const first = val.charAt(0).toUpperCase() // 字符串的 slice 方法,可以截取字符串,从指定索引往后截取 const other = val.slice(1) // 强调:过滤器中,一定要有一个返回值 return first + other } } }) </script> </body>
定义全局过滤器,不用定义到filter里面
// 使用 Vue.filter() 定义全局过滤器 Vue.filter('capi', function (str) { const first = str.charAt(0).toUpperCase() const other = str.slice(1) return first + other + '~~~' })
watch 侦听器
侦听器的格式
- 方法格式的侦听器
- 缺点1:无法在刚进入页面的时候,自动触发!!!
- 缺点2:如果侦听的是一个对象,如果对象中的属性发生了变化,不会触发侦听器!!!
- 对象格式的侦听器
- 好处1:可以通过 选项,让侦听器自动触发!!!
- 好处2:可以通过 选项,让侦听器深度监听对象中每个属性的变化!!!
普通侦听器
<body>
<div id="app">
<input type="text" v-model="username">
</div>
<script src="./lib/vue-2.6.12.js"></script>
<script src="./lib/jquery-v3.6.0.js"></script>
<script>
const vm = new Vue({
el: '#app',
data: {
username: 'admin'
},
// 所有的侦听器,都应该被定义到 watch 节点下
watch: {
// 侦听器本质上是一个函数,要监视哪个数据的变化,就把数据名作为方法名即可
// 新值在前,旧值在后
username(newVal) {
if (newVal === '') return
// 1. 调用 jQuery 中的 Ajax 发起请求,判断 newVal 是否被占用!!!
$.get('https://www.escook.cn/api/finduser/' + newVal, function (result) {
console.log(result)
})
}
}
})
</script>
</body>
立即调用
默认情况下,组件在初次加载完毕后不会调用watch 侦听器。如果想让watch 侦听器立即被调用,则需要使用immediate选项。示例代码如下:
watch:{
username:{
//handler是固定写法,表示当username的值变化时,自动调用handler处理函数
handler:asyncfunction(newVal){
if(newVal==='')return
const{
data:res}=awaitaxios.get('https://www.escook.cn/api/finduser/'+newVal)
console.log(res)
},
//表示页面初次渲染好之后,就立即触发当前的watch侦听器
immediate:true
}
}
对象侦听器
watch: {
// 定义对象格式的侦听器
username: {
// 侦听器的处理函数
handler(newVal, oldVal) {
console.log(newVal, oldVal)
},
// immediate 选项的默认值是 false
// immediate 的作用是:控制侦听器是否自动触发一次!
immediate: true
}
}
深度侦听
watch: {
/* info: { handler(newVal) { console.log(newVal) }, // 开启深度监听,只要对象中任何一个属性变化了,都会触发“对象的侦听器” deep: true }*/
// 如果要侦听的是对象的子属性的变化,则必须包裹一层单引号
'info.username'(newVal) {
console.log(newVal)
}
}
计算属性
计算属性指的是通过一系列运算之后,最终得到一个属性值。这个动态计算出来的属性值可以被模板结构或methods 方法使用。
特点:
- 定义的时候,要被定义为“方法”
- 在使用计算属性的时候,当普通的属性使用即可
好处:
- 实现了代码的复用
- 只要计算属性中依赖的数据源变化了,则计算属性会自动重新求值!
所有的计算属性,都要定义到 computed 节点之下
<body>
<div id="app">
<div>
<span>R:</span>
<input type="text" v-model.number="r">
</div>
<div>
<span>G:</span>
<input type="text" v-model.number="g">
</div>
<div>
<span>B:</span>
<input type="text" v-model.number="b">
</div>
<hr>
<!-- 专门用户呈现颜色的 div 盒子 -->
<!-- 在属性身上,: 代表 v-bind: 属性绑定 -->
<!-- :style 代表动态绑定一个样式对象,它的值是一个 {
} 样式对象 -->
<!-- 当前的样式对象中,只包含 backgroundColor 背景颜色 -->
<div class="box" :style="{ backgroundColor: rgb }">
{
{
rgb }}
</div>
<button @click="show">按钮</button>
</div>
<script>
// 创建 Vue 实例,得到 ViewModel
var vm = new Vue({
el: '#app',
data: {
// 红色
r: 0,
// 绿色
g: 0,
// 蓝色
b: 0
},
methods: {
// 点击按钮,在终端显示最新的颜色
show() {
console.log(this.rgb)
}
},
// 所有的计算属性,都要定义到 computed 节点之下
// 计算属性在定义的时候,要定义成“方法格式”
computed: {
// rgb 作为一个计算属性,被定义成了方法格式,
// 最终,在这个方法中,要返回一个生成好的 rgb(x,x,x) 的字符串
rgb() {
return `rgb(${
this.r}, ${
this.g}, ${
this.b})`
}
}
});
console.log(vm)
</script>
</body>
axios
axios 是一个专注于网络请求的库!
axios 的基本使用
axios() axios.get() axios.post() axios.delete() axios.put()
发起 GET 请求:
axios({
// 请求方式
method: 'GET',
// 请求的地址
url: 'http://www.liulongbin.top:3006/api/getbooks',
// URL 中的查询参数
params: {
id: 1
}
}).then(function (result) {
console.log(result)
})
发起 POST 请求:
document.querySelector('#btnPost').addEventListener('click', async function () {
// 如果调用某个方法的返回值是 Promise 实例,则前面可以添加 await!
// await 只能用在被 async “修饰”的方法中
//{data}解构赋值,只要返回的data数据 {data : res}结构赋值重新赋值res=data
const {
data: res } = await axios({
method: 'POST',
url: 'http://www.liulongbin.top:3006/api/post',
//请求体参数
data: {
name: 'zs',
age: 20
}
})
console.log(res)
})
直接请求
document.querySelector('#btnGET').addEventListener('click', async function () {
/* axios.get('url地址', { // GET 参数 params: {} }) */
const {
data: res } = await axios.get('http://www.liulongbin.top:3006/api/getbooks', {
params: {
id: 1 }
})
console.log(res)
})
document.querySelector('#btnPOST').addEventListener('click', async function () {
// axios.post('url', { /* POST 请求体数据 */ })
const {
data: res } = await axios.post('http://www.liulongbin.top:3006/api/post', {
name: 'zs', gender: '女' })
console.log(res)
})
vue-cli 的使用
https://cli.vuejs.org/zh/
使用 npm install -g @vue/cli 命令,即可方便的把它安装到自己的电脑上,cd到项目文件下 npm run serve 运行项目
单页面应用程序(英文名:Single Page Application)简称SPA,顾名思义,指的是一个Web 网站中只有唯一的一个HTML 页面,所有的功能与交互都在这唯一的一个页面内完成
-
在终端下运行如下的命令,创建指定名称的项目:
vue cerate 项目的名称
-
vue 项目中 src 目录的构成:
assets 文件夹:存放项目中用到的静态资源文件,例如:css 样式表、图片资源 components 文件夹:程序员封装的、可复用的组件,都要放到 components 目录下 main.js 是项目的入口文件。整个项目的运行,要先执行 main.js App.vue 是项目的根组件。
工作原理
在工程化的项目中,vue 要做的事情很单纯:通过main.js 把App.vue 渲染到index.html 的指定区域中
①App.vue 用来编写待渲染的模板结构
②index.html 中需要预留一个el 区域
③main.js 把App.vue 渲染到了index.html 所预留的区域中
vue 组件
组件化开发指的是:根据封装的思想,把页面上可重用的UI 结构封装为组件,从而方便项目的开发和维护。
- vue 组件的三个组成部分
template-> 组件的模板结构
script-> 组件的JavaScript 行为
style-> 组件的样式
- template 是vue 提供的容器标签,只起到包裹性质的作用,它不会被渲染为真正的DOM 元素template 中只能包含唯一的根节点
总结
export default{
// 所有的变量,都应该被定义到 data 节点下
data() {
return{
}
}
// 所有的侦听器,都应该被定义到 watch 节点下
watch: {
}
// 所有的过滤器,都应该被定义到 filters 节点下
filters: {
}
// 所有的函数,都应该被定义到 methods 节点下
method: {
}
// 所有的计算属性,都应该被定义到 computed 节点下
computed: {
}
}
day4/day5
vue组件
组件使用
在根组件(一般App.vue作为根组件)里面导入其他子组件
-
使用import 语法导入需要的组件
import Left from '@/components/Left.vue' import Right from '@/components/Right.vue' import Test from '@/components/Test.vue' //组件目录
-
使用components节点注册组件
export default { // 2. 注册组件 components: { Left, Right, Test } }
-
以标签形式使用刚才注册的组件
<Left></Left> <Right></Right>
通过components 注册的是私有子组件例如:
在组件A的components 节点下,注册了组件F。则组件F 只能用在组件A 中;不能被用在组件C 中。
注册全局组件
在vue 项目的main.js 入口文件中,通过Vue.component() 方法
// 导入需要被全局注册的那个组件
import Count from '@/components/Count.vue'
//参数1:字符串格式,表示组件的“注册名称”
//参数2:需要被全局注册的那个组件
Vue.component('MyCount',Count)