Vue.js基础(2.0+)

来源:互联网 发布:网络交易管理办法 问题 编辑:程序博客网 时间:2024/06/07 17:40

1、注册组件

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

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


2、构造器

扩展 Vue 构造器,从而用预定义选项创建可复用的组件构造器

var MyComponent = Vue.extend({  // 扩展选项})// 所有的 `MyComponent` 实例都将以预定义的扩展选项被创建var myComponentInstance = new MyComponent()

Vue.js 组件其实都是被扩展的Vue 实例

 

3、生命周期

实例生命周期的钩子不同阶段调用,如created mounted updated destroyed 。钩子的 this 指向调用它的 Vue 实例


4、缩写

<!-- 完整语法 --><a v-bind:href="url"></a><!-- 缩写 --><a :href="url"></a><!-- 完整语法 --><a v-on:click="doSomething"></a><!-- 缩写 --><a @click="doSomething"></a>

5、计算属性

var vm = new Vue({  el: '#example',  data: {    message: 'Hello'  },  computed: {    // a computed getter    reversedMessage: function () {      // `this` points to the vm instance      return this.message.split('').reverse().join('')    }  }})
computed: {  fullName: {    // getter    get: function () {      return this.firstName + ' ' + this.lastName    },    // setter    set: function (newValue) {      var names = newValue.split(' ')      this.firstName = names[0]      this.lastName = names[names.length - 1]    }  }}

6Class

<div class="static"     v-bind:class="{ active: isActive, 'text-danger': hasError }"></div><div v-bind:class="[isActive ? activeClass : '', errorClass]"><div v-bind:class="[{ active: isActive }, errorClass]">

7Style

<div v-bind:style="styleObject"></div>
<div v-bind:style="styleObject"></div>data: {  styleObject: {    color: 'red',    fontSize: '13px'  }}

 v-bind:style 使用需要特定前缀的 CSS 属性时,如 transform Vue.js会自动侦测并添加相应的前缀。

2.3开始你可以为 style 绑定中的属性提供一个包含多个值的数组,常用于提供多个带前缀的值:

<div :style="{ display: ['-webkit-box', '-ms-flexbox', 'flex'] }">


8、条件渲染

<template v-if="ok">  <h1>Title</h1>  <p>Paragraph 1</p>  <p>Paragraph 2</p></template><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>

Vue 会尽可能高效地渲染元素,通常会复用已有元素而不是从头开始渲染。不要复用它们,添加一个具有唯一值的 key 属性

<template v-if="loginType === 'username'">  <label>Username</label>  <input placeholder="Enter your username" key="username-input"></template><template v-else>  <label>Email</label>  <input placeholder="Enter your email address" key="email-input"></template>

v-show 的元素始终会被渲染并保留在 DOM中。v-show 是简单地切换元素的 CSS属性 display 

v-if v-for一起使用时,v-for具有比 v-if更高的优先级。


9、列表渲染

<ul id="example-2">  <li v-for="(item, index) in items">/*in 可以换为of*/    {{ parentMessage }} - {{ index }} - {{ item.message }}  </li></ul><ul>  <template v-for="item in items">    <li>{{ item.msg }}</li>    <li class="divider"></li>  </template></ul>

 v-for 通过一个对象的属性来迭代

<div v-for="(value, key, index) in object">  {{ index }}. {{ key }} : {{ value }}</div>

在遍历对象时,是按 Object.keys() 的结果遍历,但是不能保证它的结果在不同的 JavaScript 引擎下是一致的。

<div>  <span v-for="n in 10">{{ n }}</span></div>

v-for不能自动传递数据到组件里,因为组件有自己独立的作用域。为了传递迭代数据到组件里,我们要用 props 

Vue.component('todo-item', {  template: `    <li>      {{ title }}      <button v-on:click="$emit('remove')">X</button>    </li>  `,  props: ['title']})

10、数组更新检测

由于 JavaScript的限制, Vue不能检测以下变动的数组:

1.   当你利用索引直接设置一个项时,例如: vm.items[indexOfItem] = newValue

2.   当你修改数组的长度时,例如: vm.items.length = newLength

解决办法:

//1、// Vue.setVue.set(example1.items, indexOfItem, newValue)// Array.prototype.splice`example1.items.splice(indexOfItem, 1, newValue)//2、example1.items.splice(newLength)

11、事件处理器

原生 DOM 事件,可以用特殊变量 $event 把它传入方法

<button v-on:click="warn('Form cannot be submitted yet.', $event)">Submit</button>
// ...methods: {  warn: function (message, event) {    // 现在我们可以访问原生事件对象    if (event) event.preventDefault()    alert(message)  }}
 Vue.js 为 v-on 提供了 事件修饰符。通过由点(.)表示的指令后缀来调用修饰符。

<!-- 阻止单击事件冒泡 --><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><!-- 只当事件在该元素本身(而不是子元素)触发时触发回调 --><div v-on:click.self="doThat">...</div>
<!-- 在某个组件的根元素上监听一个原生事件 -->
<my-component v-on:click.native="doTheThing"></my-component>

<!-- 点击事件将只会触发一次(可用于组件上) --><a v-on:click.once="doThis"></a>
Vue 允许为 v-on 在监听键盘事件时添加按键修饰符:

<!-- 只有在 keyCode 是 enter 时调用 vm.submit() --><input v-on:keyup.enter="submit"><!-- 缩写语法 --><input @keyup.enter="submit">


全部的按键别名:

  • .enter
  • .tab
  • .delete (捕获 “删除” 和 “退格” 键)
  • .esc
  • .space
  • .up
  • .down
  • .left
  • .right

  • .ctrl
  • .alt
  • .shift
  • .meta

<!-- Alt + C --><input @keyup.alt.67="clear"><!-- Ctrl + Click --><div @click.ctrl="doSomething">Do something</div>

可以通过全局 config.keyCodes 对象自定义按键修饰符别名:

// 可以使用 v-on:keyup.f1Vue.config.keyCodes.f1 = 112


12、表单控件

v-model 指令在表单控件元素上创建双向数据绑定。它会根据控件类型自动选取正确的方法来更新元素。

v-model 并不关心表单控件初始化所生成的值。因为它会选择 Vue 实例数据来作为具体的值。对于要求 IME (如中文、 日语、 韩语等) 的语言,你会发现那v-model不会在 ime 构成中得到更新。如果你也想实现更新,请使用 input事件。

<input type="checkbox" id="jack" value="Jack" v-model="checkedNames"><label for="jack">Jack</label><input type="checkbox" id="john" value="John" v-model="checkedNames"><label for="john">John</label><input type="checkbox" id="mike" value="Mike" v-model="checkedNames"><label for="mike">Mike</label><br><span>Checked names: {{ checkedNames }}</span>
new Vue({  el: '...',  data: {    checkedNames: []  }})
v-bind 实现绑定 value 到 Vue 实例的一个动态属性上
<input  type="checkbox"  v-model="toggle"  v-bind:true-value="a"  v-bind:false-value="b">
// 当选中时vm.toggle === vm.a// 当没有选中时vm.toggle === vm.b
修饰符

.lazy

在默认情况下, v-model 在 input 事件中同步输入框的值与数据 (除了 上述 IME 部分),但你可以添加一个修饰符 lazy ,从而转变为在 change 事件中同步:

<!-- 在 "change" 而不是 "input" 事件中更新 --><input v-model.lazy="msg" >

.trim
如果要自动过滤用户输入的首尾空格,可以添加 trim 修饰符到 v-model 上过滤输入:
.number
如果想自动将用户的输入值转为 Number 类型(如果原值的转换结果为 NaN 则返回原值),可以添加一个修饰符 number给 v-model 来处理输入值:


13、组件

(1)使用组件

要注册一个全局组件,你可以使用 Vue.component(tagName, options)

Vue.component('my-component', {  // 选项})
对于自定义标签名尽管遵循(小写,并且包含一个短杠)
通过使用组件实例选项注册,可以使组件仅在另一个实例/组件的作用域中可用:

var Child = {  template: '<div>A custom component!</div>'}new Vue({  // ...  components: {    // <my-component> 将只在父模板可用    'my-component': Child  }})

<ul> ,<ol><table> ,<select> 中限制自定义组件

<table>  <tr is="my-row"></tr></table>

应当注意,如果您使用来自以下来源之一的字符串模板,这些限制将不适用:

  • <script type="text/x-template">
  • JavaScript内联模版字符串
  • .vue 组件

Vue构造器中data 必须是函数。

<div id="example-2">  <simple-counter></simple-counter>  <simple-counter></simple-counter>  <simple-counter></simple-counter></div>
Vue.component('simple-counter', {  template: '<button v-on:click="counter += 1">{{ counter }}</button>',  // 技术上 data 的确是一个函数了,因此 Vue 不会警告,  // 但是我们返回给每个组件的实例的却引用了同一个data对象  data: function () {    return {counter:0}  }})new Vue({  el: '#example-2'})


(2)Prop
在 Vue.js 中,父子组件的关系可以总结为 props down, events up 。父组件通过 props 向下传递数据给子组件,子组件通过 events 给父组件发送消息。

Vue.component('child', {  // 声明 props  props: ['message'],  // 就像 data 一样,prop 可以用在模板内  // 同样也可以在 vm 实例中像 “this.message” 这样使用  template: '<span>{{ message }}</span>'})
HTML 特性是不区分大小写的。所以,当使用的不是字符串模版,camelCased (驼峰式) 命名的 prop 需要转换为相对应的 kebab-case (短横线隔开式) 命名:
<!-- kebab-case in HTML --><child my-message="hello!"></child>
Vue.component('child', {  // camelCase in JavaScript  props: ['myMessage'],  template: '<span>{{ myMessage }}</span>'})
prop 是单向绑定的:当父组件的属性变化时,将传导给子组件,但是不会反过来。这是为了防止子组件无意修改了父组件的状态——这会让应用的数据流难以理解。可以定义一个局部变量,并用 prop 的值初始化它:
prop验证

Vue.component('example', {  props: {    // 基础类型检测 (`null` 意思是任何类型都可以)String/Number/Boolean/Array/Object/Function    propA: Number,    // 多种类型    propB: [String, Number],    // 必传且是字符串    propC: {      type: String,      required: true    },    // 数字,有默认值    propD: {      type: Number,      default: 100    },    // 数组/对象的默认值应当由一个工厂函数返回    propE: {      type: Object,      default: function () {        return { message: 'hello' }      }    },    // 自定义验证函数    propF: {      validator: function (value) {        return value > 10      }    }  }})
type 也可以是一个自定义构造器函数,使用 instanceof 检测。

(3)自定义事件

子组件通过自定义事件把数据传递回去

每个 Vue 实例都实现了事件接口(Events interface),即:

  • 使用 $on(eventName) 监听事件
  • 使用 $emit(eventName) 触发事件

Vue的事件系统分离自浏览器的EventTarget API。尽管它们的运行类似,但是$on 和 $emit 不是addEventListener 和 dispatchEvent 的别名。
不能用$on侦听子组件抛出的事件,而必须在模板里直接用v-on绑定,就像以下的例子:

<div id="counter-event-example">  <p>{{ total }}</p>  <button-counter v-on:increment="incrementTotal"></button-counter>  <button-counter v-on:increment="incrementTotal"></button-counter></div>
Vue.component('button-counter', {  template: '<button v-on:click="increment">{{ counter }}</button>',  data: function () {    return {      counter: 0    }  },  methods: {    increment: function () {      this.counter += 1      this.$emit('increment')    }  },})new Vue({  el: '#counter-event-example',  data: {    total: 0  },  methods: {    incrementTotal: function () {      this.total += 1    }  }})
2.3 重新引入了 .sync 修饰符,但是这次它只是作为一个编译时的语法糖存在。它会被扩展为一个自动更新父组件属性的 v-on 侦听器。
<comp :foo.sync="bar"></comp>
<comp :foo="bar" @update:foo="val => bar = val"></comp>

当子组件需要更新 foo 的值时,它需要显式地触发一个更新事件:

this.$emit('update:foo', newValue)

(4)Slot分发内容

<slot> 元素可以用一个特殊的属性 name 来配置如何分发内容。多个 slot 可以有不同的名字。具名 slot 将匹配内容片段中有对应 slot 特性的元素。
仍然可以有一个匿名 slot ,它是默认 slot ,作为找不到匹配的内容片段的备用插槽。如果没有默认的 slot ,这些找不到匹配的内容片段将被抛弃。

在父级中,具有特殊属性 scope 的 <template> 元素,表示它是作用域插槽的模板。scope 的值对应一个临时变量名,此变量接收从子组件中传递的 prop 对象:

<div class="child">  <slot text="hello from child"></slot></div>
<div class="parent">  <child>    <template scope="props">      <span>hello from parent</span>      <span>{{ props.text }}</span>    </template>  </child></div>
<div class="parent">  <div class="child">    <span>hello from parent</span>    <span>hello from child</span>  </div></div>