8.Vue框架快速上手

8.1 前端环境准备

8.1.1 MVVM模式

image.png

8.1.2 Vue快速入门

导入 vue.js 的 script 脚本文件
新建一个文件夹保存前端代码,新建一个demo.html
vsCode中“!+enter”可以自动生成模板
image.png
引用vue

<script src="https://unpkg.com/vue@3"></script>

使用vue

<body>
  <div id="counter">
    Counter: {{ counter }}
  </div>
  <script>
  const Counter = {
    data() {
      return {
        counter: "Hello World!"
      }
    }
  }
  Vue.createApp(Counter).mount('#counter')
  </script>
</body>

在vsCode中安装open in browser插件,右键点击“open in default browser”即可看到效果
image.png
示例1:基本用法

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <!-- 1.导入vue的脚本文件 -->
  <script src="https://unpkg.com/vue@3"></script>
</head>
<body>
  <!-- 2.声明要被vue所控制的DOM区域 -->
  <div id="counter">
    Counter: {{ counter }}
  </div>

  <!-- 3.创建vue的实例对象 -->
  <script>
  const Counter = {
    //指定数据源,即MVVM中的Model
    data() {
      return {
        counter: "Hello Vue!"
      }
    }
  }
  Vue.createApp(Counter).mount('#counter')
  </script>
</body>
</html>

2.内容渲染指令

<body>
  <div id="counter">
    <p>姓名:{{username}}</p>
    <p>性别:{{gender}}</p>

    <p>{{desc}}</p>
    <p v-html="desc"></p>
  </div>

  <script>
  const Counter = {
    //指定数据源,即MVVM中的Model
    data() {
      return {
        username:'zhangsan',
        gender:'男',
        desc:'<a href="http://www.baidu.com">百度</a>'
      }
    }
  }
  Vue.createApp(Counter).mount('#counter')
  </script>
</body>

显示:
image.png
3.内容绑定指令
“:”等同于“v-bind:”,意思是将属性绑定到页面元素上

<body>
  <div id="counter">
    <a :href="link">百度</a>
    <input type="text" :placeholder="inputValue">
    <img :src="imgSrc" :style="{width:w}" alt="">
  </div>

  <script>
  const Counter = {
    //指定数据源,即MVVM中的Model
    data() {
      return {
        link:"http://www.baidu.com",
        //文本框的占位符内容
        inputValue:'请输入内容',
        //图片的src地址
        imgSrc:'./images/demo.jpeg',
        w:'500px'
      }
    }
  }
  Vue.createApp(Counter).mount('#counter')
  </script>
</body>

image.png
4.使用JavaScript表达式

<body>
  <div id="counter">
    <p>{{number + 1}}</p>
    <p>{{ok ? 'True' : 'False'}}</p>
    <p>{{message.split('').reverse().join('')}}</p>
    <p :id="'list' + id">xxx</p>
    <p>{{user.name}}</p>
  </div>

  <script>
  const Counter = {
    //指定数据源,即MVVM中的Model
    data() {
      return {
        number:9,
        ok:false,
        message:'ABC',
        id:3,
        user:{
          name:'zs',
        }
      }
    }
  }
  Vue.createApp(Counter).mount('#counter')
  </script>
</body>

显示:
image.png
5.事件绑定指令

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <script src="https://unpkg.com/vue@3"></script>
</head>
<body>
  <div id="counter">
    <h3>count的值为:{{count}}</h3>
    <button v-on:click="addCount">+1</button>
    <button @click="count+=1">+1</button>
  </div>

  <script>
  const Counter = {
    data() {
      return {
        count:0,
      }
    },
    methods:{
      //点击按钮,让count自增+1
      addCount(){
        this.count += 1
      },
    }
  }
  Vue.createApp(Counter).mount('#counter')
  </script>
</body>
</html>

显示:
image.png
6.条件渲染指令

<body>
  <div id="counter">
    <button @click="flag = !flag">Toggle Flag</button>
    <p v-if="flag">请求成功 --- 被 v-if 控制</p>
    <p v-show="flag">请求成功 --- 被 v-show 控制</p>
  </div>

  <script>
  const Counter = {
    data() {
      return {
        flag:false,
      }
    }
  }
  Vue.createApp(Counter).mount('#counter')
  </script>

显示:(点击后的结果)
image.png
"v-if"如果是false,值不会被创建;"v-show"不管真假,标签都存在,true会显示,false会隐藏。
7.v-else和v-else-if指令

<body>
  <div id="counter">
    <p v-if="num > 0.5">随机数 > 0.5</p>
    <p v-else>随机数 ≤ 0.5</p>
    <hr/>
    <p v-if="type === 'A'">优秀</p>
    <p v-else-if="type === 'B'">良好</p>
    <p v-else-if="type === 'C'">一般</p>
    <p v-else>差</p>

    <div v-show="a">测试</div>
    <button @click="!a">点击</button>
  </div>

  <script>
  const Counter = {
    data() {
      return {
        num:Math.random(),
      }
    }
  }
  Vue.createApp(Counter).mount('#counter')
  </script>

显示:
image.png
8.列表渲染指令

<body>
  <div id="counter">
    <ul>
      <li v-for="(user,i) in userList">索引是:{{i}},姓名是:{{user.name}}</li>
    </ul>
  </div>

  <script>
  const Counter = {
    data() {
      return {
        userList:[
          {id:1, name:'zhangsan'},
          {id:2, name:'lisi'},
          {id:3, name:'wangwu'}
        ]
      }
    }
  }
  Vue.createApp(Counter).mount('#counter')
  </script>
</body>

显示:
image.png
9.v-for中的key

<body>

  <div id="counter">

    <!-- 添加用户的区域 -->
    <div>
      <input type="text" v-model="name"/>
      <button @click="addNewUser">添加</button>
    </div>
    
    <!-- 用户列表区域 -->
    <ul>
      <li v-for="(user,index) in userlist">
        <input type="checkbox"/>
        姓名:{{user.name}}
      </li>
    </ul>
  </div>

  <script>
  const Counter = {
    data() {
      return {
        //用户列表
        userlist:[
          {id:1, name:'zs'},
          {id:2, name:'ls'}
        ],
        //输入的用户名
        name:'',
        //下一个可用的id值
        nextId:3
      }
    },
    methods:{
      //点击了添加按钮
      addNewUser(){
        this.userlist.unshift({id:this.nextId,name:this.name})//
        this.name = ''
        this.nextId++
      }
    }
  }
  Vue.createApp(Counter).mount('#counter')
  </script>
</body>

v-modle的内容输入后会自动影响“name”的值
显示:
image.png
使用v-for的key标签唯一标识当前页面元素

    <!-- 用户列表区域 -->
    <ul>
      <li v-for="(user,index) in userlist" :key="user.id">
        <input type="checkbox"/>
        姓名:{{user.name}}
      </li>
    </ul>

9.组件化开发

9.1 NPM的使用

  • NPM(Node Package Manager)是一个NodeJS包管理和分发工具。
  • NPM以其优秀的依赖管理机制和庞大的用户群体,目前已经发展成为整个JS领域的依赖管理工具
  • NPM最常见的用法就是用于安装和更新依赖。要使用NPM,首先要安装Node工具
    官网下载地址:下载地址:https://nodejs.org/zh-cn
    image.png

    9.2 Vue Cli的使用

  • Vue CLI是Vue官方提供的构建工具,通常称为脚手架。
  • 用于快速搭建一个带有热重载(在代码修改后不必刷新页面即可呈现修改后的效果)及构建生产版本等功能的单页面应用。
  • Vue CLI基于 webpack 构建,也可以通过项目内的配置文件进行配置。
  • 安装:npm install -g @vue/cli
    然后cmd打开命令行窗口,输入:vue creat hello,选择Manually select features->把Linter取消(空格)->选择3.x->选择In package.json->N
    image.png
    之后会自动下载,完毕后会创建hello的项目,然后用vsCode打开即可
    image.png
    启动项目,查看->终端->输入:npm run serve

    9.3 组件化开发

  • 组件(Component)是Vue.js最强大的功能之一。组件可以扩展HTML元素,封装可重用的代码。
  • Vue的组件系统允许我们使用小型、独立和通常可复用的组件构建大型应用
    image.png
    组件的构成
  • Vue 中规定组件的后缀名是 .vue
  • 每个 .vue 组件都由 3 部分构成,分别是
  • template,组件的模板结构,可以包含HTML标签及其他的组件
  • script,组件的 JavaScript 代码
  • style,组件的样式
    组件的使用:先创建HelloWorld.vue,然后在App.vue中进行导入和使用
    image.png

    10.第三方组件element-ui

    image.png

    10.1 组件间的传值

  • 组件可以由内部的Data提供数据,也可以由父组件通过prop的方式传值。
  • 兄弟组件之间可以通过Vuex等统一数据源提供数据共享
    新建component项目:vue create component-demo
    image.png
    删除HelloWorld.vue,删除相关内容。
    新建Movie.vue,在app.vue中导入注册。

vue2和vue3的差异:vue2中的所有组件必须包含在一个父标签下,vue3没有限制。
组件之间可以任意嵌套。

10.1.2 组件间传值的实现

App.vue中重用Movie组件,使用v-for标签渲染多个组件。
image.png
Movie.vue内容
image.png
页面显示效果
image.png

10.2 element-ui介绍

  • Element是国内饿了么公司提供的一套开源前端框架,简洁优雅,提供了Vue、React、Angular等多个版本。
  • 文档地址:https://element.eleme.cn/#/zh-CN/
  • 安装:npm i element-ui
  • 引入 Element:
    image.png

    10.3 第三方图标库

  • 由于Element UI提供的字体图符较少,一般会采用其他图表库,如著名的Font Awesome
  • Font Awesome提供了675个可缩放的矢量图标,可以使用CSS所提供的所有特性对它们进行更改,包括大小、颜色、阴影或者其他任何支持的效果。
  • 文档地址:http://fontawesome.dashgame.com/
  • 安装:npm install font-awesome
  • 使用:import 'font-awesome/css/font-awesome.min.css'
    使用:
    image.png
    image.png

    11 Axios网络请求

    image.png
    在实际项目开发中,前端页面所需要的数据往往需要从服务器端获取,这必然
    涉及与服务器的通信。

  • Axios 是一个基于 promise 网络请求库,作用于node.js 和浏览器中。
  • Axios 在浏览器端使用XMLHttpRequests发送网络请求,并能自动完成JSON
  • 数据的转换 。
  • 安装:npm install axios
  • 地址:https://www.axios-http.cn/
    发送网络请求
    11.1.1 get请求
    image.png
    image.png
    11.1.2 post请求
    image.png
    11.1.3 异步回调方式
    async/await
    image.png
    其他请求方式
    参考:https://axios-http.com/zh/docs/req_config
    image.png
    image.png
    11.2 为什么会出现跨域问题
    为了保证浏览器的安全,不同源的客户端脚本在没有明确授权的情况下,不能
    读写对方资源,称为同源策略,同源策略是浏览器安全的基石
  • 同源策略(Sameoriginpolicy)是一种约定,它是浏览器最核心也最基本的安全功能
  • 所谓同源(即指在同一个域)就是两个页面具有相同的协议(protocol),主机(host)和端口号(port)
  • 当一个请求url的协议、域名、端口三者之间任意一个与当前页面url不同即为跨域,此时无法读取非同源网页的 Cookie,无法向非同源地址发送 AJAX 请求
    11.2.1 跨域问题解决
  • CORS(Cross-Origin Resource Sharing)是由W3C制定的一种跨域资源共享技术标准,其目的就是为了解决前端的跨域请求。
  • CORS可以在不破坏即有规则的情况下,通过后端服务器实现CORS接口,从而实现跨域通信。
  • CORS将请求分为两类:简单请求和非简单请求,分别对跨域通信提供了支持。
    11.2.2 简单请求
    满足以下条件的请求即为简单请求:
  • 请求方法:GET、POST、HEAD
  • 除了以下的请求头字段之外,没有自定义的请求头:
  • Accept、Accept-Language、Content-Language、Last-Event-ID、Content-Type
  • Content-Type的值只有以下三种:
  • text/plain、multipart/form-data、application/x-www-form-urlencoded
    11.2.3 简单请求的服务器处理
    对于简单请求,CORS的策略是请求时在请求头中增加一个Origin字段,
    image.png
    服务器收到请求后,根据该字段判断是否允许该请求访问,如果允许,则在
    HTTP头信息中添加Access-Control-Allow-Origin字段。
    image.png
    11.2.4 非简单请求
  • 对于非简单请求的跨源请求,浏览器会在真实请求发出前增加一次OPTION请求,称为预检请求(preflight request)
  • 预检请求将真实请求的信息,包括请求方法、自定义头字段、源信息添加到HTTP头信息字段中,询问服务器是否允许这样的操作。
  • 例如一个GET请求:
    image.png
  • Access-Control-Request-Method表示请求使用的HTTP方法,Access- Control-Request-Headers包含请求的自定义头字段
  • 服务器收到请求时,需要分别对Origin、Access-Control-Request-Method、Access-Control-Request-Headers进行验证,验证通过后,会在返回HTTP头
  • 信息中添加:
    image.png
  • Access-Control-Allow-Methods、Access-Control-Allow-Headers:真实请求允许的方法、允许使用的字段
  • Access-Control-Allow-Credentials: 是否允许用户发送、处理cookie
  • Access-Control-Max-Age: 预检请求的有效期,单位为秒,有效期内不会重复发送预检请求。
  • 当预检请求通过后,浏览器才会发送真实请求到服务器。这样就实现了跨域资源的请求访问。
    11.3 Spring Boot中配置CORS
    在传统的Java EE开发中,可以通过过滤器统一配置,而Spring Boot中对此则提供了更加简洁的解决方案
    image.png
    实际使用:
    在控制器类中,加入@CrossOrigin注解,可使该类中的所有方法允许被跨域
    image.png
    注意:箭头函数内部的作用域继承于父级,涉及到网络请求要用箭头函数
    。。。。。。。
    第一步:在mian.js中引入axios(vue2项目),这样全局就可以使用axios;配置baseURL
    image.png
    第二步:Hello.vue中使用axios
    image.png
    至此,已经可以把后端数据显示到前端页面了。

飞呀
1 声望4 粉丝