vue 笔记

表严肃vue笔记

引言

v-model: 绑定data中的属性,input中输入的内容会显示在下面的span中。双向绑定。

<div id="app">
    <div>
        <input type="text" v-model="name">
        <span v-show="name">你的名字是:{{name}}</span>
    </div>
    <div>
        <input type="text" v-model="age">
        <span v-show="age">你的年龄是:{{age}}</span>
    </div>
    <div>
        <input type="text" v-model="sex">
        <span v-show="sex">你的性别是:{{sex}}</span>
    </div>
</div>
//双花括号中的语句vue会把他当成一种类js的语言来解析,会解析一部分js语句,比如 typeof 1 不会报错,但是如果是if(1) return '11'就会报错。

aaaa

var app = new Vue({
  el: '#app',
  data: {
    name: null,
    age: null,
    sex: null,
  }
});
//el告诉vue 他应该和哪个元素绑定,也就是生成的对象应该作用的是哪个域,这个作用在id为app的元素上面。

v-for指令

<div id="app">
    <ul>
        <li v-for="food in foodList">{{food.name}}:¥{{food.discount? food.price * food.discount : food.price}}</li>
    </ul>
</div>

main.js

var app = new Vue({
  el: '#app',
  data: {
    // foodList: ['葱', '姜', '蒜'],
    foodList: [
      {
        name: '葱',
        price: 10,
        discount: .8,
      },
      {
        name: '姜',
        price: 5,
        discount: .5
      },
      {
        name: '蒜',
        price: 4.5,
      },
    ],
  }
});

v-bind 指令

绑定标签的属性为data中的属性值,可以省略用冒号代替

<div id="app">
    <a :class="{active: isActive}" :href="url">
        点我
        <!--<img :src="img">-->
    </a>
</div>

main.js

var app = new Vue({
  el: '#app',
  data: {
    url: 'http://baidu.com',
    img: 'https://dummyimage.com/100x100/ffcc00/ffffff',
    klass: 'btn btn-default',
    isActive: true,
  }
});

v-on 指令

用于绑定事件的。v-on:click可以简写为@click

绑定多个事件:v-on="{mouseenter: onEnter, mouseleave: onOut}",键是事件名,值是触发的方法。

@submit.prevent 阻止提交之后的默认get或者post,造成整个页面刷新的行为

@submit.prevent 阻止冒泡行为。

<div id="app">
    <button v-on="{mouseenter: onEnter, mouseleave: onOut}" @click="onClick">点我</button>
    <form @keyup.enter="onEnter" @submit.prevent="onSubmit">
        <input type="text">
        <button type="submit">提交</button>
    </form>
</div>

mian.js

    
var app = new Vue({
  el: '#app',
  methods: {
    onClick: function () {
      console.log('clicked');
    },

    onEnter: function () {
      console.log('mouse enter');
    },

    onOut: function () {
      console.log('mouse leave');
    },

    onSubmit: function () {
      console.log('submitted');
    },

    onEnter: function () {
      console.log('entered');
    },
  }
});

v-model指令

  • 数据双向绑定
  • v-model.lazy 惰性更新,只有当鼠标blur的时候才会更新。v-model.trim 删除前后空格。
  • v-model.mumber 转化为数字类型。
  • v-model可以在imput,textarea,seclect 三种情况下使用。
<div id="app">
    <!--<label>-->
    <!--单选框-->
    <!--男-->
    <!--<input v-model="sex" value="male" type="checkbox">-->
    <!--</label>-->
    <!--<label>-->
    <!--女-->
    <!--<input v-model="sex" value="female" type="checkbox">-->
    <!--</label>-->
    <!--<br>-->
    <!--{{sex}}-->
    <!--<textarea v-model="article"></textarea>-->
    <!--多选框-->
    <div>你来自哪里?</div>
    <select v-model="from">
        <option value="1">王家沟</option>
        <option value="2">背背山</option>
    </select>
    {{from}}
    <div>你要去哪里?</div>
    <!--多选框可以多选,按住ctrl可以多选-->
    <select v-model="dest" multiple>
        <option value="1">王家沟</option>
        <option value="2">背背山</option>
        <option value="3">背背山</option>
        <option value="4">背背山</option>
        <option value="5">背背山</option>
    </select>
    {{dest}}
</div>

main.js

var app = new Vue({
  el: '#app',
  data: {
    from: 1,
    dest: []
    // sex: ['male']
    // article: `Lorem ipsum dolor sit amet, consectetur adipisicing elit. Beatae blanditiis eos fugit id inventore iure, laborum laudantium magnam minima non nostrum nulla perspiciatis quasi quibusdam repellendus temporibus tenetur totam voluptatem.`
  }
});

控制流指令

<div id="app">
    <div v-if="role == 'admin' || role == 'super_admin'">
        管理员你好
    </div>
    <div v-else-if="role == 'hr'">
        待查看简历列表:<br>
        ...
    </div>
    <div v-else>
        您没有权限访问此页面
    </div>
</div>

main.js

var app = new Vue({
  el: '#app',
  data: {
    role: 'super_admin'
  }
});

计算属性

如果filter比较复杂,考虑要不要使用计算属性,因为计算属性有缓存,计算能力比较强。

<div id="app">
    <table border="1">
        <thead>
        <th>学科</th>
        <th>分数</th>
        </thead>
        <tbody>
        <tr>
            <td>数学</td>
            <td><input type="text" v-model="math"></td>
        </tr>
        <tr>
            <td>物理</td>
            <td><input type="text" v-model="physics"></td>
        </tr>
        <tr>
            <td>英语</td>
            <td><input type="text" v-model="english"></td>
        </tr>
        <tr>
            <td>总分</td>
            <td>{{sum}}</td>
        </tr>
        <tr>
            <td>平均分</td>
            <td>{{average}}</td>
        </tr>
        </tbody>
    </table>
</div>

main.js

var app = new Vue({
  el: '#app',
  data: {
    math: 90,
    physics: 80,
    english: 30,
  },
  computed: {
    sum: function () {
      return parseFloat(this.math) + parseFloat(this.physics) + parseFloat(this.english);
    },
    average: function () {
      return Math.round(this.sum / 3);
    }
  },
});

组件

全局及局部组件

<div id="seg1">
    <alert></alert>
</div>
<div id="seg2">

</div>

main.js

//全局组件
new Vue("alert",)
//局部组件
var alert_component = {
  template: '<button @click="on_click">弹弹弹</button>',
  methods: {
    on_click: function () {
      alert('Yo.');
    }
  }
};

new Vue({
  el: '#seg1',
  components: {
    alert: alert_component
  }
});

new Vue({
  el: '#seg2'
});


配置组件

<style>
        .liked {
            background: deeppink;
        }
    </style>
<div id="app">
    <like></like>
</div>
<template id="like-component-tpl">
    <button :class="{liked: liked}" @click="toggle_like()">
        👍 {{like_count}}
    </button>
</template>

main.js

Vue.component('like', {
  template: '#like-component-tpl',
  data: function () {
    return {
      like_count: 10,
      liked: false,
    }
  },
  methods: {
    toggle_like: function () {
      if (!this.liked)
        this.like_count++;
      else
        this.like_count--;

      this.liked = !this.liked;
    }
  }
})

new Vue({
  el: '#app',
})

父子组件

父组件跟子组件通信

props 接收的是使用这个组件的div 传来的值,可以在methods中使用。

index.html

<div id="app">
    <user :username='username'></user>
</div>

main.js

//子组件
Vue.component('user', {
  template: '<a :href="\'/user/\' + username">@{{username}}</a>',
  props: ['username'],
  methods: {}
})
//父组件
new Vue({
  el: '#app',
  data: {
      username:2,
   }
})

props 接收的是使用这个组件的div 传来的值,可以在methods或者template中使用。

分三步走:

  • 在父组件中给要用的值赋值 username:2,
  • 在props里面声明一下,说他等一下要引用父组件的数据props: ['username']
  • 用到这个组件的时候,在标签里说明一下,,user引用的是username:2 的这个值。

子组件跟父组件通信

<div id="app">
    <balance></balance>
</div>

//父组件
Vue.component('balance', {
  template: `
  <div>
    <show @show-balance="show_balance"></show>
    <div v-if="show">
    您的余额:¥98逸
    </div>
  </div>
  `,
  methods: {
    show_balance: function(data) {
      this.show = true;
      console.log('data:', data);
      
    }
  },
  data: function() {
    return {
      show: false,
    }
  }
});
//子组件
Vue.component('show', {
  template: '<button @click="on_click()">显示余额</button>',
  methods: {
    on_click() {
      this.$emit('show-balance', {a: 1, b:  2});
    }
  }
});
// this.$emit触发事件,在父组件中使用这个组件的地方监听。
new Vue({
  el: '#app',
})

平行组件通信

<div id="app">
    <huahua></huahua>
    <shuandan></shuandan>
</div>

var Event = new Vue();

Vue.component('huahua', {
  template: `
    <div>
        我说:<input @keyup="on_change" v-model="i_said"/>
    </div>`,
  methods: {
    on_change: function () {
      Event.$emit('huahua-said-something', this.i_said);
    }
  },
  data: function () {
    return {
      i_said: '',
    }
  }
})
Vue.component('shuandan', {
  template: `<div>花花说:{{huahua_said}}</div>`,
  data: function () {
    return {
      huahua_said: '',
    };
  },
  mounted: function () {
    var me = this;
    Event.$on('huahua-said-something', function(data) {
      me.huahua_said = data;
    });
  }
})

new Vue({
  el: '#app',
})

过滤器

{{length | meter}} 通过管道符 | 把length 传到后面的meter过滤器中。

filter不会修改原始数据,就像解决最后一公里的问题。

<div id="app">
    <div>
        <input v-model="length"> mm
        <br>
        {{length | meter}}
    </div>
    <hr>
    <div>
        <input v-model="price">
        <br>
        {{ price | currency('USD') }}
    </div>
</div>

main.js

Vue.filter('meter', function (val, unit) {
  val = val || 0;
  unit = unit || 'm';
  return (val / 1000).toFixed(2) + unit;
});

Vue.filter('currency', function (val, unit) {
  val = val || 0;
  unit = unit || '元';
  return val + unit;
});

new Vue({
  el: '#app',
  data: {
    price: 10,
    length: 10,
  }
})

自定义指令

组件是游戏里的英雄,指令就是英雄的技能。一个英雄可以有多种技能,不同的英雄可以有相同的技能也是可以的。

<!doctype html>
<html lang="zh-cn">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Example</title>
    <style>
        .card {
            width: 200px;
            background: #ccc;
            padding: 10px;
            margin: 5px;
        }
    </style>
</head>
<body>
<div id="app">
    <div v-pin="card1.pinned" class="card">
        <button @click="card1.pinned = !card1.pinned">钉住/取消</button>
        Lorem ipsum dolor sit amet, consectetur
    </div>
    <div v-pin="card2.pinned" class="card">
        <a @click="card2.pinned = !card2.pinned" href="#">pin it</a>
        Lorem ipsum dolor sit amet, consectetur
    </div>

    <div>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Adipisci beatae, est fugit obcaecati optio quibusdam
        repellat sit temporibus voluptate. In molestiae natus nostrum quam soluta ut veniam vero voluptate voluptatibus?
    </div>
    <div>Adipisci culpa cumque debitis doloremque hic illum in necessitatibus non. Accusamus ad animi cupiditate debitis
        dolorem, eveniet exercitationem explicabo maiores natus odit optio perferendis quasi recusandae sed similique
        tempore temporibus.
    </div>
    <div>Adipisci commodi deleniti dicta dolor eaque enim excepturi exercitationem, explicabo facere in libero magnam
        nam nobis officiis quibusdam quo quod, sapiente veniam vero voluptatum! Aliquam doloribus facere odit quas
        voluptas.
    </div>
    <div>At cumque illum in iure maiores necessitatibus quaerat repudiandae temporibus ut voluptatibus! Aliquid autem
        deleniti doloribus est, minus mollitia natus nemo possimus quae quia repellat sed unde veniam vitae voluptatem!
    </div>
    <div>Eligendi impedit necessitatibus nisi, possimus repudiandae soluta tempora vero! Corporis earum, impedit minus
        nemo odio omnis quisquam sequi? Accusamus alias aspernatur optio praesentium rerum vel! Adipisci doloribus minus
        nesciunt quos?
    </div>
    <div>Ab ad animi blanditiis fuga ipsum itaque qui sapiente soluta! At consectetur eum facilis iste itaque magni
        molestiae officia provident tenetur veniam! Ea error est eum itaque nesciunt similique voluptas?
    </div>
    <div>Adipisci eius excepturi fuga fugit in quo reprehenderit suscipit, temporibus? Accusantium adipisci aliquid
        beatae, corporis cum eligendi, expedita fuga fugiat mollitia necessitatibus sapiente sequi tempora totam,
        voluptatem voluptates! Officiis, perferendis!
    </div>
    <div>Alias consequuntur cumque dignissimos laborum perspiciatis? Eum eveniet ex harum laboriosam laborum libero
        maiores quos vel? Debitis doloribus, dolorum eaque, ex modi, molestiae necessitatibus numquam quas quibusdam
        repudiandae temporibus voluptates.
    </div>
    <div>Asperiores beatae libero neque quae quasi. Alias corporis dicta dolor eum id, ipsam nam natus nihil numquam
        praesentium quisquam recusandae, rerum saepe, tempore unde ut voluptatem. Cupiditate dolore quae sapiente?
    </div>
    <div>Blanditiis cupiditate facilis laudantium maiores molestias, nesciunt odit tempora tenetur. Accusamus alias
        aliquam architecto asperiores beatae consectetur cumque enim iste laboriosam nisi possimus, quidem quis quos
        ullam ut voluptate voluptatum?
    </div>
</div>
<script src="../lib/vue.js"></script>
<script src="js/main.js"></script>
</body>
</html>

main.js

Vue.directive('pin', function (el, binding) {
  //binging.value=true;
  var pinned = binding.value;
  if (pinned) {
    el.style.position = 'fixed';
    el.style.top = '10px';
    el.style.left = '10px';
  } else {
    el.style.position = 'static';
  }
})

new Vue({
  el: '#app',
  data: {
    card1: {
      pinned: false,
    },
    card2: {
      pinned: false,
    },
  }
})

配置传参

<div id="app">
    <div v-pin:true.bottom.left="card1.pinned" class="card">
        <button @click="card1.pinned = !card1.pinned">钉住/取消</button>
        Lorem ipsum dolor sit amet, consectetur
    </div>
    <div v-pin="card2.pinned" class="card">
        <a @click="card2.pinned = !card2.pinned" href="#">pin it</a>
        Lorem ipsum dolor sit amet, consectetur
    </div>

    <div>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Adipisci beatae, est fugit obcaecati optio quibusdam
        repellat sit temporibus voluptate. In molestiae natus nostrum quam soluta ut veniam vero voluptate voluptatibus?
    </div>
    <div>Adipisci culpa cumque debitis doloremque hic illum in necessitatibus non. Accusamus ad animi cupiditate debitis
        dolorem, eveniet exercitationem explicabo maiores natus odit optio perferendis quasi recusandae sed similique
        tempore temporibus.
    </div>
    <div>Adipisci commodi deleniti dicta dolor eaque enim excepturi exercitationem, explicabo facere in libero magnam
        nam nobis officiis quibusdam quo quod, sapiente veniam vero voluptatum! Aliquam doloribus facere odit quas
        voluptas.
    </div>
    <div>At cumque illum in iure maiores necessitatibus quaerat repudiandae temporibus ut voluptatibus! Aliquid autem
        deleniti doloribus est, minus mollitia natus nemo possimus quae quia repellat sed unde veniam vitae voluptatem!
    </div>
    <div>Eligendi impedit necessitatibus nisi, possimus repudiandae soluta tempora vero! Corporis earum, impedit minus
        nemo odio omnis quisquam sequi? Accusamus alias aspernatur optio praesentium rerum vel! Adipisci doloribus minus
        nesciunt quos?
    </div>
    <div>Ab ad animi blanditiis fuga ipsum itaque qui sapiente soluta! At consectetur eum facilis iste itaque magni
        molestiae officia provident tenetur veniam! Ea error est eum itaque nesciunt similique voluptas?
    </div>
    <div>Adipisci eius excepturi fuga fugit in quo reprehenderit suscipit, temporibus? Accusantium adipisci aliquid
        beatae, corporis cum eligendi, expedita fuga fugiat mollitia necessitatibus sapiente sequi tempora totam,
        voluptatem voluptates! Officiis, perferendis!
    </div>
    <div>Alias consequuntur cumque dignissimos laborum perspiciatis? Eum eveniet ex harum laboriosam laborum libero
        maiores quos vel? Debitis doloribus, dolorum eaque, ex modi, molestiae necessitatibus numquam quas quibusdam
        repudiandae temporibus voluptates.
    </div>
    <div>Asperiores beatae libero neque quae quasi. Alias corporis dicta dolor eum id, ipsam nam natus nihil numquam
        praesentium quisquam recusandae, rerum saepe, tempore unde ut voluptatem. Cupiditate dolore quae sapiente?
    </div>
    <div>Blanditiis cupiditate facilis laudantium maiores molestias, nesciunt odit tempora tenetur. Accusamus alias
        aliquam architecto asperiores beatae consectetur cumque enim iste laboriosam nisi possimus, quidem quis quos
        ullam ut voluptate voluptatum?
    </div>
</div>

main.js

Vue.directive('pin', function (el, binding) {

  var pinned = binding.value;
  var position = binding.modifiers;
  var warning = binding.arg;

  if (pinned) {
    el.style.position = 'fixed';

    for (var key in position) {
      if (position[key]) {
        el.style[key] = '10px';
      }
    }
    if (warning === 'true') {
      el.style.background = 'yellow';
    }
  } else {
    el.style.position = 'static';
  }
})

new Vue({
  el: '#app',
  data: {
    card1: {
      pinned: false,
    },
    card2: {
      pinned: false,
    },
  }
})

混合mixins

重复功能和数据的储存器

<div id="app">
    <tooltip></tooltip>
    <popup></popup>
</div>

main.js

var base = {
  methods: {
    show: function () {
      this.visible = true;
    },
    hide: function () {
      this.visible = false;
    },
    toggle: function () {
      this.visible = !this.visible;
    }
  },
  data: function () {
    return {
      visible: false,
    }
  }
};

Vue.component('tooltip', {
  template: `
  <div>
    <span @mouseenter="show" @mouseleave="hide">bys</span>
    <div v-if="visible">
    白岩松
    </div>
  </div>
  `,
  mixins: [base],
  data: function () {
    return {
      visible: true,
    }
  }
});

Vue.component('popup', {
  template: `
  <div>
    <button @click="toggle">Popup</button>
        <div v-if="visible">
        <span @click="hide">X</span>
          <h4>title</h4>
    Lorem ipsum dolor sit amet, consectetur adipisicing elit. Amet dolorum, iusto non nostrum porro ratione. Dolor dolorem id impedit. Dolore excepturi exercitationem incidunt iste magnam odio quas temporibus. Assumenda, magni.
        </div>
  </div>
  `,
  mixins: [base]
});

new Vue({
  el: '#app',
  data: {}
})

插槽

<div id="app">
    <panel>
        <div slot="title">
            Yo.
        </div>
        <div slot="content">
            Yo
            Yo
            Yo
        </div>
    </panel>
</div>
<template id="panel-tpl">
    <div class="panel">
        <div class="title">
            <slot name="title"></slot>
        </div>
        <div class="content">
            <slot name="content"></slot>
        </div>
        <div class="footer">
            <slot name="footer">
                更多信息
            </slot>
        </div>
    </div>

main.js

Vue.component('panel', {
  template: '#panel-tpl',
})

new Vue({
  el: '#app',
  data: {}
})

路由

不需要整页刷新,只需要拿一次数据。节省资源。

不管点击的是哪个链接,最后的结果应该渲染在这里。

安装和基本配置

<div id="app">
    <div>
        <router-link to="/">首页</router-link>
        <router-link to="/about">关于我们</router-link>
    </div>
    <div>
        <router-view></router-view>
    </div>
</div>
<script src="../lib/vue.js"></script>
<script src="../lib/router.js"></script>
<script src="app.js"></script>

app.js

var routes = [
  {
    path: '/',
    component: {
      template: `
      <div>
        <h1>首页</h1>
      </div>
      `,
    },
  },
  {
    path: '/about',
    component: {
      template: `
      <div>
        <h1>关于我们</h1>
      </div>
      `,
    },
  },
];

var router = new VueRouter({
  routes: routes,
});

new Vue({
  el: '#app',
  router: router,
});

传参及获取传参

第一种方式:params

  • 王花花

  • path: '/user/:name',

  • 我叫:{{$route.params.name}}

第二种方式 query

  • 在浏览器的链接中输入?age=11

  • 我今年:{{$route.query.age}}岁了
<div id="app">
    <div>
        <router-link to="/">首页</router-link>
        <router-link to="/about">关于我们</router-link>
        <router-link to="/user/王花花">王花花</router-link>
        <router-link to="/user/李拴蛋">李拴蛋</router-link>
    </div>
    <div>
        <router-view></router-view>
    </div>
</div>

app.js

var routes = [
  {
    path: '/',
    component: {
      template: `
      <div>
        <h1>首页</h1>
      </div>
      `,
    },
  },
  {
    path: '/about',
    component: {
      template: `
      <div>
        <h1>关于我们</h1>
      </div>
      `,
    },
  },
  {
    path: '/user/:name',
    component: {
      template: `
      <div>
        <div>我叫:{{$route.params.name}}</div>
        <div>我今年:{{$route.query.age}}岁了</div>
      </div>
      `,
    },
  },
];

var router = new VueRouter({
  routes: routes,
});

new Vue({
  el: '#app',
  router: router,
});

手动访问和传参

通过触发按钮事件改变路由

<div id="app">
    <div>
        <router-link to="/">首页</router-link>
        <router-link to="/about">关于我们</router-link>
        <router-link to="/user/王花花">王花花</router-link>
        <router-link to="/user/李拴蛋">李拴蛋</router-link>
        <button @click="surf">漫游</button>
    </div>
    <div>
        <router-view></router-view>
    </div>
</div>

app.js

var routes = [
  {
    path: '/',
    component: {
      template: `
      <div>
        <h1>首页</h1>
      </div>
      `,
    },
  },
  {
    path: '/about',
    component: {
      template: `
      <div>
        <h1>关于我们</h1>
      </div>
      `,
    },
  },
  {
    path: '/user/:name',
    component: {
      template: `
      <div>
        <div>我叫:{{$route.params.name}}</div>
        <router-link to="more" append>更多信息</router-link>
        <router-view></router-view>
      </div>
      `,
    },
    children: [
      {
        path: 'more',
        component: {
          template: `
          <div>
          用户{{$route.params.name}}的详细信息
          Lorem ipsum dolor sit amet, consectetur adipisicing elit. Adipisci cum deleniti doloribus expedita inventore natus officiis quod quos similique voluptate! Distinctio nisi sequi tenetur voluptatum? Debitis iste neque pariatur voluptatibus?
           </div>
          `
        }
      }
    ]
  },
];

var router = new VueRouter({
  routes: routes,
});

new Vue({
  el: '#app',
  router: router,
  methods:{
    surf:function(){
      setTimeout(function(){
          this.router.push('/about')
      },2000)
    }
  }
});

子路由以及路由应该怎么添加

添加方式:更多信息 append表示增加的意思。

<div id="app">
    <div>
        <router-link to="/">首页</router-link>
        <router-link to="/about">关于我们</router-link>
        <router-link to="/user/王花花">王花花</router-link>
        <router-link to="/user/李拴蛋">李拴蛋</router-link>
    </div>
    <div>
        <router-view></router-view>
    </div>
</div>

app.js

var routes = [
  {
    path: '/',
    component: {
      template: `
      <div>
        <h1>首页</h1>
      </div>
      `,
    },
  },
  {
    path: '/about',
    component: {
      template: `
      <div>
        <h1>关于我们</h1>
      </div>
      `,
    },
  },
  {
    path: '/user/:name',
    component: {
      template: `
      <div>
        <div>我叫:{{$route.params.name}}</div>
        <router-link to="more" append>更多信息</router-link>
        <router-view></router-view>
      </div>
      `,
    },
    children: [
      {
        path: 'more',
        component: {
          template: `
          <div>
          用户{{$route.params.name}}的详细信息
          Lorem ipsum dolor sit amet, consectetur adipisicing elit. Adipisci cum deleniti doloribus expedita inventore natus officiis quod quos similique voluptate! Distinctio nisi sequi tenetur voluptatum? Debitis iste neque pariatur voluptatibus?
           </div>
          `
        }
      }
    ]
  },
];

var router = new VueRouter({
  routes: routes,
});

new Vue({
  el: '#app',
  router: router,
});

命名视图


pat对应的components 里面两个component,名字 和router-view 中name的值相同。

<div id="app">
    <div>
        <router-link to="/">首页</router-link>
        <router-link to="/user">用户管理</router-link>
        <router-link to="/post">帖子管理</router-link>
    </div>
    <div>
        <router-view name="sidebar"></router-view>
        <router-view name="content"></router-view>
    </div>
</div>

app.js

var routes = [
  {
    path: '/',
    component: {
      template: `
      <div>
        <h1>首页</h1>
      </div>
      `,
    }
  },
  {
    path: '/user',
    components: {
      sidebar: {
        template: `
        <div>
          <ul>
              <li>用户列表</li>
              <li>权限管理</li>
          </ul>
        </div>
        `
      },
      content: {
        template: `
            <div>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Deleniti in, laborum molestias necessitatibus optio perferendis quaerat quas qui quisquam sapiente. Architecto corporis eos eum libero optio, perspiciatis quo rem vel!</div>
        `
      }
    }
  },
  {
    path: '/post',
    components: {
      sidebar: {
        template: `
        <div>
          <ul>
              <li>帖子列表</li>
              <li>标签管理</li>
          </ul>
        </div>
        `
      },
      content: {
        template: `
            <div>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Deleniti in, laborum molestias necessitatibus optio perferendis quaerat quas qui quisquam sapiente. Architecto corporis eos eum libero optio, perspiciatis quo rem vel!</div>
        `
      }
    }
  }
];

var router = new VueRouter({
  routes: routes,
});

new Vue({
  el: '#app',
  router: router,
});

导航钩子

可以理解为路由的生命周期或者理解为中间件

<div id="app">
    <div>
        <router-link to="/">首页</router-link>
        <router-link to="/login">登录</router-link>
        <router-link to="/post">帖子管理</router-link>
    </div>
    <div>
        <router-view></router-view>
    </div>
</div>

app.js

var routes = [
  {
    path: '/',
    component: {
      template: `<h1>首页</h1>`
    }
  },
  {
    path: '/login',
    component: {
      template: `<h1>登录</h1>`
    }
  },
  {
    path: '/post',
    component: {
      template: `<h1>帖子管理</h1>`
    }
  },
];

var router = new VueRouter({
  routes: routes,
});

router.beforeEach(function (to, from, next) {
  var logged_in = true;

  if (!logged_in && to.path == '/post')
    next('/login');
  else
    next();
});

router.afterEach(function (to, from) {

});

new Vue({
  el: '#app',
  router: router,
});


元数据及路由匹配

meta 对当前路由的自定义属性

to.matched 是一个数组。

<div id="app">
    <div>
        <router-link to="/">首页</router-link>
        <router-link to="/login">登录</router-link>
        <router-link to="/post">文章管理</router-link>
        <router-link to="/a">A</router-link>
    </div>
    <div>
        <router-view></router-view>
    </div>
</div>

app.js

var routes = [
  {
    path: '/',
    component: {
      template: `<h1>首页</h1>`
    }
  },
  {
    path: '/a',
    meta: {
      login_required: true,
    },
    component: {
      template: `<h1>A</h1>`
    }
  },
  {
    path: '/login',
    component: {
      template: `<h1>登录</h1>`
    }
  },
  {
    path: '/post',
    meta: {
      login_required: true
    },
    component: {
      template: `<div>
        <h1>帖子管理</h1>
        <router-link to="rain" append>后座</router-link>
        <router-view></router-view>
      </div>`,
    },
    children: [
      {
        path: 'rain',
        component: {
          template: `<h2>雨天asdf后座</h2>`
        }
      }
    ]
  },
];

var router = new VueRouter({
  routes: routes,
});

router.beforeEach(function (to, from, next) {
  var logged_in = true;

  if (!logged_in && to.matched.some(function (item) {
      return item.meta.login_required;
    }))
    next('/login');
  else
    next();
});

new Vue({
  el: '#app',
  router: router,
});


watch属性的使用

考虑一个问题:想要实现 两个文本框的内容改变,则全名的文本框中的值也跟着改变;(用以前的知识如何实现???)

  1. 监听data中属性的改变:
<div id="app">
    <input type="text" v-model="firstName"> +
    <input type="text" v-model="lastName"> =
    <span>{{fullName}}</span>
  </div>

  <script>
    // 创建 Vue 实例,得到 ViewModel
    var vm = new Vue({
      el: '#app',
      data: {
        firstName: 'jack',
        lastName: 'chen',
        fullName: 'jack - chen'
      },
      methods: {},
      watch: {
        'firstName': function (newVal, oldVal) { // 第一个参数是新数据,第二个参数是旧数据
          this.fullName = newVal + ' - ' + this.lastName;
        },
        'lastName': function (newVal, oldVal) {
          this.fullName = this.firstName + ' - ' + newVal;
        }
      }
    });
  </script>

  1. 监听路由对象的改变:
<div id="app">
    <router-link to="/login">登录</router-link>
    <router-link to="/register">注册</router-link>

    <router-view></router-view>
  </div>

  <script>
    var login = Vue.extend({
      template: '<h1>登录组件</h1>'
    });

    var register = Vue.extend({
      template: '<h1>注册组件</h1>'
    });

    var router = new VueRouter({
      routes: [
        { path: "/login", component: login },
        { path: "/register", component: register }
      ]
    });

    // 创建 Vue 实例,得到 ViewModel
    var vm = new Vue({
      el: '#app',
      data: {},
      methods: {},
      router: router,
      watch: {
        '$route': function (newVal, oldVal) {
          if (newVal.path === '/login') {
            console.log('这是登录组件');
          }
        }
      }
    });
  </script>

computed计算属性的使用

  1. 默认只有getter的计算属性:
<div id="app">
    <input type="text" v-model="firstName"> +
    <input type="text" v-model="lastName"> =
    <span>{{fullName}}</span>
  </div>

  <script>
    // 创建 Vue 实例,得到 ViewModel
    var vm = new Vue({
      el: '#app',
      data: {
        firstName: 'jack',
        lastName: 'chen'
      },
      methods: {},
      computed: { // 计算属性; 特点:当计算属性中所以来的任何一个 data 属性改变之后,都会重新触发 本计算属性 的重新计算,从而更新 fullName 的值
        fullName() {
          return this.firstName + ' - ' + this.lastName;
        }
      }
    });
  </script>

  1. 定义有gettersetter的计算属性:
<div id="app">
    <input type="text" v-model="firstName">
    <input type="text" v-model="lastName">
    <!-- 点击按钮重新为 计算属性 fullName 赋值 -->
    <input type="button" value="修改fullName" @click="changeName">

    <span>{{fullName}}</span>
  </div>

  <script>
    // 创建 Vue 实例,得到 ViewModel
    var vm = new Vue({
      el: '#app',
      data: {
        firstName: 'jack',
        lastName: 'chen'
      },
      methods: {
        changeName() {
          this.fullName = 'TOM - chen2';
        }
      },
      computed: {
        fullName: {
          get: function () {
            return this.firstName + ' - ' + this.lastName;
          },
          set: function (newVal) {
            var parts = newVal.split(' - ');
            this.firstName = parts[0];
            this.lastName = parts[1];
          }
        }
      }
    });
  </script>

watchcomputedmethods之间的对比

  1. computed属性的结果会被缓存,除非依赖的响应式属性变化才会重新计算。主要当作属性来使用;
  2. methods方法表示一个具体的操作,主要书写业务逻辑;
  3. watch一个对象,键是需要观察的表达式,值是对应回调函数。主要用来监听某些特定数据的变化,从而进行某些具体的业务逻辑操作;可以看作是computedmethods的结合体;

使用 this.$refs 来获取元素和组件

  <div id="app">
    <div>
      <input type="button" value="获取元素内容" @click="getElement" />
      <!-- 使用 ref 获取元素 -->
      <h1 ref="myh1">这是一个大大的H1</h1>

      <hr>
      <!-- 使用 ref 获取子组件 -->
      <my-com ref="mycom"></my-com>
    </div>
  </div>

  <script>
    Vue.component('my-com', {
      template: '<h5>这是一个子组件</h5>',
      data() {
        return {
          name: '子组件'
        }
      }
    });

    // 创建 Vue 实例,得到 ViewModel
    var vm = new Vue({
      el: '#app',
      data: {},
      methods: {
        getElement() {
          // 通过 this.$refs 来获取元素
          console.log(this.$refs.myh1.innerText);
          // 通过 this.$refs 来获取组件
          console.log(this.$refs.mycom.name);
        }
      }
    });
  </script>

什么是路由

  1. 后端路由:对于普通的网站,所有的超链接都是URL地址,所有的URL地址都对应服务器上对应的资源;
  2. 前端路由:对于单页面应用程序来说,主要通过URL中的hash(#号)来实现不同页面之间的切换,同时,hash有一个特点:HTTP请求中不会包含hash相关的内容;所以,单页面程序中的页面跳转主要用hash实现;
  3. 在单页面应用程序中,这种通过hash改变来切换页面的方式,称作前端路由(区别于后端路由);

相关文件

  1. URL中的hash(井号)
posted @ 2019-09-18 09:30  windalm  阅读(243)  评论(0编辑  收藏  举报