我们看一张 报纸 ,然后版面栏目不是很多嘛,比如这块是实事新闻,那块是娱乐新闻,东西很多放在一起管理就麻烦,分块各人管一小块就清晰点。 vuejs 就是干这事的,它提供了版面接口(版面成了一个容易扩展的独立对象),使得报纸的内容更容易修改(动态化)。

就是把报纸的 版面结构版面内容 分离开来,使 版面结构 不动的情况下 版面内容 可以随意变化。

前端历史

  • htmljavascript , css 技术相继出来以后,一张 报纸 基本满足用户的需求了,且还有少量互动,但程序员处理浏览器兼容性还是非常麻烦。

  • ajax 技术的出现,使 报纸 可以局部更新,体验更好,也节省了带宽。

  • jQuery 大大简化语法,提高了生产力。

  • angularjs vuejs 等前端框架出现,改变着传统网页单页无法重用的设计模式,改变了编码范式

  • nodejs 的出现,使得前端工程师都要把后端工程师消灭了。

安装

1
  <script src="https://cdn.bootcss.com/vue/2.6.10/vue.min.js"></script>

基本结构

版面结构

1
2
3
  <div>
    <h1>Hello,world {{message}}</h1>
  </div>

版面内容

1
2
3
4
5
6
7
  new Vue(
      {
          el:'h1', 
          data:{
              message:'Hello Vue', 
          }
      })

看下结构,模板式的关联方式,这样版面结构和版面内容就相互对应了,以后只要修改版面内容就可以了。

特性

版面结构(模板)

动态数据和事件的绑定方式跟原来不一样了,用了vue定义的模板样式。编程范式也跟 原来很不相同,以前是一步一步命令式的方式(命令范式),现在是配置式的(声明范 式),简化了好多代码。

因为版面结构与数据发生了绑定,所以 vue 会追踪数据是否发生变化来决定是否重新 渲染页面结构。这种方式叫响应式系统, 实例被创建时 data 中的数据是 响应式 的。

数据绑定
文本
1
2
3
  <div id="app">
    {{ message }}
  </div>
1
2
3
4
5
6
  var app = new Vue{ 
      el:'#app'
      data:{ 
          message:'Hello Vue!'
      } 
  }

这里 message 是响应式的,它一变,页面就要重新渲染。

不会改变的文本

1
  <span v-once>这个将不会改变: {{ msg }}</span>
HTML

对文本进行 HTML 解析

1
  <span v-html="rawHtml"></span>
属性绑定
  • v-bind:title="message"

1
  <button v-bind:disabled="isButtonDisabled">Button</button>

特殊例子, 如果 `isButtonDisabled` 的值是 `null`、`undefined` 或 `false`,则 `disabled` 特性甚至不会被包含在渲染出来的 `<button>` 元素中。

使用 JavaScript 表达式

直接使用,注意与语句区分

1
2
3
4
  {{ number + 1 }}
  {{ ok ? 'YES' : 'NO' }}
  {{ message.split('').reverse().join('') }}
  <div v-bind:id="'list-' + id"></div>
条件与循环
  • v-if 条件判断

  • v-else 分支

  • v-for 循环

  • v-else-if

  • v-show 仅仅隐藏

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    
      <div v-if="type === 'A'">
        A
      </div>
      <div v-else-if="type === 'B'">
        B
      </div>
      <div v-else-if="type === 'C'">
        C
      </div>
      <div v-else>
        Not A/B/C
      </div>
事件绑定
  • v-on

事件修饰符
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
  <!-- 阻止单击事件继续传播 -->
  <a v-on:click.stop="doThis"></a>

  <!-- 提交事件不再重载页面 -->
  <form v-on:submit.prevent="onSubmit"></form>

  <!-- 修饰符可以串联 -->
  <a v-on:click.stop.prevent="doThat"></a>

  <!-- 只有修饰符 -->
  <form v-on:submit.prevent></form>

  <!-- 添加事件监听器时使用事件捕获模式 -->
  <!-- 即元素自身触发的事件先在此处处理,然后才交由内部元素进行处理 -->
  <div v-on:click.capture="doThis">...</div>

  <!-- 只当在 event.target 是当前元素自身时触发处理函数 -->
  <!-- 即事件不是从内部元素触发的 -->
  <div v-on:click.self="doThat">...</div>

  <!-- 点击事件将只会触发一次 -->
  <a v-on:click.once="doThis"></a>

  <!-- 滚动事件的默认行为 (即滚动行为) 将会立即触发 -->
  <!-- 而不会等待 `onScroll` 完成  -->
  <!-- 这其中包含 `event.preventDefault()` 的情况 -->
  <div v-on:scroll.passive="onScroll">...</div>
  <!-- 这个 `.passive` 修饰符尤其能够提升移动端的性能。 -->
按键修饰符
1
2
3
4
  <!-- 只有在 `keyCode` 是 13 时调用 `vm.submit()` -->
  <input v-on:keyup.13="submit">
  <!-- 同上 -->
  <input v-on:keyup.enter="submit">

自定义按键修饰符别名

1
2
  // 可以使用 `v-on:keyup.f1`
  Vue.config.keyCodes.f1 = 112

全部的按键别名

  • .enter

  • .tab

  • .delete (捕获“删除”和“退格”键)

  • .esc

  • .space

  • .up

  • .down

  • .left

  • .right

系统修饰键

  • .ctrl

  • .alt

  • .shift

  • .meta

1
2
3
4
5
6
  <!-- Alt + C -->
  <input @keyup.alt.67="clear">

  <!-- Ctrl + Click -->
  <div @click.ctrl="doSomething">Do something</div>
  `
表单绑定
  • v-model

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    
      <input v-model="message" placeholder="edit me">
    
      <!-- 多行文本 -->
      <textarea v-model="message" placeholder="add multiple lines"></textarea>
    
      <!-- 复选框 -->
      <input type="checkbox" id="jack" value="Jack" v-model="checkedNames">
      <input type="checkbox" id="john" value="John" v-model="checkedNames">
    
      <!-- 单选按钮 -->
      <input type="radio" id="one" value="One" v-model="picked">
      <input type="radio" id="two" value="Two" v-model="picked">
    
      <!-- 选择框 -->
      <select v-model="selected">
        <option disabled value="">请选择</option>
        <option>A</option>
        <option>B</option>
        <option>C</option>
      </select>
    
      <!-- 渲染的动态选项 -->
      <select v-model="selected">
        <option v-for="option in options" v-bind:value="option.value">
          {{ option.text }}
        </option>
      </select>
值绑定
1
2
3
4
5
6
  <input
    type="checkbox"
    v-model="toggle"
    true-value="yes"
    false-value="no"
    >
冻结绑定
  • Object.freeze(obj)

缩写
  • v-bind 缩写 :

  • v-on 缩写 @

计算属性

对于需要修饰的内容 ,直接用模板处理会加重模板的清晰度,可以用计算属性维护

1
2
3
4
5
6
7
  computed: {
      // 计算属性的 getter
      reversedMessage: function () {
          // `this` 指向 vm 实例
          return this.message.split('').reverse().join('')
      }
  }
侦听器

自己有特殊需求可以使用

1
2
3
4
5
  watch: {
         // 如果  dataname 发生改变,这个函数就会运行
      dataname: function ( ){
      }
  },
Class 与 Style 绑定
class
1
2
3
  <div class="static"
       v-bind:class="{ active: isActive, 'text-danger': hasError }">
  </div>
1
2
3
4
  data: {
      isActive: true,
      hasError: false
  }

结果渲染为

1
  <div class="static active"></div>

或者

1
  <div v-bind:class="classObject"></div>
1
2
3
4
5
6
  data: {
      classObject: {
          active: true,
          'text-danger': false
      }
  }
style
1
<div v-bind:style="styleObject"></div>
1
2
3
4
5
6
  data: {
      styleObject: {
          color: 'red',
          fontSize: '13px'
      }
  }

组件

相当于自定义的标签,自己辛苦定义一个,当然要重复使用了啊

定义组件
  • Vue.component(tagName, options)

    1
    2
    3
    4
    
      // 定义名为 todo-item 的新组件
      Vue.component('todo-item', {
          template: '<li>这是个待办项</li>'
      })
    
使用组件

组件也是要配对的,和标签一样的用法

1
2
3
4
  <ol>
    <!-- 创建一个 todo-item 组件的实例 -->
    <todo-item1 v-for="i in [1,2,3]"></todo-item>
  </ol>
定义局部组件
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
  var Child = {
      template: '<div>A custom component!</div>'
  }

  new Vue({
      // ...
      components: {
          // <my-component> 将只在父组件模板中可用
          'my-component': Child
      }
  })
模板解析注意事项

因为 Vue 的解析在 DOM 之后,所以对于像 `<ul>`、`<ol>`、`<table>`、 `<select>` 这样的元素会有限制,这时要用到 is 特性

错误的方法

1
2
3
  <table>
    <my-row>...</my-row>
  </table>

正确的方法

1
2
3
  <table>
    <tr is="my-row"></tr>
  </table>
  • JavaScript 内联模板字符串

    • `.vue` 组件

    这两种方式就没有限制

data 必须是函数
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
  Vue.component('buttonclicked', {
      props: [
          'initial_count'
      ],
      data() {
          return {
              count: 0
          }
      },
      template: '<button v-on:click="onclick">Clicked {{ count }} times</button>',
      methods: {
          onclick() {
              this.count += 1;
          }
      },
      mounted() {
          this.count = this.initial_count;
      }
  });

过渡效果

Vue 在插入、更新或者移除 DOM 时,提供多种不同方式的应用过渡效果。 包括以下工具:

在 CSS 过渡和动画中自动应用 class 可以配合使用第三方 CSS 动画库,如 Animate.css 在过渡钩子函数中使用 JavaScript 直接操作 DOM 可以配合使用第三方 JavaScript 动画库,如 Velocity.js.

单文件组件

为了更好地适应复杂的项目,Vue 支持以.vue 为扩展名的文件来定义一个完整组件, 用以替代使用 Vue.component 注册组件的方式。开发者可以使用 Webpack 或 Browserify 等构建工具来打包单文件组件。

生命周期

每个 Vue 实例在被创建时都要经过一系列的初始化过程——例如,需要设置数据监听、 编译模板、将实例挂载到 DOM 并在数据变化时更新 DOM 等。同时在这个过程中也会运 行一些叫做 生命周期钩子 的函数,这给了用户在不同阶段添加自己的代码的机会。

  • created 实例被创建后执行

  • mounted

  • updated

  • destroyed