笔记:SpringBoot+Vue全栈开发2
- 1. MVVM模式
- 2. Vue组件化开发
- 3. 第三方组件element-ui的使用
- 4. axios网络请求
- 5. 前端路由VueRouter
1. MVVM模式
MVVM是Model-View-ViewModel的缩写,是一种基于前端开发的架构模式,其核心是提供对View和ViewModel的双向数据绑定。
ViewModel负责连接View和Model,保证视图和数据的一致性。
使用的vue版本为vue3,直接导入vue3本地文件路径在html文件中,然后在写入如下代码:
Vue.createApp({
data(){
return {
}
},
methods: {
}
}).mount("#app");
// 挂载
data下用于写数据变量,methods下写方法,然后把整个vue容器挂载到id值为app的标签上。
渲染数据使用双花括号,即“{{}}”,花括号中可以写变量或者表达式;如果要渲染html标签字符串,使用v-html;设置标签属性值时使用v-bind:属性名,可以简写为“:属性名”;设置标签元素上的事件时使用v-on:时间名,可以简写为“@事件名”;进行条件判断可以考虑使用v-if或v-show,其中使用v-if为false时,在页面上是没有这个标签元素,而v-show为false时,只是设置了这个标签元素的css样式值"display:none",通常频繁变换切换的考虑使用v-show;进行列表渲染时,使用v-if,即v-for=“user in users"或者v-for=”(user,index) in users",后者带有index下表索引,从0开始,通常需要添加key属性,否则存在潜在的bug,下述演示代码中没有使用key属性;v-model是对表单标签元素进行双向数据绑定。
参考代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>vue3</title>
<script type="text/javascript" src="../vue3.js"></script>
</head>
<body>
<div id="app">
<div>{{text_str}}</div>
<div>{{html_str}}</div>
<div v-html="html_str"></div>
<a v-bind:href="href_str">{{href_text}}</a>
<!-- {{表达式或者变量}}} -->
<p>{{v}}</p>
<button v-on:click="hh_fuc">+1</button>
<br>
<!-- 条件判断 -->
<button @click="flag = !flag">变换</button>
<p v-if="flag">v-if:哈哈2</p>
<p v-show="flag">v-show:哈哈2</p>
<!-- 列表渲染 -->
<ul>
<!-- <li v-for="user in users">
<span>{{user.username}}</span>
<span>{{user.age}}</span>
</li> -->
<li v-for="(user,i) in users">
<span>{{i}}</span>
<span>{{user.username}}</span>
<span>{{user.age}}</span>
</li>
</ul>
</div>
</body>
<script type="text/javascript">
Vue.createApp({
data(){
return {
text_str:"hello world!",
html_str:"<h3>哈哈</h3>",
href_str:"https://www.baidu.com",
href_text:"百度",
v:1,
flag:false,
users:[
{
username:"张三",
age:23
},
{
username: "李四",
age: 29
},
{
username: "王五",
age: 32
}
]
}
},
methods: {
hh_fuc: function () {
this.v++;
}
}
}).mount("#app");
// 挂载
</script>
</html>
2. Vue组件化开发
需要用到npm命令,当然首先需要安装nodejs。
使用Vue CLI 脚手架进行构建项目,创建项目命令为:
npm install -g @vue/cli
// 安装vue cli脚手架命令
vue create 项目名
// 创建项目命令
运行首先来到当前项目目录下,然后使用命令npm run serve
vue中规定组件的后缀名为“.vue”,每个“.vue”组件都由3个部分构成,分别为template、script、style。
自定义组件,首先在当前项目的components目录下新建vue文件,文件命名通常首字母大写,然后在这个文件下添加组件的三部分,之后在App.vue这个文件中导入刚才新建的组件,“import 组件 from ‘./components/组件.vue’”,然后在进行注册一下,即可在页面上添加刚才新建的组件了。
运行结果:
3. 第三方组件element-ui的使用
由第三方组件element-ui目前仅支持vue2,vue3仍在开发当中,为此,下述项目为vue2。element-ui官网链接为:element-ui
需要注意的是vue2中template下只能有一个直接子标签,而vue3没有限制。下载element-ui命令为:
npm install element-ui
直接在当前项目的文件下运行上述命令即可,然后在mian.js文件中导入element-ui组件,并对这个组件进行全局注册。
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
Vue.use(ElementUI);
之后在一些组件下copy element-ui的组件的源码并进行修改就可以用在自己的项目上了,如下:
<template>
<el-table
:data="tableData"
style="width: 100%"
:row-class-name="tableRowClassName">
<el-table-column
prop="date"
label="日期"
width="180">
</el-table-column>
<el-table-column
prop="name"
label="姓名"
width="180">
</el-table-column>
<el-table-column
prop="address"
label="地址">
</el-table-column>
</el-table>
</template>
<style>
.el-table .warning-row {
background: oldlace;
}
.el-table .success-row {
background: #f0f9eb;
}
</style>
<script>
export default {
methods: {
tableRowClassName({row, rowIndex}) {
if (rowIndex === 1) {
return 'warning-row';
} else if (rowIndex === 3) {
return 'success-row';
}
return '';
}
},
data() {
return {
tableData: [{
date: '2016-05-02',
name: '王小虎',
address: '上海市普陀区金沙江路 1518 弄',
}, {
date: '2016-05-04',
name: '王小虎',
address: '上海市普陀区金沙江路 1518 弄'
}, {
date: '2016-05-01',
name: '王小虎',
address: '上海市普陀区金沙江路 1518 弄',
}, {
date: '2016-05-03',
name: '王小虎',
address: '上海市普陀区金沙江路 1518 弄'
}]
}
}
}
</script>
运行结果:
4. axios网络请求
安装axios,命令为:
npm install axios
在项目中导入
import axios from 'axios'
发起网络请求通常需要涉及到生命周期,在created里边。
这里有一条api接口,如下:
这个接口的端口号为9998,而我的vue项目的端口号为8080,此时会出现跨域问题,跨域也就是请求协议、ip地址及端口号三者不同导致的。
报错信息为:“localhost/:1 Access to XMLHttpRequest at ‘http://localhost:9998/users’ from origin ‘http://localhost:8080’ has been blocked by CORS policy: No ‘Access-Control-Allow-Origin’ header is present on the requested resource.”
解决跨域的问题,通常可以从前端和后端两个进行解决,下面采用的是在后端代码添加配置类来解决跨域问题。
package com.liuze.demo.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class CrosConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**") // 允许跨域访问的路径
.allowedOrigins("*") // 允许跨域访问的源
.allowedMethods("POST","GET","PUT") // 允许的请求方式
.maxAge(168000) // 预检间隔时间
.allowedHeaders("*") // 允许头部设置
.allowCredentials(false); // 是否发送cookie
}
}
另外,也可以在这个控制器类上添加注解“@CrossOrigin”,这样对于整个控制器类下面的接口都是可以生效的。
在页面上进行显示
created:function(){ axios.get("http://localhost:9998/users").then((res)=>{
this.tableData = res.data;
})
}
5. 前端路由VueRouter
通过不同路由,把路径和组件一一映射。
vue-router目前有两个版本,分别为vue-router3.x,vue-router4.x,前者只能和vue2进行结合使用,后者只能和vue3进行结合使用。安装vue-router的命令如下:
npm install vue-router@4
在项目的components组件目录下新建几个组件“.vue”文件,组件文件中写上最简单的结构容易辨别即可。然后在项目的目录下新建router文件夹,在这个目录下新建“index.js”,在这个文件中写路径与组件的映射关系。
import VueRouter from 'vue-router';
import Vue from 'vue';
import Find from '../components/Find.vue'
import Friend from '../components/Friend.vue'
import Music from '../components/Music.vue'
Vue.use(VueRouter)
const router = new VueRouter({
routes: [
{path:"/",redirect:'/find'}, // 重定向
{ path: '/find', component: Find },
{ path: '/friend', component: Friend },
{ path: '/music', component: Music }
]
});
// 导出
export default router
然后在“main.js”文件中把这个router路由导入到vue容器中
import Vue from 'vue'
import App from './App.vue'
import router from './router/index.js'
Vue.config.productionTip = false
new Vue({
render: h => h(App),
router: router
}).$mount('#app')
在“App.vue”主组件上添加“router-link,router-view”标签元素
<template>
<div id="app">
<router-link to="/find">发现</router-link>
<router-link to="/friend">朋友</router-link>
<router-link to="/music">音乐</router-link>
<router-view></router-view>
</div>
</template>
运行结果如下:
动态路由,也就是根据路径中的一些参数不同,从而跳到不同的页面。如在上述“index.js”中给Music添加子组件,如下,
{ path: '/music', component: Music
,children:[
{path:':id',component:MusicItem2}]
}
对应的Music组件为:
<template>
<div>
音乐
<router-link to="/music/1">音乐1</router-link>
<router-link to="/music/2">音乐2</router-link>
<router-view></router-view>
</div>
</template>
组件MusicItem2为:
<template>
<div>
音乐{{$route.params.id}}
</div>
</template>
运行结果: