1 简介
- VUE 是一种流行的渐进式JavaScript框架,用于构建Web用户界面
- 它具有易学、轻量级、灵活性强、高效率等特点,并且可以与其他库和项目集成
- 是目前最流行的前端框架之一
- VUE-Cli 称为“VUE脚手架”,它是由VUE官方提供的客户端,专门为单页面应用快速搭建的脚手架
- 使用它可以轻松的创建新的应用程序,而且可以自动生成vue和webpack工程模板
2 VUE安装操作
2.1 在cmd窗口创建VUE工程
2.1.1卸载已有的Node.js
- VUE项目创建需要用到Node.js,而Node.js的版本可能会影响最终的项目创建
- 所以我们可以卸载原有的Node.js,安装推荐的版本
- 打开运行窗口(Win+R),输入control
- 打开控制面板,选择"卸载程序"
- 找到Node.js,鼠标右键卸载即可
2.1.2 下载Node.js
下载网址:https://mirrors.tuna.tsinghua.edu.cn/nodejs-release/v16.14.2/node-v16.14.2-x64.msi
2.1.3 安装Node.js
- 一直点击下一步,直至安装结束
- 打开命令窗口(Win+R),输入cmd
- 此安装包会自动配置环境变量,安装完成后,可检查npm命令是否可用
- 输入 npm -v 命令,检查npm是否可用,注意v是小写的
- 如果显示版本就是OK的,这里如果是8.5.0版本也是正确的!
2.1.4 配置npm源
npm(Node Package Manager)是 Node.js 的默认包管理和依赖管理工具
它允许用户轻松地安装、更新和管理 Node.js 应用程序所需的模块(也称为“包”)
- 确认npm命令可用后,就可以配置npm源
- nmp源(即npm仓库,称之为:registry)默认是境外服务器
- 在国外访问速度较慢,通常在初次使用时,应该将npm源更换为国内的服务器地址
- 例如使用 https://registry.npmmirror.com作为npm源
- 使用命令:npm config set registry https://registry.npmmirror.com
- 配置后可以使用get命令查看npm源
npm config get registry
注意:这个命令只能获取到你配置的源,无法检查是否正确!请认真检查url
2.1.5 安装VUE CLI
- 配置好npm源后,就可以安装VUE CLI(VUE脚手架)了,此过程将从仓库服务器中下载VUE Cli,通常耗时30秒至5分钟左右。
命令:npm install -g @vue/cli
只要安装显示的文字中没有出现ERROR就可以,警告(提示更新npm版本或提示某些软件版本偏旧等)都可忽略
注意:无论你使用哪种操作系统,必须保证当前登录的用户具有最高访问权限,例如,在Windows操作系统中,请使用管理员模式的命令提示符,并且,不要使用Power Shell,在Mac OS中,请使用 sudo来执行以上命令。
@vue/cli是Vue官方提供的一个全局模块包(得到vue命令), 此包用于创建脚手架项目
@vue/cli的好处:开箱即用,支持webpack/babel/css/less/开发服务器支持
- 安装完毕后,可以验证一下,命令: vue -V 注意:这里的V是大写的!
可以看到当前的VUE Cli:@vue/cli 5.0.8
2.1.6 创建VUE CLI工程
通常用vue命令来创建VUE CLI工程,并且会将工程创建在执行命令时的位置,所以,可以先进入准备存放项目的文件夹再创建项目
- 建议切换到其他盘,不要在系统盘里存放项目,命令: d:
- 在对应的盘下创建一个文件夹,当做VUE项目的工作空间,命令: mkdir Vue-Workspace
- 进入到刚刚创建好的文件夹,命令: cd Vue-Workspace
- 创建VUE项目,格式:vue create 项目名,命令: vue create vue-project-01
- 下面即将进入创建项目时的各项选项配置,一定要慢,不要连续敲回车,会自动选择下一个选项的默认项!按图示步骤操作即可:
按上下键移动
空格键选中 再按一次取消选中
回车键进入下一项配置,一定要慢!!!不要连续敲回车!!!
依次选中选项:
- Please pick a preset:
- “Manually select features”
- Check the features needed for your project:
- Babel(ES6高级语法向低版本兼容工具)
- Router(路由:进行页面跳转使用的组件)
- Vuex(全局状态管理工具)
- Choose a version of Vue.js that you want to start the project with
- 3.x
- Use history mode for router?
- Y(直接回车)
- Where do you prefer placing config for Babel,ESLint,etc.?
- In package.json
- Save this as a preset for future projects?
- N(直接回车)
如果未出现ERROR字样,通常是创建成功了
- 进入到刚刚创建好的项目,命令:cd vue-project-01
- 运行vue项目,命令:npm run serve
- 按Ctrl+C可以终止项目,出现提示语后输入"Y"即可
2.2 在IDEA中创建VUE工程
2.2.1 IDEA创建-启动-停止VUE工程步骤
- 在IDEA中打开下方的Terminal工具,输入命令
- 首先输入 npm 命令,如图所示,如果提示"不是可运行的程序或批处理文件",需要重启IDEA
- 创建v1项目,命令: vue create v1
- 进入到v1文件夹下,并启动项目
2.2.2 可能出现的问题与解决方案
2.2.3 关于VUE CLI
在使用VUE之前,你需要:
- 在你的电脑上安装Node.js,并配置环境变量
- 在你的电脑上配置npm源,使得它可以更快速、更稳定的下载所需的资源
- 在你的电脑上安装VUE Cli
- 以上操作对于每台电脑都是一次性操作
2.2.4 修改项目启动端口号
默认端口号8080,但此端口号使用频率高,存在被占用的情况,所以我们可以修改端口号:
- 打开package.json配置文件
- 在第6行的位置添加 --port 9090 ,9090就是我们新修改的端口号
- “serve”: “vue-cli-service serve --port 9090”
- 重新启动我们的项目,可以看到端口号已被改成了9090
2.2.5 安装Vue.js插件
- 打开File下的设置Settings,找到插件Plugins,在市场中搜索vue,如果没有安装,点击Install安装
- 安装完毕后可以在Installed中看到已安装的插件
- 点开App.vue文件,如果上面有如下提示,也是需要安装插件
2.2.6 VUE Cli 热部署测试
- VUE Cli工程启动的服务支持热部署
- (热更新,即:当保存对源代码的修改后,会自动重新编译打包并覆盖原本已经启动的服务中的文件)
- 打开App.vue文件,可以在里面添加内容
- 点击项目访问链接可以看到网页内容立即发生改变
Vue脚本架工程启动的服务支持热部署
(热更新,即:当保存对源代码的修改后,会自动重新编译打包并覆盖原本已经启动的服务中的文件)
并没有重启服务的做法,如果在某些场景中需要实现“重启”的效果(例如修改服务端口等),可以先停止服务,然后再次启动服务
2.3 VUE的使用
2.3.1 主页构成
- 默认的主页是由以下3个文件完成显示的:
- /App.vue
- /views/HomeView.vue
- /components/HelloWorld.vue
2.3.2 App.vue代码
router-link类似于a标签,to属性在/router/index.js中有配置
<!--HTML写在template标签中-->
<template>
<h1>热部署测试aaa</h1>
<nav>
<!-- 脚手架工程中的router-link相当于超链接a标签 -->
<!-- 区别:超链接a跳转时页面整体刷新 router-link跳转时页面不会整体刷新,局部刷新 -->
<!-- /相当于根,点Home时url为:http://localhost:9090/ -->
<router-link to="/">Home主页</router-link> |
<!-- 点About时url为:http://localhost:9090/about -->
<router-link to="/about">About关于</router-link> |
<router-link to="/other">其他关于</router-link>
</nav>
<!-- router-view用来表示可变区域 -->
<router-view/>
</template>
<!--CSS写在style标签中-->
<style>
/*public下的index.html中的内容设置样式*/
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
/*让文字不要有锯齿,更平滑*/
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
}
/* 设置上面导航栏的内间距 */
nav {
padding: 30px;
}
/* 设置上面导航栏链接的文字颜色与字重 */
nav a {
font-weight: bold;
color: #2c3e50;
}
/* 设置激活的超链接文字用不同的字体颜色 */
nav a.router-link-exact-active {
color: #42b983;
}
</style>\
2.3.3 HomeView.vue代码
<!--HTML内容写在template标签中-->
<template>
<div class="home">
<!-- logo图片 -->
<img alt="Vue logo" src="../assets/logo.png">
<img alt="Vue logo" src="../assets/logo.png">
<!-- vue自带的自定义的组件HelloWorld 具体:/components/HelloWorld.vue -->
<HelloWorld msg="Welcome to Your Vue.js App欢迎小可爱"/>
</div>
</template>
<!--JavaScript内容写在script标签中-->
<script>
// @ is an alias to /src
// 导入自定义组件HelloWorld后才能使用
import HelloWorld from '@/components/HelloWorld.vue'
export default {
name: 'HomeView',
components: {
HelloWorld
}
}
</script>
2.3.4 index.js代码
- 假如to里写的path是"/",那么就会显示对应component的HomeView.vue中的内容
- 假如to里写的path是"/about",那么就会显示对应component的AboutView.vue中的内容
类似于后端工程在方法上加:
@RequestMapping(“/v1/users/reg”)
localhost:8080/v1/users/reg就会找此方法提供服务
import { createRouter, createWebHistory } from 'vue-router'
//预加载:提前加载(只有这个是预加载)
import HomeView from '../views/HomeView.vue'
const routes = [
{
path: '/',
name: 'home',
component: HomeView
},
{
path: '/about',
name: 'about',
//箭头函数:懒加载,用到了再加载
component: () => import( '../views/AboutView.vue')
},
{
path: '/other',
name: 'other',
//箭头函数:懒加载,用到了再加载
component: () => import( '../views/OtherView.vue')
}
]
const router = createRouter({
history: createWebHistory(process.env.BASE_URL),
routes
})
export default router
2.3.5 新view.vue的创建方式
- 在 v1/src/App.vue中添加新view文件的router-link链接
- 在v1/src/views文件夹下创建一个新的VueComponent(也就是.vue文件)
- 编写新创建好的.vue文件
- template标签中放的是HTML
- style标签中放的是CSS
- script标签中放的是JS
注意:vue3的script开始标签中必须要有setup,否则代码不生效!
- 还需要在v1/src/router/index.js文件中配置路由跳转的路径
- path就是App.vue中router-link标签中to属性的值
- 箭头函数加载的就是对应的.vue文件的路径
- 写完可以启动项目访问:http://localhost:9090/ 进行测试,如果看到了下图所示的内容,则表明配置成功了
3 前端工程分类
前端工程分为单页面架构和多页面架构
- 多页面架构(传统方案):
指工程中存在多个*.html 文件,每一个页面对应一个 html 文件 - 单页面架构(VUE 脚手架工程):
指工程中只有一个 html 页面文件,通过一个 html 页面中的内容改变实现多页面的效果
每个页面至少对应一个*.vue 文件
用户的URL只对应一个页面,我们可以随时替换这个页面的内容,方便更新
每个页面可以由多个部分组成,每个部分都可以按需替换
局部替换的做法,也反向实现了页面某些部分的"复用"
注意:
- html 文件是页面全部内容,vue 文件可能是页面的一个部分,也能是页面的所有内容
- 两种方式对用户体验没有影响,不论哪种方式在用户端是一样的
4 IDEA工具VUE工程初始化
- 确保IDEA中有vue插件
- 通过 IDEA 的 Terminal 工具,在工程的根目录下,执行 vue create 工程名 来创建工程
- 通过 cd 工程名 指令 进入到创建的 vue 工程目录下
- 启动工程: npm run serve
- 停止工程:Ctrl+C 输入 Y 回车
- 修改端口号:在 package.json 文件的第 6 行修改:
"serve": "vue-cli-service serve --port 9090",
5 VUE项目工程结构解析
项目中需要大家关注的主要内容:
- public 文件夹:里面存放静态资源文件,如:图片/视频等
- src/router/index.js:路由配置文件,在里面配置请求地址和 VUE 组件的映射关系
- src/views:在里面创建对应每个页面的*.vue 文件
- App.vue:此组件工程启动后自动挂载到 index.html 页面的组件,可以理解为工程的入口
- main.js:当需要引入其他框架或对框架进行配置时使用此文件
- package.json:修改端口号
6 MVC与MVVM
MVC 设计模式就是将实现前端业务的所有代码划分为三部分
- M: Model 模型 , 对应数据相关代码
- V: View 视图, 对应的是页面标签相关
- C: Controller 控制器, 对应的是将数据显示到页面中的过程代码
MVC 设计模式的弊端: Controller 需要频繁的进行 DOM 相关操作(遍历查找元素),比较浪费资源
MVVM 设计模式就很好的解决了这个问题:
MVVM 设计模式也是将实现前端业务的所有代码划分为三部分
- M: Model 模型 , 对应数据相关代码(数据)
- V: View 视图, 对应的是页面标签相关(页面)
- VM:ViewModel 视图模型,直接将页面元素与变量进行绑定
- 视图模型负责将页面中可能发生改变的元素和某个变量在内存中进行绑定
- 对变量进行监听,当变量发生改变时,会从内存中找到和变量所对应的元素, 让元素进行改动
这样就不用像 MVC 设计模式中通过遍历查找的方式查找元素了,大大提高了执行的效率
7 VUE指令练习
7.1 文本相关指令练习
- const info = ref(“文本相关的内容”); 定义响应式变量,注意需要导入!
- {{变量}} 插值,让此处的文本内容与变量进行绑定
- v-text=“响应式变量名”:将文本内容与变量进行绑定
- v-html=“响应式变量名”:将标签内容与变量进行绑定
- 关于写法:
- 响应式变量的导入语句: import {ref} from “vue”;
- 在JS代码中使用响应式变量: console.log(info.value);
- 箭头函数: const f = (参数列表)=>{方法体}
<template>
<h1>文本相关指令</h1>
<!-- 插值指令:将此处显示文本与变量的值进行绑定,修改变量值,页面文本随之改变 -->
{{info}}
<p>{{info}}</p>
<h3>{{info}}</h3>
<!-- 响应式变量的值也可以拼接 -->
<h1>{{info+'周一好!'}}</h1>
<p v-text="info"></p>
<p v-html="info"></p>
<!-- 给按钮绑定一个点击事件 -->
<button @click="f()">我是按钮</button>
</template>
<script setup>
import {ref} from "vue";
//响应式变量
const info = ref('我是文本666');
const f = () => {//箭头函数 (参数列表)=>{方法体}
info.value = '值<b>更新</b>了!'//在JS中操作响应式变量的值,必须加 .value!!!
}
</script>
<style scoped>
</style>
7.2 属性绑定练习
- v-bind:属性名=“变量名”
- 让元素的 xxx 属性的值与变量值进行绑定
- 可以简写成 :属性名=“变量名”
<template>
<h1>属性绑定练习</h1>
<input type="text" value="kk"> <!--输入框默认值设置为kk-->
<input type="text" value="info"> <!--输入框默认值设置为info-->
<input type="text" v-bind:value="info"> <!--输入框value属性与响应式变量info绑定-->
<input type="text" :value="info"> <!--属性绑定可以简写 去掉前面的v-bind-->
<hr>
<a href="url">超链接1</a>
<a :href="url">超链接2</a>
</template>
<script setup>
import {ref} from "vue";
const info = ref('属性绑定999')
const url = ref('https://www.jd.com')
url.value = 'https://www.baidu.com';
</script>
<style scoped>
</style>
7.3 双向绑定练习
- 双向绑定:页面中的内容发生改变,变量的值也会随之改变
- v-model=“变量名” 除了这个其他都是单向绑定
- 当需要获取用户输入的内容时使用(输入框/单选/多选/下拉选框等)
- 之前 DOM 操作需要先获取 html 元素,再获取 html 元素的值,效率较低
- 现在使用 MVVM 的方式:当页面的值发生改变,变量保存的值也会立即随之改变,可以直接使用
- 双向绑定的数据会实时更新,但注意用户输入也会影响绑定的数据
<template>
<h1>双向绑定指令</h1>
{{info}}
<input type="text" :value="info">
<hr>
<!-- 双向绑定:将页面与下方变量info进行绑定
1)info变量的值会显示在绑定的html元素上
2)页面html元素发生改变,绑定的info变量的值也会随之改变-->
<input type="text" v-model="info">
<h3>登录页面</h3>
<input type="text" placeholder="请输入用户名" v-model="user.username">
<input type="password" placeholder="请输入密码" v-model="user.password">
<br>
性别:
<input type="radio" name="gender" value="1" v-model="user.gender">男
<input type="radio" name="gender" value="0" v-model="user.gender">女
<button @click="f()">登录</button>
</template>
<script setup>
import {ref} from "vue";
const info = ref('测试数据');
const user = ref({username:'tom',password:'123',gender:"0"})
const f = ()=>{
console.log(user.value);
console.log(user.value.username);
console.log(user.value.password);
console.log(user.value.gender);
}
</script>
<style scoped>
</style>
7.4 事件绑定练习
- @click=“f()” 与 v-on:click=“f()” 都是绑定点击事件
- @keydown.enter=“ent()” 表示绑定敲回车事件
<template>
<h1>事件绑定指令</h1>
<!-- 下面两种写法是等价的,我们一般用第1种 -->
<button @click="f()">按钮1</button>
<button v-on:click="f()">按钮2</button>
<h3>回车按下事件</h3>
<input type="text" @keydown.enter="ent()">
</template>
<script setup>
const f = ()=>{
alert('点击了!');
}
const ent = ()=>{
alert('鞋子信息...')
}
</script>
<style scoped>
</style>
7.5 循环指令练习
- v-for=“元素 in 数组” 遍历数组 遍历时会生成当前遍历到的元素
- v-for=“元素 in 数字n” 遍历数组 从1到数字n,步长为1,数字n可以自定义
- v-for=“(元素,下标) in 数组” 第2个参数是当前遍历到的元素下标,从0开始
<template>
<h1>循环指令</h1>
<ul>
<!-- 循环遍历arr数组,uname就是本轮循环遍历到的元素 -->
<li v-for="uname in arr">{{uname}}</li>
</ul>
<ol>
<!-- 从1开始遍历,一直到数字5,固定每次++,结束数字5可以自定义 -->
<li v-for="item in 5">{{item}}</li>
</ol>
<table border="1px">
<caption>商品列表</caption>
<tr>
<th>序号</th>
<th>商品名称</th>
<th>商品价格</th>
<th>商品库存</th>
<th>操作</th>
</tr>
<tr v-for="(item,index) in productArr">
<td>{{index+1}}</td>
<td>{{item.title}}</td>
<td>{{item.price}}</td>
<td>{{item.num}}</td>
<td><button @click="del(index)">删除</button></td>
</tr>
</table>
</template>
<script setup>
import {ref} from "vue";
const arr = ref(["张三","李四","王五","赵六","钱七"]);
const productArr = ref([
{title:'小米手机',price:5000,num:800},
{title:'华为手机',price:6000,num:900},
{title:'苹果手机',price:7000,num:100},
{title:'OPPO手机',price:8000,num:200},
]);
const del = (index)=>{
if(confirm('您确认要删除此条数据吗?')){
//删除数组中的元素,从当前index开始,删1个元素
productArr.value.splice(index,1);
}
}
</script>
<style scoped>
</style>
7.6 隐藏显示指令练习
v-if=“变量”:控制元素是否显示
- true 显示,false 不显示
- 直接在DOM中跳过该元素渲染,HTML代码中没有该元素
- 元素首次渲染需要复杂计算或初始化,v-if初次加载的速度快,推荐使用
v-else: 和最近的未关闭的 v-if 状态取反
v-show=“变量”:控制元素是否显示
- true 显示,false 不显示(隐藏元素)
- 通过设置CSS display:none;让元素隐藏
- 当元素需要频繁修改显示状态时推荐使用,不用多次新建删除元素,开销较小
<template>
<h1>隐藏显示指令</h1>
<!-- v-if="布尔值" true元素显示 false元素消失
false表示该元素不会被渲染到DOM中,会直接跳过这部分内容的渲染 -->
<p v-if="true">张三</p>
<p v-if="false">李四</p>
<p>王五</p>
<hr>
<p v-if="isShow">月亮</p>
<p v-if="isShow">星星</p>
<!-- v-else是v-if取反 它会找离自己最近的v-if进行取反 -->
<p v-else>太阳</p>
<hr>
<!-- v-if是直接在DOM中跳过该元素渲染,HTML代码中没有该元素 -->
<p v-if="false">小绿</p>
<!-- v-show是修改元素的CSS属性display:none;在频繁切换是否显示时才推荐,性能更好 -->
<p v-show="false">小红</p>
</template>
<script setup>
import {ref} from "vue";
const isShow = ref(false);
</script>
<style scoped>
</style>
7.7 计算器练习
<template>
<h1>计算器练习</h1>
<input type="text" placeholder="请输入数字1" v-model="a"/>
<input type="text" placeholder="请输入数字2" v-model="b"/>
<hr>
<button @click="calc('+')">加</button>
<button @click="calc('-')">减</button>
<button @click="calc('*')">乘</button>
<button @click="calc('/')">除</button>
<h4>运算结果:{{result}}</h4>
</template>
<script setup>
import {ref} from "vue";
//ref('');表示创建一个响应式变量,''是空的占位符,
//如果不写'',ref的初始值是undefined不推荐
const a = ref('');
const b = ref('');
const result = ref('');
const calc = (o)=>{
result.value = eval(a.value+o+b.value);
}
//eval("5*2")
//结果为10 将字符串形式的算式转为JS进行运算
</script>
<style scoped>
</style>
7.8 猜数字练习
<template>
<h1>猜数字练习</h1>
<input type="text" placeholder="请输入1~100之间的整数" v-model="num">
<button @click="guess()">猜一猜</button>
<h3>{{result}}</h3>
</template>
<script setup>
import {ref} from "vue";
const num = ref('');
const result = ref('');
//生成一个随机数
let x = parseInt(Math.random() * 100)+1;
console.log(x);
const guess = ()=>{
if(num.value>x){
result.value = '猜大了!';
}else if(num.value<x){
result.value = '猜小了!';
}else{
result.value = '猜对了!';
}
}
</script>
<style scoped>
</style>
7.9 员工列表练习
<template>
<h1>员工列表练习</h1>
<input type="text" placeholder="请输入员工姓名" v-model="e.name">
<input type="text" placeholder="请输入员工工资" v-model="e.salary">
<input type="text" placeholder="请输入员工岗位" v-model="e.job">
<button @click="add()">点我添加</button>
<hr>
<table border="1px">
<tr>
<th>员工编号</th>
<th>员工姓名</th>
<th>员工工资</th>
<th>员工岗位</th>
</tr>
<tr v-for="(emp,i) in arr">
<td>{{i+1}}</td>
<td>{{emp.name}}</td>
<td>{{emp.salary}}</td>
<td>{{emp.job}}</td>
</tr>
</table>
</template>
<script setup>
import {ref} from "vue";
//1.准备数组用来保存多个员工对象
const arr = ref([]);
//2.准备一个空的员工模板对象用来接收输入框输入的数据
const e = ref({name: '', salary: '', job: ''});
//3.定义添加员工的方法
const add = ()=>{
//4.判断输入框数据是否有空值
if(e.value.name.trim()==''||e.value.salary.trim()==''||e.value.job.trim()==''){
alert('请输入完整的信息!');
return;
}
//5.每准备好一个员工数据,就存入arr数组中
arr.value.push(e.value);
//6.新增成功后,清空输入框数据
e.value = {name: '', salary: '', job: ''};
}
</script>
<style scoped>
</style>
7.10 VUE指令总结
- {{变量}}:插值,让此处的文本内容和变量进行绑定
- v-text=“变量”:让元素的文本内容和变量进行绑定
- v-html=“变量”:让元素的 html 标签内容和变量进行绑定
- v-bind:属性名=“变量”:让 xxx 属性的值和变量进行绑定,简写是把 v-bind 去掉
- v-model=“变量”:让控件的值和变量进行双向绑定
应用场景:当需要获取用户输入内容时使用
(当变量的值改变时,控件的值会随之改变;当控件中用户输入的值改变时,变量的值也会随之改变)
- v-on:事件名=“方法”:事件绑定,简写@事件名
- v-for=“(变量,下标) in 数组”:循环遍历指令,遍历的过程中生成遍历到的当前元素
- v-if=“变量”:控制元素是否显示,true 显示,false 不显示(直接不渲染该元素)
- v-else 和 v-if 的状态取反
- v-show=“变量”:控制元素是否显示,true 显示,false 不显示(隐藏元素)