1、Vue的组件
在vue中只要一个index.html,里面只有一个id为app的div标签,内部的具体内容通过.vue类型的组件(component)填充。这个div标签在main.js中被Vue对象托管
new Vue({
el: '#app',
components: {App},
template: '<App/>'
});
组件之间可以相互引用,被引用的组件就是子组件,引用它的组件就是父组件。通过这种父子组件的关系,Vue可以组合显示出各种各样的页面,并且由于组件可以重复使用,所以大大减少的冗余代码。
2、Vue的路由
关于Vue的组件的使用这里只是简单介绍,详细信息不再赘述。Vue的脚手架搭建出来的项目也是可以部署在服务器上被访问到的,那么也就可以在地址栏输入地址获取不同页面。想要做到这一点,需要为脚手架工程安装路由,在项目工程目录下执行以下命令(注意:==不论是npm还是cnpm,在一个Vue工程中,不管是安装什么东西,请一直使用其中一种执行==)
cnpm install vue-router --save
安装了路由管理器(router)后,需要在==main.js==中引入、使用和配置
import Vue from 'vue'
import App from './App'
//引入路由管理器
import VueRouter from "vue-router"
//引入组件
import Home from "./components/Home";
import Hello from "./components/Hello";
import Login from "./components/Login";
import BlogView from "./components/BlogView";
import AddBlog from "./components/AddBlog";
Vue.config.productionTip = false;
//使用路由管理器
Vue.use(VueRouter);
//配置路由
const router = new VueRouter({
routes: [
//path表示地址栏内输入的地址 name表示路由的名字 component表示显示的组件
{path: "/", name: "home", component: Home},
{path: "/blog/list", name: "blog_view", component: BlogView},
{path: "/blog/add", name: "blog_add", component: AddBlog},
{path: "/hello", name: "hello", component: Hello},
{path: "/login", name: "login", component: Login},
],
mode: "history"//去掉浏览器地址栏中出现的#号
});
new Vue({
router,//使用路由
el: '#app',
components: {App},
template: '<App/>'
});
配置完main.js后,最后还需要在App.vue中启用路由标签,这样就能实现根据路由(地址栏地址)显示视图(组件)的效果
<template>
<div id="app">
<!--开启路由视图-->
<router-view></router-view>
</div>
</template>
<script>
export default {
name: 'App',
}
</script>
<style>
#app {
font-family: 'Avenir', Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style>
路由只是前端资源的获取,想要从后端获得数据,还需要通过http请求和接口。
3、Vue通过接口请求后端数据
3.1、 跨域访问
首先要明确一点,前端工程和后端工程是两个不同的工程,它们分别部署。所以前端在请求后端数据的时候,属于跨域访问,受限于同源策略,这种访问会被浏览器禁止,所以我们要设置一个代理,绕过同源策略向后端发送请求。在==index.js==中设置代理:
// Paths
assetsSubDirectory: 'static',
assetsPublicPath: '/',
proxyTable: {
// /api指向下面的target
'/api': {
// target就是后端项目的接口 根据实际情况配置
target: "http(s)://ip地址:端口/项目名(根据实际情况)",
changeOrigin: true,
pathRewrite: {
'^/api': ''
}
}
}
3.2、安装配置axios
在Vue中推荐我们使用axios发送ajax请求,要想使用axios首先还是在Vue脚手架工程目录下运行命令,安装axios
cnpm install axios
安装完axios后,在==main.js==中进行引入配置
// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue'
import App from './App'
//引人axios
import axios from "axios"
Vue.config.productionTip = false;
//axios的使用
Vue.prototype.axios = axios; //全局axios对象设置
axios.defaults.headers.post['Content-Type'] = 'application/json';
new Vue({
el: '#app',
components: {App},
template: '<App/>'
});
配置了全局的axios后,在所有组件中就可以直接使用,不需要重复引入。
3.3、使用axios
在组件中使用axios:
<template>
<div id="show-blogs">
<h1>博客总览</h1>
<div class="single-blog" v-for="blog in blogs">
<h2 v-rainbow>{{blog.title | to_uppercase}}</h2>
<article v-theme>
{{blog.body| snippet}}
</article>
</div>
</div>
</template>
<script>
export default {
name: "BlogView",
data() {
return {
blogs: []
}
},
//钩子函数 Vue实例创建后立即发送请求
created() {
//this.axios是因为我们配置了全局的axios,所以加上this,get表示这是一个get请求
// /api/blog/list相当于:http(s)://ip地址:端口/项目名(根据实际情况)/blog/list
//.then处理响应结果
this.axios.get("/api/blog/list").then(
//这里使用es6的箭头函数,因为这个函数不会重新绑定this变量,这样this.blogs指向的就是
//data里的blogs
(data) => {
this.blogs = data.data.map.blogs;
}
)
},
}
</script>
<style>
#show-blogs {
max-width: 800px;
margin: 0 auto;
}
.single-blog {
padding: 20px;
margin: 20px 0;
box-sizing: border-box;
background-color: #eee;
}
</style>
这样博客的数据就能从后端请求过来,通过Vue渲染到组件,展示出来。axios向后端传参的时候需要注意一点:
<template>
<div id="add-blog">
<h2>添加博客</h2>
<form v-if="!submited">
<label>博客标题</label>
<input type="text" v-model="blog.title"/>
<label>博客内容</label>
<textarea v-model="blog.content"></textarea>
<div id="checkboxs">
<label>Vue.js</label>
<input type="checkbox" value="Vue.js" v-model="blog.categories"/>
<label>Node.js</label>
<input type="checkbox" value="Node.js" v-model="blog.categories"/>
<label>React.js</label>
<input type="checkbox" value="React.js" v-model="blog.categories"/>
<label>Angular3.js</label>
<input type="checkbox" value="Angular3.js" v-model="blog.categories"/>
</div>
<label>作者</label>
<select v-model="blog.author">
<option v-for="a in authors">
{{a}}
</option>
</select>
<button @click.prevent="addBlog">AddBlog</button>
</form>
<hr/>
<div v-if="submited">
<h2>您的博客发布{{msg}}。。。</h2>
</div>
<div id="preview">
博客标题 :{{blog.title}} <p/>
博客内容 :{{blog.content}} <p/>
<p v-for="c in blog.categories">
{{c}}
</p>
作者 :{{blog.author}}
</div>
</div>
</template>
<script>
export default {
data() {
return {
blog: {
title: "",
content: "",
categories: [],
author: ""
},
authors: ["jim", "tom", "lucy"],
submited: false,
msg: "失败"
}
},
methods: {
addBlog: function () {
//把文章的分类合成一个字符串,用逗号","隔开
let cg = "";
this.blog.categories.forEach(e => {
cg += "," + e;
});
cg = cg.substring(1);
//发送post请求
this.axios.post("/api/blog/add", {//传递参数这里和jqury基本相同
title: this.blog.title,
content: this.blog.content,
author: this.blog.author,
categories: cg
}).then((data) => {
if (data.data.code == "200") {
this.msg = "成功";
}
this.submited = true;
console.log(data);
}).catch(function (error) {
console.log(error);
});
}
}
}
</script>
<style scoped>
#add-blog * {
box-sizing: border-box;
}
#add-blog {
margin: 20px auto;
max-width: 800px;
padding: 20px;
}
label {
display: block;
margin: 20px 0 10px;
}
input[type=text], textarea, select {
display: block;
width: 100%;
padding: 8px;
}
#checkboxs label {
display: inline-block;
margin-top: 5px;
}
#checkboxs input {
display: inline-block;
margin-right: 10px;
}
textarea {
height: 100px;
}
button {
display: block;
margin: 20px 0;
background-color: crimson;
border: 0;
cursor: pointer;
padding: 14px;
border-radius: 4px;
font-size: 18px;
}
#preview {
border: 1px solid #ccc;
padding: 15px;
}
</style>
在上面的例子中,发送带参数的请求其实和jquery没什么太大的区别,但是axios和jquery对参数的封装不同,在jquery中数据可以用对应类型变量一个个接收,也可以通过对象接收;而然对于==POST==请求,==axios发送出去的数据必须使用对象接收,而且要求后端使用json格式解析,如果是springMVC或者springboot,那就必须使用一个对象或者Map集合并且加上@RequestBody注解接收参数==,对于==GET==请求,==必须在参数前面加上@RequestParam==。
4、总结
前后端分离,后端提供接口,前端请求获得数据后渲染到视图上,这样前后端就实现了解耦合。只要按照约定的格式和接口交换数据,那么前后端之间就可以自由组合,完全不会影响到整个项目的运行。比如需要更新前端的界面设计,只需要修改前端代码,在修改完成后替换现有前端工程,后端完全不需要做任何更改。而且Vue工程本身的组件也是可以替换修改自由组合,极大地提高了前端页面的自由度。