当前位置:首页 » 《随便一记》 » 正文

Vue框架

11 人参与  2024年05月03日 09:43  分类 : 《随便一记》  评论

点击全文阅读


目录

简单介绍

MVVM

下载安装Node.js

安装Vue.js插件

 新建Vue.js项目

下载vue依赖库

Vue工程目录结构

修改代码模板

vue组件中,添加模型数据

 Vue双向绑定

动态绑定

vue组件中,显示图片

单选框绑定

复选框绑定

Vue的script表达式

Vue实例声明周期

Vue事件

判断语句

列表渲染

综合练习

Vue路由

路由跳转

嵌套路由

跨域问题

axios解决跨域问题

Vue中配置代理

跨域增删改查操作


简单介绍

        Vue.js(读音 /vjuː/, 类似于 view)是一套用于构建用户界面的渐进式框架。

        Vue被设计为可以自底向上逐层应用。Vue的核心库只关注视图层,易于上手,便于与第三方库或既有项目整合。

Vue.js - 渐进式 JavaScript 框架 | Vue.js (vuejs.org)icon-default.png?t=N7T8https://cn.vuejs.org/

MVVM

        Vue是基于MVVM架构模式的JavaScript框架,MVVM是Model-View-ViewModel的缩写,它是一种前端架构模式,与MVC(Model-View-Controller)和MVP(Model-View-Presenter)类似,但它更加关注于数据绑定和视图模板。

        在MVVM模式下,视图层(View)与数据层(Model)之间没有直接的联系,而是通过中间层(ViewModel)进行交互、通信,(ViewModel负责将模型层的数据转换成视图层的数据,同时监听视图层的变化并将变化的数据传递给模型层)Model和ViewModle之间的交互是双向的。因此,View数据的变化会同步到Model中,而Model中数据的变化也会影响。

Model:代表数据模型,也可以在Model中定义数据修改和操作的业务逻辑View:代表UI组件,他负责将数据模型转化成UI展示出来ViewModle:监听数据模型的改变和控制视图行为、处理用户交互;简单理解就是一个同步View和Model的对象,连接Model和View

下载安装Node.js

        Node.js是一个让JavaScript运行在服务端的开发平台,(类似Maven)它可用于方便地搭建响应速度块,易于拓展的网络应用。Download | Node.jsNode.js® is a JavaScript runtime built on Chrome's V8 JavaScript engine.icon-default.png?t=N7T8https://nodejs.org/en/download/        安装完以后,运行cmd,在dos界面中,输入“node -v”查看安装版本,验证Node.js是否已成功安装。

node -v

        Node.js可以作为前端开发库的存在,需要设置拉取镜像地址,国内的服务器速度较快,一般设置为淘宝镜像。(直接在dos界面中粘贴这个地址)

npm config set registry=https://registry.npm.taobao.org

查看镜像设置是否成功 

npm config list

安装Vue.js插件

IDE工具栏中: 

文件——设置——插件——Marketplace下搜索Vue.js即可

 新建Vue.js项目

 注意:项目名称不要以大写命名,全小写

终端输入 npm run serve

npm run serve

最后,打开浏览器

连续按下Ctrl+c,可以关闭前端服务器  

下载vue依赖库

npm install --save axios  vue-router echarts  element-plus @element-plus/icons-vue

安装以下包并将它们作为依赖项保存在项目`package.json`文件中:

- axios:一种流行的基于承诺的 HTTP 客户端,用于从 JavaScript 向 API 发出请求。
- vue-router:一个 Vue.js 插件,用于在您的应用程序中实现客户端路由。
- echarts:一个强大的图表和可视化库,用于在 Web 应用程序中显示数据。
- element-plus:一个 Vue.js UI 库,提供一组可定制和响应式 UI 组件。
- @element-plus/icons-vue:一组用于 Element Plus 库的图标。

该--save选项会将这些包添加到dependencies在 中的部分package.json,这意味着它们是你的应用程序运行所必需的。

Vue工程目录结构

node_modles :插件目录

public:静态资源

src:源码目录

        main.js:程序入口文件

        vue.config.js:可选的配置文件,如果项目的根目录中存在此文件,它会被@vue/cli-service自动加载

const { defineConfig } = require('@vue/cli-service')module.exports = defineConfig({  transpileDependencies: true,//忽略未使用变量或组件报错问题  lintOnSave:false,//关闭ESLint检测  devServer:{    port:8086//改变端口  }})

构建

npm run build

修改代码模板

设置——编辑器——文件和代码模板

<template>     <div>#[[$END$]]#    </div></template><script>export default {    data(){            return{            }    }}</script><style scoped></style>

vue组件中,添加模型数据

添加模型数据

<script>export default {  data() {    return {      msg:"哈喽"    }  }}</script>

展示模型数据

<template>  <div>    {{msg}}}  </div></template>

启动服务

npm run serve

注意 :vue数据中的html代码,双大括号会将数据解释为普通文本,而非HTML代码,为了输出真正的HTML,需要使用v-html指令

添加模型数据:

info:"<span style='color: red'>hello</span>"

展示模型数据:

<div v-html="info"> </div>

 Vue双向绑定

        模型和视图组件的双向绑定,界面数据发生变化时,模型数据变化,反之也一样(不用再频繁的document.id了)

添加模型数据:

name:" "

展示模型数据:

姓名:<input type="text" v-model="name"><br>{{name}}

        当文本框内容发生变化时,name属性值随之变化。同样,当name属性值发生变化时,文本框内容随之变化

动态绑定

当元素的属性来自Vue对象数据时,使用v-bind表示

divcss:"color:blue"
<div v-bind:style="divcss">div内容</div>

 可缩写为:

<div :style="divcss">div内容</div>

vue组件中,显示图片

添加模型数据:

pic:require("@/img/wallhaven-9dxlw8.jpg")

注意: 图片如果是本地文件 需要加require,网络图片的URL路径就不需要加require了

展示模型数据:

url路径的三种方式:

“@”符号在src目录下查找资源

“../” 在当前目录的父目录下查找

“./” 当前目录下查找

<img :src="pic" width="500" height="300">

单选框绑定

添加模型数据:

sex:""

展示模型数据:

<input type="radio" v-model="sex" value="男">男<input type="radio" v-model="sex" value="女">女{{sex}}

        当sex的值发生变化时,和该sex的值对应的单选框被选中,当用户点击不同单选框时,也会将点中单选框的value值,赋给sex

复选框绑定

添加模型数据:

 likeArray:[]

展示模型数据:

<input type="checkbox" v-model="likeArray" value="唱">唱<input type="checkbox" v-model="likeArray" value="跳">跳<input type="checkbox" v-model="likeArray" value="rap">rap<input type="checkbox" v-model="likeArray" value="篮球">篮球{{likeArray}}

Vue的script表达式

在使用 { { } } 显示数据时,可以支持一些简单的运算,加减乘除、字符串运算、三目运算等..

添加模型数据:

money:3000

展示模型数据: 

年薪:{{money*13}}

Vue实例声明周期

        每个vue实例在被创建时,都要经过一系列的初始化过程--例如,需要设置数据监听、编译模板、将实例挂载到DOM并在数据变化时更新DOM等。同时在这个过程中也会运算一些叫做生命周期钩子的函数,这些生命周期钩子函数可以用来在特定时间点执行代码,这给了用户在不同阶段添加自己的代码的机会

每个Vue实例声明周期分为四大类:

创建-----created挂载,将数据渲染到页面上-----mounted更新,在数据更改时调用-----updated销毁-----unmounted 每个阶段都有一个beforeXXX方法,在执行某个阶段之前执行

Vue事件

添加模型数据:

<script>export default {  data() {    return {      userName:"",      pwd:""    }  },  //methods方法中,访问模板数据需要加this  methods:{    land(){      if(this.userName=="爪哇" && this.pwd =="123"){        alert("登陆成功")      }else {        alert("登陆失败")      }    }  }}</script>

展示模型数据:  

<template>  <div>    用户名:<input type="text" v-model="userName"><br>    密码:<input type="password" v-model="pwd"><br>         <input type="button" value="登录" @click="land()">  </div></template>

判断语句

当v-if 中的条件为真时,渲染该组件,如果为假则不做渲染

添加模型数据:

<script>export default {  data() {    return {      grade:""    }  }}</script>

展示模型数据:  

<template>  <div>    请输入成绩:<input type="text" v-model="grade"><br>    评价:<span v-if="grade>=60">及格</span>          <span v-else>不及格</span>  </div></template>

列表渲染

Vue组件 遍历

添加模型数据:

<script>export default {  data() {   return {    userList:[{id:2,name:"张三丰",money:2500},            {id:3,name:"张无忌",money:3500},            {id:4,name:"章若楠",money:100000}]    }  }}</script>

展示模型数据:  

<table border="1" width="80%" cellpadding="0">  <thead>    <tr>      <th>编号</th>      <th>姓名</th>      <th>工资</th>    </tr>  </thead>  <tbody>  <tr v-for="user in userList">    <td>{{user.id}}</td>    <td>{{user.name}}</td>    <td>{{user.money}}</td>  </tr>  </tbody></table>

遍历整数

添加模型数据:

pages:5

展示模型数据: 

<a v-for="n in pages" :href="'findByItem?pageNO='+n" style="margin-left: 10px">{{n}} </a>

综合练习

添加模型数据:

<script>//导出模块默认值export default {  //data函数,返回一个包含组件使用的数据的对象。可以通过组件的方法和模板访问和修改此数据  data() {    return {      userList:[{id:1,name:'迪丽热巴',money:10000,status:"会员"},        {id:2,name:'古力娜扎',money:5500,status:"会员"},        {id:3,name:'马尔扎哈',money:200,status:"非会员"},        {id:4,name:'白鹿',money:8000,status:"会员"}],      showAdd:false,//添加界面的状态      userObj:{},//空对象,接收用户输入      showUpdate:false,      updateObj:{}    }  },  methods:{    add(){      //在数组中追加元素      this.userList.push(this.userObj);      //将userobj引用新对象,清空界面数据      this.userObj={};      //隐藏添加界面      this.showAdd=false;    },    changeStatus(id){      //根据指定的条件在对象数组中查找对象      let user = this.userList.find(n=>n.id==id);      user.status = '会员'    },    del(id){      //查询指定id,对应下标      let index = this.userList.findIndex(n=>n.id==id);      //按下标 截取元素      this.userList.splice(index,1);    },    findById(id){      this.updateObj = this.userList.find(n=>n.id==id);      this.showUpdate=true;    },  }}</script>

展示模型数据: 

<!--模板--><template>  <div>    <input type="button" value="添加" @click="showAdd = true"><!--构建表格-->    <table border="1" width="80%" cellpadding="0">      <!--表头-->       <thead>        <tr>          <th>id</th>          <th>名字</th>          <th>工资</th>          <th>状态</th>          <th>操作</th>        </tr>       </thead>      <!--表格正文-->      <tbody>        <tr v-for="user in userList">          <td>{{user.id}}</td>          <td>{{user.name}}</td>          <td>{{user.money}}</td>          <td>{{user.status}}</td>          <td>            <input type="button" v-if="user.status=='非会员'" value="升级为会员" @click="changeStatus(user.id)">            <input type="button" value="删除" @click="del(user.id)">            <input type="button" value="修改" @click="findById(user.id)">          </td>        </tr>      </tbody>    </table>    <!--showAdd为真时,渲染该组件-->    <div class="dialog" v-if="showAdd">      <div class="content">        编号:<input type="text" v-model="userObj.id"><br>        姓名:<input type="text" v-model="userObj.name"><br>        工资:<input type="text" v-model="userObj.money"><br>        状态:<input type="radio" value="会员" v-model="userObj.status">会员        <input type="radio" value="非会员" v-model="userObj.status">非会员<br>        <input type="button" value="添加" @click="add">      </div>    </div>    <div class="dialog" v-if="showUpdate">      <div class="content">        编号:{{updateObj.id}}<br>        姓名:{{updateObj.name}}<br>        工资:<input type="text" v-model="updateObj.money"><br>        状态:{{updateObj.status}}<br>        <input type="button" value="修改" @click="showUpdate=false">      </div>    </div>  </div></template>

样式:

<style scoped>  .dialog{    position: absolute;    left: 0px;    top: 0px;    width: 100%;    height: 100%;    background-color: rgba(66, 185, 173, 0.53);    display: flex;    justify-content: center;    align-items: center;  }  .content{    background-color: azure;    border: 1px solid black;    width: 600px;    height: 400px;    padding: 20px;  }</style>

Vue路由

        在web开发中,路由是根据url分配到对应的处理程序,对于大多数单页面应用,都推荐使用官方支持的vue-router。vue-router通过管理url,实现url和组件的对应,以及通过url进行组件之间的切换。

一、在src目录下,新建router文件夹 新建index.js、routes.js

二、在routes.js文件中,注册URL和VUE组件的映射关系

const routes = [    {name:"Login", //路由名称        path:"/login", //访问组件的URL路径        component: () => import('@/login.vue')},//导入vue组件    {name:"App",        path:"/app",        component: () => import('@/App')},];export default routes ;

三、完成index.js

//创建了路由器实例import {createRouter,createWebHistory} from 'vue-router'//将路由的配置信息传递给了 routes 变量import  routes  from "./routes"const router = createRouter({    history:createWebHistory(),    routes});export default router ;

 四、在main.js中导入路由

import router from "@/router/index"

五、在APP.vue中添加路由视图

<template>  <div>    <router-view></router-view>  </div></template><script>export default {}</script><style></style>

六、在main.js中,导入路由视图

import { createApp } from 'vue'import App from './App.vue'import router from "@/router/index"createApp(App).use(router).mount('#app')

打开浏览器  - Local:   http://localhost:8086/后面跟具体的路径


路由跳转

1、通过标签,完成跳转

<router-link to="/press">跳转..</router-link>
<a href="/press">跳转..</a>

2、通过js代码完成跳转

 land(){      if(this.userName=="爪哇" && this.pwd =="123"){       //两种方式都可以       this.$router.push("/userPress");       location.href="/userPress"      }else {        alert("登陆失败")      }

嵌套路由

在一个Vue组件中,再嵌入路由视图,称为嵌套路由

如果在父级路由对应的组件中定义了子级路由的标签,那么子级路由渲染的内容会插入到父级路由组件中的标签中,这样子级路由就可以继承父级路由的布局。        

一、在routes.js中,完成路由注册

const routes = [    {name:"Index",        path:"/index",        component: () => import('@/index'),    children:[        {name:"Order",            path:"/index/order",//嵌套路由的path路由,先写父路由路径,在写子路由路径            component: () => import('@/order/order')},        {name:"Room",            path:"/index/room",            component: () => import('@/order/room')}    ]    }];export default routes ;

二、在Vue组件中,添加路由视图

<template>  <div>    <div><h1>标题</h1></div>    <div style="display: flex">      <div style="width: 200px;height: 400px">          <router-link to="/index/order">订单</router-link><br>          <a href="/index/room">房间管理</a>      </div>      <div style="width: 800px;height: 400px">          <router-view></router-view>      </div>    </div>  </div></template>

跨域问题

        跨域问题来自浏览器安全机制,浏览器安全的基石是“同源政策”。其目的,是为了保障用户信息的安全,防止恶意的网站窃取数据。

        同源政策即:防止Cookie在不同的服务器之间共享,以保证cookie信息的安全性。如果非同源,共有三种行为受到限制;Cookie无法读取、DOM无法获得、Ajax请求无法发送。

        在同源政策中,A网页设置的Cookie,B网页不能打开,除非这两个网页“同源”,即:协议、域名、端口都相同。

axios解决跨域问题

axios中,可以通过配置代理,解决跨域问题。

        客户端请求服务端的数据是存在跨域问题的,而服务器和服务器之间可以相互请求数据,是没有跨域的概念。

        所以,可以配置一个代理的服务器请求另一个服务器中的数据,然后把请求出来的数据返回到代理服务器中。代理服务器再返回数据给客户端,从而实现跨域访问数据。

Vue中配置代理

在vue.config.js中添加proxy配置

module.exports = defineConfig({  transpileDependencies: true,  lintOnSave:false,  devServer:{    port:8086,    proxy: {      "/project": {        target: "http://localhost:8088",        pathRewrite: {          "^/project": "/"        }      }    }  }})

客户端以/project开始的请求,由代理服务器访问http://localhost:8088服务器。

跨域增删改查

即前后端分离开发

后台服务器控制组件

@RestController@RequestMapping("student")public class StudentController {    @Autowired    private IStudentService service;    @RequestMapping("add")    public String add(StudentBean studentBean, MultipartFile pic) throws IOException {        String fileName = pic.getOriginalFilename();        fileName = System.currentTimeMillis() + fileName.substring(fileName.lastIndexOf("."));        pic.transferTo(new File("E:/mavenstudy/JavaWeb/studentProject/face/"+fileName));        studentBean.setFace(fileName);        service.add(studentBean);        return "ok" ;    }    @RequestMapping("del")    public String del(Integer id){        service.del(id);        return "ok";    }    @RequestMapping("upd")    public String upd(Integer id,String phone){        service.upd(id,phone);        return "ok";    }    @RequestMapping("findByItem")    public IPage<StudentBean> findByItem(Integer pageNO, String name, LocalDate startTime,LocalDate endTime){       return service.findByItem(pageNO,name,startTime,endTime);    }    @RequestMapping("findById")    public StudentBean findById(Integer id){        return service.findById(id);    }}

1、在Vue组件中引入axios库。

import axios from 'axios';
它是一个基于Promise的HTTP客户端,可以用于浏览器和node.js中的AJAX请求。

2、定义data数据,包括分页对象cutObj、查询对象queryObj、添加对象addObj、修改对象updateObj,以及控制添加和修改(弹出层显示)的showAdd和showUpdate布尔值。这些js对象,用于存储前端与后端之间的数据交互信息。它们可以用来存储响应数据中的各种数据项,如分页信息、查询条件、添加信息等等,以便前端对这些数据进行展示和处理。

  data() {    return {      cutObj:{},      queryObj:{},      addObj:{},      showAdd:false,      updateObj:{},      showUpdate:false    }  }

3、在模板中使用v-for指令渲染学生信息表格,并使用v-if指令控制添加和修改的弹出框。

<template>  <!--构建表格-->  <div>    <table border="1" width="80%" >      <thead>          <th>姓名</th>          <th>生日</th>          <th>电话</th>          <th>操作</th>      </thead>      <tbody>        <!--遍历records数组-->        <tr v-for="student in cutObj.records">          <td>{{student.name}}</td>          <td>{{student.birthday}}</td>          <td>{{student.phone}}</td>          <!--绑定点击事件,调用函数的同时,将当前student.id作为参数传递-->          <td><input type="button" value="修改" @click="findById(student.id)"></td>          <td><input type="button" value="删除" @click="del(student.id)"></td>        </tr>      </tbody>    </table>    <!--遍历分页对象中的pages数组,绑定属性值,每个按钮的值等于正在循环的当前页码(即n)-->    <div>      <input type="button" v-for="n in cutObj.pages" :value="n" @click="findByItem(n)" style="margin-left: 10px">    </div>    <!--双向绑定-->    姓名:<input type="text" v-model="queryObj.name"><br>    起始日期:<input type="text" v-model="queryObj.startTime"><br>    结束日期:<input type="text" v-model="queryObj.endTime"><br>    <input type="button" value="查询" @click="findByItem(1)">    <hr>    <input type="button" value="添加" @click="showAdd=true">  </div>  <!--showAdd为真时,渲染该组件-->  <div class="dialog" v-if="showAdd">    <div class="content">      姓名:<input type="text" v-model="addObj.name"><br>      生日:<input type="text" v-model="addObj.birthday"><br>      电话:<input type="text" v-model="addObj.phone"><br>      头像:<input type="file" id="faceFile"><br>      <input type="button" value="添加" @click="addStudent()"><br>    </div>  </div>  <div class="dialog" v-if="showUpdate">  <div class="content">    <!--显示图片,src绑定表达式(路径+文件名)-->    <img :src="'/project/face/'+updateObj.face" width="80" height="80"><br>    姓名:{{updateObj.name}}<br>    生日:{{updateObj.birthday}}<br>    电话:<input type="text" v-model="updateObj.phone"><br>    <input type="button" value="修改" @click="updateStudent()"><br>  </div>  </div></template>

弹出层样式  

<style scoped>.dialog{  position: absolute;  left: 0px;  top: 0px;  width: 100%;  height: 100%;  background-color: rgba(66, 185, 173, 0.53);  display: flex;  justify-content: center;  align-items: center;}.content{  background-color: azure;  border: 1px solid black;  width: 600px;  height: 400px;  padding: 20px;}</style>

4、在methods中定义一系列方法,findByItem方法用于查询学生信息、addStudent方法用于添加学生信息、del方法用于删除学生信息、findById方法用于根据ID查询学生信息、updateStudent方法用于修改学生信息。 

methods:{    findByItem(pageNO){      this.queryObj.pageNO=pageNO;      axios.get("/project/student/findByItem",{        params:this.queryObj      }).then(resp=>{        this.cutObj = resp.data;      })    },    addStudent(){        /*在使用axios进行表单数据类型的请求时,需要将表单数据转为FormData对象,          然后将该对象作为参数传递给axios的POST方法。*/      let formObj = new  FormData();      //FormData对象将表单数据转换为键值对形式的数据,添加      formObj.append("name",this.addObj.name);      formObj.append("birthday",this.addObj.birthday);      formObj.append("phone",this.addObj.phone);      //通过DOM操作,获取(文件上传控件)元素,且只获取该文件上传控件中选择的第一个文件      //.files 是一个 FileList 对象,它包含了文件上传控件中所有选择的文件        formObj.append("pic",document.getElementById("faceFile").files[0]);      /*设置HTTP请求头的Content-Type字段为表单数据类型的请求,        以便服务器端能够正确解析表单数据。*/      let config={        headers:{'Content-Type':'multipart/form-data'}      }      axios.post("/project/student/add",formObj,config).then(resp=>{        if(resp.data=="ok"){          this.findByItem(1);          this.showAdd=false;        }      })    },    del(id){      axios.get("/project/student/del",{params:{id}}).then(resp=>{            if(resp=="ok"){              this.findByItem(1);            }          }      )    },    findById(id){      axios.get("/project/student/findById",{params:{id}}).then(resp=>{        this.updateObj=resp.data;        this.showUpdate=true;      })    },    updateStudent(){      axios.get("/project/student/upd",{params:this.updateObj}).then(resp=>{        if(resp.data=="ok"){          this.findByItem(1);          this.showUpdate=false;        }      })    }  }

5、在created钩子函数(它在组件创建完成后立即执行)中调用findByItem方法查询学生信息,并将查询结果赋值给cutObj。

  methods:{  },  created() {    //this代表当前的Vue实例    this.findByItem(1);  }

点击全文阅读


本文链接:http://zhangshiyu.com/post/103047.html

<< 上一篇 下一篇 >>

  • 评论(0)
  • 赞助本站

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

关于我们 | 我要投稿 | 免责申明

Copyright © 2020-2022 ZhangShiYu.com Rights Reserved.豫ICP备2022013469号-1