【Vue2搭建(安装脚手架)项目配置】

女爷i 2024-03-31 17:19 191阅读 0赞

Vue 2

1. Vue 基础

1) 环境准备

安装脚手架
  1. npm install -g @vue/cli
  • -g 参数表示全局安装,这样在任意目录都可以使用 vue 脚本创建项目
创建项目
  1. vue ui

使用图形向导来创建 vue 项目,如下图,输入项目名

在这里插入图片描述

选择手动配置项目

在这里插入图片描述

添加 vue router 和 vuex

在这里插入图片描述

选择版本,创建项目

在这里插入图片描述

安装 devtools
  • devtools 插件网址:https://devtools.vuejs.org/guide/installation.html

在这里插入图片描述

运行项目

进入项目目录,执行

  1. npm run serve
修改端口

前端服务器默认占用了 8080 端口,需要修改一下

  • 文档地址:DevServer | webpack
  • 打开 vue.config.js 添加

    1. const {
    2. defineConfig } = require('@vue/cli-service')
    3. module.exports = defineConfig({
  1. // ...
  2. devServer: {
  3. port: 7070
  4. }
  5. })
添加代理

为了避免前后端服务器联调时, fetch、xhr 请求产生跨域问题,需要配置代理

  • 文档地址同上
  • 打开 vue.config.js 添加

    1. const {
    2. defineConfig } = require('@vue/cli-service')
    3. module.exports = defineConfig({
  1. // ...
  2. devServer: {
  3. port: 7070,
  4. proxy: {
  5. '/api': {
  6. target: 'http://localhost:8080',
  7. changeOrigin: true
  8. }
  9. }
  10. }
  11. })
Vue 项目结构
  1. PS D:\2022.js\代\第3\client> tree src
  2. D:\2022.JS\代\第3\CLIENT\SRC
  3. ├─assets
  4. ├─components
  5. ├─router
  6. ├─store
  7. └─views
  • assets - 静态资源
  • components - 可重用组件
  • router - 路由
  • store - 数据共享
  • views - 视图组件

以后还会添加

  • api - 跟后台交互,发送 fetch、xhr 请求,接收响应
  • plugins - 插件

2) Vue 组件

Vue 的组件文件以 .vue 结尾,每个组件由三部分组成

  1. <template></template>
  2. <script></script>
  3. <style></style>
  • template 模板部分,由它生成 html 代码
  • script 代码部分,控制模板的数据来源和行为
  • style 样式部分,一般不咋关心

入口组件是 App.vue

先删除原有代码,来个 Hello, World 例子

  1. <template>
  2. <h1>{
  3. {msg}}</h1>
  4. </template>
  5. <script>
  6. export default {
  7. data() {
  8. return {
  9. msg: "Hello, Vue!"
  10. }
  11. }
  12. }
  13. </script>

解释

  • export default 导出组件对象,供 main.js 导入使用
  • 这个对象有一个 data 方法,返回一个对象,给 template 提供数据
  • { {}} 在 Vue 里称之为插值表达式,用来绑定 data 方法返回的对象属性,绑定的含义是数据发生变化时,页面显示会同步变化
文本插值
  1. <template>
  2. <div>
  3. <h1>{
  4. { name }}</h1>
  5. <h1>{
  6. { age > 60 ? '老年' : '青年' }}</h1>
  7. </div>
  8. </template>
  9. <script>
  10. const options = {
  11. data: function () {
  12. return { name: '张三', age: 70 };
  13. }
  14. };
  15. export default options;
  16. </script>
  • { {}} 里只能绑定一个属性,绑定多个属性需要用多个 { {}} 分别绑定
  • template 内只能有一个根元素
  • 插值内可以进行简单的表达式计算
属性绑定
  1. <template>
  2. <div>
  3. <div><input type="text" v-bind:value="name"></div>
  4. <div><input type="date" v-bind:value="birthday"></div>
  5. <div><input type="text" :value="age"></div>
  6. </div>
  7. </template>
  8. <script>
  9. const options = {
  10. data: function () {
  11. return { name: '王五', birthday: '1995-05-01', age: 20 };
  12. }
  13. };
  14. export default options;
  15. </script>
  • 简写方式:可以省略 v-bind 只保留冒号
事件绑定
  1. <!-- 事件绑定 -->
  2. <template>
  3. <div>
  4. <div><input type="button" value="点我执行m1" v-on:click="m1"></div>
  5. <div><input type="button" value="点我执行m2" @click="m2"></div>
  6. <div>{
  7. {count}}</div>
  8. </div>
  9. </template>
  10. <script>
  11. const options = {
  12. data: function () {
  13. return { count: 0 };
  14. },
  15. methods: {
  16. m1() {
  17. this.count ++;
  18. console.log("m1")
  19. },
  20. m2() {
  21. this.count --;
  22. console.log("m2")
  23. }
  24. }
  25. };
  26. export default options;
  27. </script>
  • 简写方式:可以把 v-on: 替换为 @
  • 在 methods 方法中的 this 代表的是 data 函数返回的数据对象
双向绑定
  1. <template>
  2. <div>
  3. <div>
  4. <label for="">请输入姓名</label>
  5. <input type="text" v-model="name">
  6. </div>
  7. <div>
  8. <label for="">请输入年龄</label>
  9. <input type="text" v-model="age">
  10. </div>
  11. <div>
  12. <label for="">请选择性别</label>
  13. <input type="radio" value="男" v-model="sex">
  14. <input type="radio" value="女" v-model="sex">
  15. </div>
  16. <div>
  17. <label for="">请选择爱好</label>
  18. 游泳 <input type="checkbox" value="游泳" v-model="fav">
  19. 打球 <input type="checkbox" value="打球" v-model="fav">
  20. 健身 <input type="checkbox" value="健身" v-model="fav">
  21. </div>
  22. </div>
  23. </template>
  24. <script>
  25. const options = {
  26. data: function () {
  27. return { name: '', age: null, sex:'男' , fav:['打球']};
  28. },
  29. methods: {
  30. }
  31. };
  32. export default options;
  33. </script>
  • 用 v-model 实现双向绑定,即

    • javascript 数据可以同步到表单标签
    • 反过来用户在表单标签输入的新值也会同步到 javascript 这边
  • 双向绑定只适用于表单这种带【输入】功能的标签,其它标签的数据绑定,单向就足够了
  • 复选框这种标签,双向绑定的 javascript 数据类型一般用数组
计算属性
  1. <!-- 计算属性 -->
  2. <template>
  3. <div>
  4. <h2>{
  5. {fullName}}</h2>
  6. <h2>{
  7. {fullName}}</h2>
  8. <h2>{
  9. {fullName}}</h2>
  10. </div>
  11. </template>
  12. <script>
  13. const options = {
  14. data: function () {
  15. return { firstName: '三', lastName: '张' };
  16. },
  17. /* methods: {
  18. fullName() {
  19. console.log('进入了 fullName')
  20. return this.lastName + this.firstName;
  21. }
  22. },*/
  23. computed: {
  24. fullName() {
  25. console.log('进入了 fullName')
  26. return this.lastName + this.firstName;
  27. }
  28. }
  29. };
  30. export default options;
  • 普通方法调用必须加 (),没有缓存功能
  • 计算属性使用时就把它当属性来用,不加 (),有缓存功能:

    • 一次计算后,会将结果缓存,下次再计算时,只要数据没有变化,不会重新计算,直接返回缓存结果
axios

axios 它的底层是用了 XMLHttpRequest(xhr)方式发送请求和接收响应,xhr 相对于之前讲过的 fetch api 来说,功能更强大,但由于是比较老的 api,不支持 Promise,axios 对 xhr 进行了封装,使之支持 Promise,并提供了对请求、响应的统一拦截功能

安装

  1. npm install axios -S

导入

  1. import axios from 'axios'
  • axios 默认导出一个对象,这里的 import 导入的就是它默认导出的对象

方法






































请求 备注
axios.get(url[, config]) ⭐️
axios.delete(url[, config])
axios.head(url[, config])
axios.options(url[, config])
axios.post(url[, data[, config]]) ⭐️
axios.put(url[, data[, config]])
axios.patch(url[, data[, config]])
  • config - 选项对象、例如查询参数、请求头…
  • data - 请求体数据、最常见的是 json 格式数据
  • get、head 请求无法携带请求体,这应当是浏览器的限制所致(xhr、fetch api 均有限制)
  • options、delete 请求可以通过 config 中的 data 携带请求体

例子

  1. <template>
  2. <div>
  3. <input type="button" value="获取远程数据" @click="sendReq()">
  4. </div>
  5. </template>
  6. <script>
  7. import axios from 'axios'
  8. const options = {
  9. methods: {
  10. async sendReq() {
  11. // 1. 演示 get, post
  12. // const resp = await axios.post('/api/a2');
  13. // 2. 发送请求头
  14. // const resp = await axios.post('/api/a3',{},{
  15. // headers:{
  16. // Authorization:'abc'
  17. // }
  18. // });
  19. // 3. 发送请求时携带查询参数 ?name=xxx&age=xxx
  20. // const name = encodeURIComponent('&&&');
  21. // const age = 18;
  22. // const resp = await axios.post(`/api/a4?name=${name}&age=${age}`);
  23. // 不想自己拼串、处理特殊字符、就用下面的办法
  24. // const resp = await axios.post('/api/a4', {}, {
  25. // params: {
  26. // name:'&&&&',
  27. // age: 20
  28. // }
  29. // });
  30. // 4. 用请求体发数据,格式为 urlencoded
  31. // const params = new URLSearchParams();
  32. // params.append("name", "张三");
  33. // params.append("age", 24)
  34. // const resp = await axios.post('/api/a4', params);
  35. // 5. 用请求体发数据,格式为 multipart
  36. // const params = new FormData();
  37. // params.append("name", "李四");
  38. // params.append("age", 30);
  39. // const resp = await axios.post('/api/a5', params);
  40. // 6. 用请求体发数据,格式为 json
  41. const resp = await axios.post('/api/a5json', {
  42. name: '王五',
  43. age: 50
  44. });
  45. console.log(resp);
  46. }
  47. }
  48. };
  49. export default options;
  50. </script>

创建实例

  1. const _axios = axios.create(config);
  • axios 对象可以直接使用,但使用的是默认的设置
  • 用 axios.create 创建的对象,可以覆盖默认设置,config 见下面说明

常见的 config 项有


































名称 含义
baseURL 将自动加在 url 前面
headers 请求头,类型为简单对象
params 跟在 URL 后的请求参数,类型为简单对象或 URLSearchParams
data 请求体,类型有简单对象、FormData、URLSearchParams、File 等
withCredentials 跨域时是否携带 Cookie 等凭证,默认为 false
responseType 响应类型,默认为 json

  1. const _axios = axios.create({
  2. baseURL: 'http://localhost:8080',
  3. withCredentials: true
  4. });
  5. await _axios.post('/api/a6set')
  6. await _axios.post('/api/a6get')
  • 生产环境希望 xhr 请求不走代理,可以用 baseURL 统一修改
  • 希望跨域请求携带 cookie,需要配置 withCredentials: true,服务器也要配置 allowCredentials = true,否则浏览器获取跨域返回的 cookie 时会报错

响应格式






















名称 含义
data 响应体数据 ⭐️
status 状态码 ⭐️
headers 响应头
  • 200 表示响应成功
  • 400 请求数据不正确 age=abc
  • 401 身份验证没通过
  • 403 没有权限
  • 404 资源不存在
  • 405 不支持请求方式 post
  • 500 服务器内部错误

请求拦截器

  1. _axios.interceptors.request.use(
  2. function(config) {
  3. // 比如在这里添加统一的 headers
  4. return config;
  5. },
  6. function(error) {
  7. return Promise.reject(error);
  8. }
  9. );

响应拦截器

  1. _axios.interceptors.response.use(
  2. function(response) {
  3. // 2xx 范围内走这里
  4. return response;
  5. },
  6. function(error) {
  7. // 超出 2xx, 比如 4xx, 5xx 走这里
  8. return Promise.reject(error);
  9. }
  10. );
条件渲染
  1. <template>
  2. <div>
  3. <input type="button" value="获取远程数据" @click="sendReq()">
  4. <div class="title">学生列表</div>
  5. <div class="thead">
  6. <div class="row bold">
  7. <div class="col">编号</div>
  8. <div class="col">姓名</div>
  9. <div class="col">性别</div>
  10. <div class="col">年龄</div>
  11. </div>
  12. </div>
  13. <div class="tbody">
  14. <div class="row" v-if="students.length > 0">显示学生数据</div>
  15. <div class="row" v-else>暂无学生数据</div>
  16. </div>
  17. </div>
  18. </template>
  19. <script>
  20. import axios from '../util/myaxios'
  21. const options = {
  22. data: function() {
  23. return {
  24. students: []
  25. };
  26. },
  27. methods : {
  28. async sendReq() {
  29. const resp = await axios.get("/api/students");
  30. console.log(resp.data.data)
  31. this.students = resp.data.data;
  32. }
  33. }
  34. };
  35. export default options;
  36. </script>
  37. <style scoped>
  38. div {
  39. font-family: 华文行楷;
  40. font-size: 20px;
  41. }
  42. .title {
  43. margin-bottom: 10px;
  44. font-size: 30px;
  45. color: #333;
  46. text-align: center;
  47. }
  48. .row {
  49. background-color: #fff;
  50. display: flex;
  51. justify-content: center;
  52. }
  53. .col {
  54. border: 1px solid #f0f0f0;
  55. width: 15%;
  56. height: 35px;
  57. text-align: center;
  58. line-height: 35px;
  59. }
  60. .bold .col {
  61. background-color: #f1f1f1;
  62. }
  63. </style>
列表渲染
  1. <template>
  2. <div>
  3. <!-- <input type="button" value="获取远程数据" @click="sendReq()"> -->
  4. <div class="title">学生列表</div>
  5. <div class="thead">
  6. <div class="row bold">
  7. <div class="col">编号</div>
  8. <div class="col">姓名</div>
  9. <div class="col">性别</div>
  10. <div class="col">年龄</div>
  11. </div>
  12. </div>
  13. <div class="tbody">
  14. <div v-if="students.length > 0">
  15. <div class="row" v-for="s of students" :key="s.id">
  16. <div class="col">{
  17. {s.id}}</div>
  18. <div class="col">{
  19. {s.name}}</div>
  20. <div class="col">{
  21. {s.sex}}</div>
  22. <div class="col">{
  23. {s.age}}</div>
  24. </div>
  25. </div>
  26. <div class="row" v-else>暂无学生数据</div>
  27. </div>
  28. </div>
  29. </template>
  30. <script>
  31. import axios from '../util/myaxios'
  32. const options = {
  33. mounted: function(){
  34. this.sendReq()
  35. },
  36. data: function() {
  37. return {
  38. students: []
  39. };
  40. },
  41. methods : {
  42. async sendReq() {
  43. const resp = await axios.get("/api/students");
  44. console.log(resp.data.data)
  45. this.students = resp.data.data;
  46. }
  47. }
  48. };
  49. export default options;
  50. </script>
  51. <style scoped>
  52. div {
  53. font-family: 华文行楷;
  54. font-size: 20px;
  55. }
  56. .title {
  57. margin-bottom: 10px;
  58. font-size: 30px;
  59. color: #333;
  60. text-align: center;
  61. }
  62. .row {
  63. background-color: #fff;
  64. display: flex;
  65. justify-content: center;
  66. }
  67. .col {
  68. border: 1px solid #f0f0f0;
  69. width: 15%;
  70. height: 35px;
  71. text-align: center;
  72. line-height: 35px;
  73. }
  74. .bold .col {
  75. background-color: #f1f1f1;
  76. }
  77. </style>
  • v-if 和 v-for 不能用于同一个标签
  • v-for 需要配合特殊的标签属性 key 一起使用,并且 key 属性要绑定到一个能起到唯一标识作用的数据上,本例绑定到了学生编号上
  • options 的 mounted 属性对应一个函数,此函数会在组件挂载后(准备就绪)被调用,可以在它内部发起请求,去获取学生数据
重用组件

按钮组件

  1. <template>
  2. <div class="button" :class="[type,size]">
  3. a<slot></slot>b
  4. </div>
  5. </template>
  6. <script>
  7. const options = {
  8. props: ["type", "size"]
  9. };
  10. export default options;
  11. </script>
  • 注意,省略了样式部分

使用组件

  1. <template>
  2. <div>
  3. <h1>父组件</h1>
  4. <my-button type="primary" size="small">1</my-button>
  5. <my-button type="danger" size="middle">2</my-button>
  6. <my-button type="success" size="large">3</my-button>
  7. </div>
  8. </template>
  9. <script>
  10. import MyButton from '../components/MyButton.vue'
  11. const options = {
  12. components: {
  13. MyButton
  14. }
  15. };
  16. export default options;
  17. </script>

发表评论

表情:
评论列表 (有 0 条评论,191人围观)

还没有评论,来说两句吧...

相关阅读

    相关 第一个Vue脚手架项目

    ①安装node运行环境 我这里node环境是已经安装完毕了,具体安装的步骤就不演示了,需要注意的是版本 不能太低,否则版本过低会出现问题。 ![在这里插入图片描述]