VUE的简陋实现

按:记录一下VUE学习初期的简陋实现,除编译器外,无需额外安装任何内容;另外简陋的实现与后台的交互。
参考了这篇博客
0. 文件准备
从官网下载vue.js(点击“开发版本”可下载)和axios.jsaxios.map(./dist/文件夹下;若无法访问,可从其余途径下载)文件。

  1. VUE项目的结构
vue-demo
|-- index.html
|-- vue.js
|-- axios.js
|-- axios.map
|-- style.css
  1. style.css
    此文件内容来自vue官网的示例。本随笔采用的是网格组件。

  2. index.html
    此文件的主要内容也是来自网格组件的官方示例。添加的内容实现的是与后台交互。
    完整的内容如下:

点击查看代码
<!DOCTYPE html>
<html>
  <head>
    <title>Grid Component</title>
    <script src="./vue.js"></script> <!--改动点-->
    <script src="./axios.js"></script> <!--改动点-->
    <link rel="stylesheet" type="text/css" href="/style.css" />

    <!-- component template -->
    <script type="text/x-template" id="grid-template">
      <table>
        <thead>
          <tr>
            <th v-for="key in columns"
              @click="sortBy(key)"
              :class="{ active: sortKey == key }">
              {{ key | capitalize }}
              <span class="arrow" :class="sortOrders[key] > 0 ? 'asc' : 'dsc'">
              </span>
            </th>
          </tr>
        </thead>
        <tbody>
          <tr v-for="entry in filteredHeroes">
            <td v-for="key in columns">
              {{entry[key]}}
            </td>
          </tr>
        </tbody>
      </table>
    </script>
    <!-- 改动点 -->
    <script type="text/x-template" id="call-template">
      <table>
        <tbody>
          <tr @click='callLink()'">
            <td >
              answer is: {{answer}}
            </td>
          </tr>
        </tbody>
      </table>
    </script>
  </head>
  <body>
    <!-- demo root element -->
    <div id="demo">
      <form id="search">
        Search <input name="query" v-model="searchQuery" />
      </form>
      <demo-grid
        :heroes="gridData"
        :columns="gridColumns"
        :filter-key="searchQuery"
      >
      </demo-grid>

      <call-demo></call-demo> <!--改动点-->
    </div>

    <script>
      // register the grid component
      Vue.component("demo-grid", {
        template: "#grid-template",
        props: {
          heroes: Array,
          columns: Array,
          filterKey: String
        },
        data: function() {
          var sortOrders = {};
          this.columns.forEach(function(key) {
            sortOrders[key] = 1;
          });
          return {
            sortKey: "",
            sortOrders: sortOrders
          };
        },
        computed: {
          filteredHeroes: function() {
            var sortKey = this.sortKey;
            var filterKey = this.filterKey && this.filterKey.toLowerCase();
            var order = this.sortOrders[sortKey] || 1;
            var heroes = this.heroes;
            if (filterKey) {
              heroes = heroes.filter(function(row) {
                return Object.keys(row).some(function(key) {
                  return (
                    String(row[key])
                      .toLowerCase()
                      .indexOf(filterKey) > -1
                  );
                });
              });
            }
            if (sortKey) {
              heroes = heroes.slice().sort(function(a, b) {
                a = a[sortKey];
                b = b[sortKey];
                return (a === b ? 0 : a > b ? 1 : -1) * order;
              });
            }
            return heroes;
          }
        },
        filters: {
          capitalize: function(str) {
            return str.charAt(0).toUpperCase() + str.slice(1);
          }
        },
        methods: {
          sortBy: function(key) {
            this.sortKey = key;
            this.sortOrders[key] = this.sortOrders[key] * -1;
          }
        }
      });

      <!--改动点-->
      Vue.component("call-demo", {
        data: function(){
            return {answer: 'this is answer.'}
        },
        template: '#call-template',
        methods: {
            callLink: function(){
                var vm = this;
                vm.answer = 'calling ...';
                <!--访问后台-->
                axios.get('http://localhost:8888/demo-system/a?param=123')
                    .then(function(response){
                        vm.answer = response.data;
                  }).catch(function(error){
                        vm.answer = 'Error! '+error;
                });
            }
      }
      });

      // bootstrap the demo
      var demo = new Vue({
        el: "#demo",
        data: {
          searchQuery: "",
          gridColumns: ["name", "power"],
          gridData: [
            { name: "Chuck Norris", power: Infinity },
            { name: "Bruce Lee", power: 9000 },
            { name: "*", power: 7000 },
            { name: "Jet Li", power: 8000 }
          ]
        }
      });
    </script>
  </body>
</html>

  1. 运行
    1)启动后台,确保浏览器访问目的网址可得到json格式的数据(本随笔中的目的网址为: http://localhost:8888/demo-system/a?param=123 );
    2)从浏览器打开index.html或者从编译器启动,点击单元格answer即可。

Tips:

  • 通常,前后端分离后会发生跨域访问错误,需要在前端或者后端进行一些额外的配置,此随笔选择利用注解@CrossOrigin(origins = "*")在后端进行配置,主要参考了这篇文章
  • vue.component的编写参考了这篇文章
上一篇:基准测试JMH的demo


下一篇:PHP获得微信用户的OpenID,然后再通过OpenID和access_token查询用户信息