一、什么是vue?

练习时使用,最新版本

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>

生产时使用,明确版本号的版本,避免造成不可预见的问题

<script src="https://cdn.jsdelivr.net/npm/vue@2.6.12"></script>

hello world

<div id="app">
    {{message}}
</div>
<script>
    var app = new Vue({
        el: "#app",
        data: {
            message: 'hello,world'
        }
    })
</script>

1.v-指令

  1. v-bind--绑定属性
<div id="app-2">
  <span v-bind:title="message">
    鼠标悬停几秒钟查看此处动态绑定的提示信息!
  </span>
</div>

<script>
  var app = new Vue({
  el: '#app',
  data: {
    message: '页面加载于 ' + new Date().toLocaleString()
  }
})
</script>

v-bind是vue特有的提供的属性,他会在dom上应用一个响应式的操作

打开console,输入app.message = "hello",页面会改变内容只显示hello

又或者输入app.message = false,内容会直接不显示

vue官网例子:

<!-- 绑定一个 attribute -->
<img v-bind:src="imageSrc">

<!-- 动态 attribute 名 (2.6.0+) -->
<button v-bind:[key]="value"></button>

<!-- 缩写 -->
<img :src="imageSrc">

<!-- 动态 attribute 名缩写 (2.6.0+) -->
<button :[key]="value"></button>

<!-- 内联字符串拼接 -->
<img :src="'/path/to/images/' + fileName">

<!-- class 绑定 -->
<div :class="{ red: isRed }"></div>
<div :class="[classA, classB]"></div>
<div :class="[classA, { classB: isB, classC: isC }]">

<!-- style 绑定 -->
<div :style="{ fontSize: size + 'px' }"></div>
<div :style="[styleObjectA, styleObjectB]"></div>

<!-- 绑定一个全是 attribute 的对象 -->
<div v-bind="{ id: someProp, 'other-attr': otherProp }"></div>

<!-- 通过 prop 修饰符绑定 DOM attribute -->
<div v-bind:text-content.prop="text"></div>

<!-- prop 绑定。“prop”必须在 my-component 中声明。-->
<my-component :prop="someThing"></my-component>

<!-- 通过 $props 将父组件的 props 一起传给子组件 -->
<child-component v-bind="$props"></child-component>

<!-- XLink -->
<svg><a :xlink:special="foo"></a></svg>

  1. v-if--控制元素的显示隐藏

刚才写了,通过app.message = false,可以让message代表的内容处于隐藏状态,但是控制的只能是通过v-for引入的内容,无法直接让元素隐藏

其实,vue中还有一个专门控制元素显示隐藏的指令--v-if

<div id="app">
  <span v-if="show">
    {{message}}
  </span>
</div>

<script>
  var app = new Vue({
    el: "#app",
    data: {
      message: 'hello,world',
      show: true
    }
  })
</script>

给元素绑定一个指令v-if = "show",然后在data中控制show的布尔值,true显示,false隐藏

同时还有这个功能的指令v-show,根据表达式之真假值,切换元素的display CSS property,也是通过绑定的布尔值来显示隐藏

但是v-ifv-show有些区别

(1) v-if是控制元素是否渲染最终控制元素的显示隐藏,适用于切换频率低的情况
(2) v-show不管显示隐藏都渲染,然后通过布尔值绑定display: none属性,适用于切换频率高的情况

注意:v-show不支持<tempalte>元素,也不支持v-else

搭配用法

v-elsev-else-if

可以通过使用v-else达到v-if的效果,必须和v-if搭配使用,比如:

<div v-if="1>2">
  hello
</div>
<div v-else>
  hi
</div>

如果v-if不成立,执行v-else,也就是显示v-else里面的内容

是不是有点javascript里面if函数的感觉了

v-else-if用法大致一样,必须和v-ifv-else搭配使用


  1. v-for--遍历数组并显示到页面上

v-for算是vue的核心指令之一了把,主要是渲染一个项目列表的

<div id="app">
  <div v-for="item in list">{{item.message}}</div>
</div>

<script>
  var app = new Vue({
    el: "#app",
    data: {
      list: [
        {message: 'html'},
        {message: 'css'}
      ]
    }
  })
</script>

可以直接把列表数据循环输出

并且在控制台中通过push()还能添加新的列表项

app.list.push({message: "js"})

vue对数据操作,就是这么神奇

不推荐v-forv-if同时使用,因为v-for拥有更高的优先级


  1. v-on--绑定事件监听器

即绑定事件,通过v-on给div绑定了一个点击事件,注意,在reverseMessage方法中,我们更新了应用的状态,但是吗诶呀触碰到dom,直接通过vue来进行处理,编写代码时只需要关注逻辑层即可

v-on:click="messagenone",然后在methods里面写上事件方法

<div id="app">
  <div v-on:click="messagenone" id="demo">{{message}}</div>
</div>

<script>
  var app = new Vue({
    el: "#app",
    data: {
      message: 'hello,wolrd'
    },
    methods: {
      messagenone: function() {
        var demo = document.getElementById('demo');
        demo.innerHTML = ''
      }
    }
  })
</script>

  1. v-model--数据的双向绑定

vue还提供了v-model指令,它能轻松实现表单输入和应用状态之间的双向绑定

可使用场景:标签input, select, textarea 和 components

<div id="app">
  <div>{{message}}</div>
  <input type="text" v-model="message">
</div>

<script>
  var app = new Vue({
    el: "#app",
    data: {
      message: 'hello,wolrd'
    }
  })
</script>

  1. v-text更新元素的内容
<div id="app">
    <div v-text="message"></div>
    <div>{{message}}</div>
</div>

<script>
    var vm = new Vue({
        el: '#app',
        data: {
            message: 'hello,wolrd'
        }
    })
</script>

上面的div和下面的div内容跟随一致变化


  1. v-html--更新元素的innerHTML

<red>不建议使用,在网站上动态渲染html是非常危险的,容易导致XXS攻击,不能用在用户提交的内容上,如果必须使用v-html,可以考虑通过使用组件来代替</red>


  1. v-pre

跳过绑定的元素和他的子元素的编译,直接显示原始内容

跳过没有指令的节点不进行编译,直接显示内容,会加快页面的响应


  1. v-cloak

在编译没有编译完成之前,模板处于的状态

<style>v-cloak] {
  display: none;
}</style>

<div v-cloak>
  {{message}}
</div>

<script>
  var vm = new Vue({
    el: '#app',
    data: {
        message: 'hello,wolrd'
    }
  })
</script>

上述代码表示的含义是,如果网络不好,{{message}}模板代表的hello,world还没有编译成功,此时{{message}}处于隐藏状态,当编译完成,页面直接显示hello,world


  1. v-once--一次性渲染

绑定该指令的元素及其子元素只会进行一次渲染,之后页面的第二次渲染会将其视为静态资源并跳过,可以用来优化性能

<div id="app">
    <span v-once>{{message}}</span>
</div>

<script>
    var vm = new Vue({
        el: '#app',
        data: {
            message: 'hello,wolrd',
        }
    })
</script>

使用场景:表单提交。可防止用户在请求未及时响应时,多次提交~

2.组件化构建应用

组件化也是vue的核心机制之一,它允许我们使用小型,可复用的组件来构建大型应用

vue-learn-3.png

在 vue 里,一个组件本质上是一个拥有预定义选项的一个 vue 实例。在 vue 中注册组件很简单

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

var app = new Vue(...)

现在可以用它构建另一个组件模板

<ol>
  <!-- 创建一个 todo-item 组件的实例 -->
  <todo-item></todo-item>
</ol>

但是这样会为每个待办项渲染同样的文本,这看起来并不炫酷。我们应该能从父作用域将数据传到子组件才对。让我们来修改一下组件的定义,使之能够接受一个props

Vue.component('todo-item', {
  // todo-item 组件现在接受一个
  // "props",类似于一个自定义 attribute。
  // 这个 props 名为 todo。
  props: ['todo'],
  template: '<li>{{ todo.text }}</li>'
})

现在,我们可以使用v-bind指令将待办项传到循环输出的每个组件中

现在我们为每个 todo-item 提供 todo 对象todo 对象是变量,即其内容可以是动态的,我们也需要为每个组件提供一个key

<div id="app-7">
  <ol>
    <todo-item
      v-for="item in groceryList"
      v-bind:todo="item"
      v-bind:key="item.id"
    ></todo-item>
  </ol>
</div>
Vue.component('todo-item', {
  props: ['todo'],
  template: '<li>{{ todo.text }}</li>'
})

var app7 = new Vue({
  el: '#app-7',
  data: {
    groceryList: [
      { id: 0, text: '蔬菜' },
      { id: 1, text: '奶酪' },
      { id: 2, text: '随便其它什么人吃的东西' }
    ]
  }
})

尽管这只是一个刻意设计的例子,但是我们已经设法将应用分割成了两个更小的单元。子单元通过prop接口与父单元进行了良好的解耦。我们现在可以进一步改进 <todo-item> 组件,提供更为复杂的模板和逻辑,而不会影响到父单元

在一个大型应用中,有必要将整个应用程序划分为组件,以使开发更易管理

<div id="app">
  <app-nav></app-nav>
  <app-view>
    <app-sidebar></app-sidebar>
    <app-content></app-content>
  </app-view>
</div>