vue的脚手架工程

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工程本身的组件也是可以替换修改自由组合,极大地提高了前端页面的自由度。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,033评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,725评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,473评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,846评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,848评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,691评论 1 282
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,053评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,700评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,856评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,676评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,787评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,430评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,034评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,990评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,218评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,174评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,526评论 2 343

推荐阅读更多精彩内容