Vue初始搭建与基础知识

作者: pdnbplus | 发布时间: 2024/06/25 | 阅读量: 85

Vue初始搭建与基础知识--潘登同学的前端笔记

搭建Vue环境

1.安装vuecli工具

cnpm install -g @vue/cli

2.创建项目

vue create my-project

3.运行项目

要在cd my-project下才能创建

npm run serve

4.注意事项

  • node_modules 文件特别大,上传项目到git上的时候,可以先把他删除,因为别人可以通过安装把文件下载回来

  • public是主目录

  • src是源码文件

  • .browserslistrc是配置文件

  • .gitignore是github的忽略文件

  • babel.config.js是ES6的babel配置文件

  • package.json也是配置文件

Vue的基础知识

转载自官方文档

模板语法

  • Vue.js 使用了基于 HTML 的模板语法,允许开发者声明式地将 DOM 绑定至底层 Vue 实例的数据。所有 Vue.js 的模板都是合法的 HTML,所以能被遵循规范的浏览器和 HTML 解析器解析。

插值

  • 双大括号(输出的是文本)
<p>{{ msg }}</p>
  • 如果想储存原始html代码,需要加上
<p v-html="price"></p>

所以所有通过v-开头的都被称为指令

  • 绑定属性 v-bind:+属性
<div v-bind:id="dynamicId"></div>
  • JS语法限制

在双大括号只能包含单行表达式(可以有一些运算或者判断)

指令

  • 所以所有通过v-开头的都被称为指令,指令的职责是,当表达式的值改变时,将其产生的连带影响,响应式地作用于 DOM。
<p v-if="seen">现在你看到我了</p>

这里,v-if 指令将根据表达式 seen 的值的真假来插入/移除 <p> 元素。

  • 参数:一些指令能够接收一个“参数”,在指令名称之后以冒号表示。例如,v-bind 指令可以用于响应式地更新 HTML attribute:
<a v-bind:href="url">...</a>

在这里 href 是参数,告知 v-bind指令将该元素的 href attribute 与表达式 url 的值绑定。

  • 另一个例子是 v-on 指令,它用于监听 DOM 事件:
<a v-on:click="doSomething">...</a>

缩写

  • v-bind 可以缩写为 :
  • v-on 可以缩写为 @

计算属性和侦听器

计算属性

下列代码不易于维护且不易复用

<div id="example">
  {{ message.split('').reverse().join('') }}
</div>

可以尝试改为

<div id="example">
  {{ reversedMessage  }}
</div>
// 在于data() 同级的水平下
computed: {
    // 计算属性的 getter
    reversedMessage: function () {
      // `this` 指向 vm 实例
      return this.message.split('').reverse().join('')
    }
  }

计算属性缓存 vs 方法

我们可以将同一函数定义为一个方法而不是一个计算属性。两种方式的最终结果确实是完全相同的。然而,不同的是计算属性是基于它们的响应式依赖进行缓存的。只在相关响应式依赖发生改变时它们才会重新求值。这就意味着只要 message 还没有发生改变,多次访问 reversedMessage 计算属性会立即返回之前的计算结果,而不必再次执行函数。

侦听器

watch 方法会响应数据的变化,当需要在数据变化时执行异步或开销较大的操作时,这个方式是最有用的。

<!-- 来设置一个输入框 在改变输入的时候会返回新旧两个值 -->
<div>
    <input type="text" name="" id="" v-model="nick">
</div>
// 与data() 同级下,当然不要忘记在data声明nick
watch:{
    // 监听的方法名称必须等于属性名
    nick(newValue,oldValue,){
      console.log(newValue,oldValue);
    },
  }

Class 与 Style 绑定

绑定 HTML Class

  • 对象语法
<div v-bind:class="{ active: isActive }"></div>

上面的语法表示 active 这个 class 存在与否将取决于数据 property isActive

可以在对象中传入更多字段来动态切换多个 class。此外,v-bind:class 指令也可以与普通的 class attribute 共存。当有如下模板:

<div
  class="static"
  v-bind:class="{ active: isActive, 'text-danger': hasError }"
></div>
data: {
  isActive: true,
  hasError: false
}

绑定的数据对象不必内联定义在模板里,也可以通过对象方式

<div v-bind:class="classObject"></div>
data: {
  classObject: {
    active: true,
    'text-danger': false
  }
}

还可以绑定一个计算属性来操作

<div v-bind:class="classObject"></div>
data: {
  isActive: true,
  error: null
},
computed: {
  classObject: function () {
    return {
      active: this.isActive && !this.error,
      'text-danger': this.error && this.error.type === 'fatal'
    }
  }
}
  • 数组语法

v-bind:style 的数组语法可以将多个样式对象应用到同一个元素上: (可以在数组中嵌套对象)

<div v-bind:style="[baseStyles, overridingStyles]"></div>

条件渲染

v-if

  • v-if 指令用于条件性地渲染一块内容。这块内容只会在指令的表达式返回 true 值的时候被渲染。可以加入else
<p v-if="flag">我出来啦</p>
<p v-else>我不见啦</p>

<template> 元素上使用 v-if 条件渲染分组

  • 因为 v-if 是一个指令,所以必须将它添加到一个元素上。但是如果想切换多个元素呢?此时可以把一个 <template> 元素当做不可见的包裹元素,并在上面使用 v-if。最终的渲染结果将不包含 <template> 元素。
<template v-if="ok">
  <h1>Title</h1>
  <p>Paragraph 1</p>
  <p>Paragraph 2</p>
</template>

v-else-if

  • 顾名思义,充当 v-if的“else-if 块”,可以连续使用:
<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-show

  • 另一个用于根据条件展示元素的选项是 v-show 指令。用法大致一样:
<h1 v-show="ok">Hello!</h1>

不同的是带有 v-show 的元素始终会被渲染并保留在 DOM 中。v-show 只是简单地切换元素的 CSS property display

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

v-ifv-show

  • v-if 是“真正”的条件渲染,因为它会确保在切换过程中条件块内的事件监听器和子组件适当地被销毁和重建。(元素删除和添加)
  • v-if 也是惰性的:如果在初始渲染时条件为假,则什么也不做——直到条件第一次变为真时,才会开始渲染条件块。
  • v-show 就简单得多——不管初始条件是什么,元素总是会被渲染,并且只是简单地基于 CSS 进行切换。
  • 一般来说,v-if 有更高的切换开销,而 v-show 有更高的初始渲染开销。因此,如果需要非常频繁地切换,则使用 v-show 较好;如果在运行时条件很少改变,则使用 v-if 较好。

列表渲染

v-for 把一个数组对应为一组元素

  • 我们可以用 v-for 指令基于一个数组来渲染一个列表。v-for 指令需要使用 item in items 形式的特殊语法,其中 items 是源数据数组,而 item 则是被迭代的数组元素的别名。
<ul id="example-1">
  <li v-for="item in items" :key="item.message">
    {{ item.message }}
  </li>
</ul>
var example1 = new Vue({
  el: '#example-1',
  data: {
    items: [
      { message: 'Foo' },
      { message: 'Bar' }
    ]
  }
})
  • v-for 块中,我们可以访问所有父作用域的 property。v-for 还支持一个可选的第二个参数,即当前项的索引。
<ul id="example-2">
  <li v-for="(item, index) in items">
    {{ parentMessage }} - {{ index }} - {{ item.message }}
  </li>
</ul>
var example2 = new Vue({
  el: '#example-2',
  data: {
    parentMessage: 'Parent',
    items: [
      { message: 'Foo' },
      { message: 'Bar' }
    ]
  }
})
  • v-for 里使用值范围: v-for 也可以接受整数。在这种情况下,它会把模板重复对应次数。
<div>
  <span v-for="n in 10">{{ n }} </span>
</div>

v-for 里使用对象

  • 可以用 v-for 来遍历一个对象的 property。
<ul id="v-for-object" class="demo">
  <li v-for="value in object">
    {{ value }}
  </li>
</ul>
new Vue({
  el: '#v-for-object',
  data: {
    object: {
      title: 'How to do lists in Vue',
      author: 'Jane Doe',
      publishedAt: '2016-04-10'
    }
  }
})
  • 也可以提供第二个的参数为 property 名称 (也就是键名):
<div v-for="(value, name) in object">
  {{ name }}: {{ value }}
</div>
  • 还可以用第三个参数作为索引:
<div v-for="(value, name, index) in object">
  {{ index }}. {{ name }}: {{ value }}
</div>

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

数组更新检测

变更方法

Vue 将被侦听的数组的变更方法进行了包裹,所以它们也将会触发视图更新。这些被包裹过的方法包括:(其他的方法(非变更方法,就是不改变原对象,只是返回新对象的操作)就不好用了)

  • push()
  • pop()
  • shift()
  • unshift()
  • splice()
  • sort()
  • reverse()
<div>
      <h3>list渲染</h3>
      <button @click="addItemHandle">添加数据</button>
      <ul>
        <li @click="getMessageHandle(item.text)" v-for="(item, index) in result" :key="item.id">
          {{ item.text }}-{{ index }}
        </li>
      </ul>
      <a @click.prevent="clickPD" href="https://pd3nbplus.github.io/">pd的个人博客</a>
    </div>
addItemHandle(){
      this.result.push({id:1004,  text: "四川的锤子"});
    }

非变更方法

  • filter() 过滤函数
  • concat() 合并多个数组 返回新数组 不改变原数组
  • slice() 数组切片

但也有解决方案(效果与上面一样)

addItemHandle(){
      this.result = this.result.concat({id:1004,  text: "四川的锤子"});
    }

<template> 上使用 v-for

  • 类似于 v-if,你也可以利用带有 v-for<template> 来循环渲染一段包含多个元素的内容。
<ul>
  <template v-for="item in items">
    <li>{{ item.msg }}</li>
    <li class="divider" role="presentation"></li>
  </template>
</ul>

v-forv-if 一同使用

注意 我们不推荐在同一元素上使用 v-ifv-for

  • 当它们处于同一节点,v-for 的优先级比 v-if 更高,这意味着 v-if 将分别重复运行于每个 v-for 循环中。当你只想为部分项渲染节点时,这种优先级的机制会十分有用,如下:
<li v-for="todo in todos" v-if="!todo.isComplete">
  {{ todo }}
</li>
  • 而如果你的目的是有条件地跳过循环的执行,那么可以将 v-if 置于外层元素 (或 <template>) 上。如:
<ul v-if="todos.length">
  <li v-for="todo in todos">
    {{ todo }}
  </li>
</ul>
<p v-else>No todos left!</p>

事件处理

监听事件

  • 可以用 v-on 指令监听 DOM 事件,并在触发时运行一些 JavaScript 代码。
<div id="example-1">
  <button v-on:click="counter += 1">Add 1</button>
  <p>The button above has been clicked {{ counter }} times.</p>
</div>
var example1 = new Vue({
  el: '#example-1',
  data: {
    counter: 0
  }
})

事件处理方法

  • 许多事件处理逻辑会更为复杂,所以直接把 JavaScript 代码写在 v-on 指令中是不可行的。因此 v-on 还可以接收一个需要调用的方法名称。
<div id="example-2">
  <!-- `greet` 是在下面定义的方法名 -->
  <button v-on:click="greet">Greet</button>
</div>
var example2 = new Vue({
  el: '#example-2',
  data: {
    name: 'Vue.js'
  },
  // 在 `methods` 对象中定义方法
  methods: {
    greet: function (event) {
      // `this` 在方法里指向当前 Vue 实例
      alert('Hello ' + this.name + '!')
      // `event` 是原生 DOM 事件
      if (event) {
        alert(event.target.tagName)
      }
    }
  }
})

内联处理器中的方法

  • 除了直接绑定到一个方法,也可以在内联 JavaScript 语句中调用方法:
<div id="example-3">
  <button v-on:click="say('hi')">Say hi</button>
  <button v-on:click="say('what')">Say what</button>
</div>
new Vue({
  el: '#example-3',
  methods: {
    say: function (message) {
      alert(message)
    }
  }
})
  • 有时也需要在内联语句处理器中访问原始的 DOM 事件。可以用特殊变量 $event 把它传入方法:
<button v-on:click="warn('Form cannot be submitted yet.', $event)">
  Submit
</button>
new Vue({
  el: '#example-3',
  methods: {
    warn: function (message, event) {
        // 现在我们可以访问原生事件对象
        if (event) {
        event.preventDefault()
        }
        alert(message)
    }
  }
})

事件修饰符(阻止默认事件,冒泡)

  • 在事件处理程序中调用 event.preventDefault()event.stopPropagation() 是非常常见的需求。尽管我们可以在方法中轻松实现这点,但更好的方式是:方法只有纯粹的数据逻辑,而不是去处理 DOM 事件细节。

为了解决这个问题,Vue.jsv-on 提供了事件修饰符。之前提过,修饰符是由点开头的指令后缀来表示的。

  • .stop
  • .prevent
  • .capture
  • .self
  • .once
  • .passive
  • .once
<!-- 阻止单击事件继续传播 -->
<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>

注意 使用修饰符时,顺序很重要;相应的代码会以同样的顺序产生。因此,用 v-on:click.prevent.self 会阻止所有的点击,而 v-on:click.self.prevent 只会阻止对元素自身的点击。

注意 不要把 .passive.prevent 一起使用,因为 .prevent 将会被忽略,同时浏览器可能会向你展示一个警告。请记住,.passive 会告诉浏览器你不想阻止事件的默认行为。

按键修饰符

  • 在监听键盘事件时,我们经常需要检查详细的按键。Vue 允许为 v-on 在监听键盘事件时添加按键修饰符:
<!-- 只有在 `key` 是 `Enter` 时调用 `vm.submit()` -->
<input v-on:keyup.enter="submit">
  • 可以直接将 KeyboardEvent.key 暴露的任意有效按键名转换为 kebab-case 来作为修饰符。
<input v-on:keyup.page-down="onPageDown">

系统修饰键

可以用如下修饰符来实现仅在按下相应按键时才触发鼠标或键盘事件的监听器。

  • .ctrl
  • .alt
  • .shift
  • .meta(window徽标)
<!-- Alt + C -->
<input v-on:keyup.alt.67="clear">

<!-- Ctrl + Click -->
<div v-on:click.ctrl="doSomething">Do something</div>

注意 请注意修饰键与常规按键不同,在和 keyup 事件一起用时,事件触发时修饰键必须处于按下状态。换句话说,只有在按住 ctrl 的情况下释放其它按键,才能触发 keyup.ctrl

  • .exact 修饰符

.exact 修饰符允许你控制由精确的系统修饰符组合触发的事件。

<!-- 即使 Alt 或 Shift 被一同按下时也会触发 -->
<button v-on:click.ctrl="onClick">A</button>

<!-- 有且只有 Ctrl 被按下的时候才触发 -->
<button v-on:click.ctrl.exact="onCtrlClick">A</button>

<!-- 没有任何系统修饰符被按下的时候才触发 -->
<button v-on:click.exact="onClick">A</button>

鼠标按钮修饰符

这些修饰符会限制处理函数仅响应特定的鼠标按钮。

  • .left
  • .right
  • .middle

表单输入与绑定

基础用法

  • 可以用 v-model 指令在表单 <input><textarea><select> 元素上创建双向数据绑定。它会根据控件类型自动选取正确的方法来更新元素。尽管有些神奇,但 v-model 本质上不过是语法糖。它负责监听用户的输入事件以更新数据,并对一些极端场景进行一些特殊处理。

注意 v-model 会忽略所有表单元素的 valuecheckedselected attribute 的初始值而总是将 Vue 实例的数据作为数据来源。你应该通过 JavaScript 在组件的 data 选项中声明初始值。

v-model 在内部为不同的输入元素使用不同的 property 并抛出不同的事件:

  • text 和 textarea 元素使用 value property 和 input 事件;
  • checkbox 和 radio 使用 checked property 和 change 事件;
  • select 字段将 value 作为 prop 并将 change 作为事件。
<!-- 简单输入框  加入lazy参数:不是实时获取而是失去焦点才获取-->
<input v-model.lazy="message" placeholder="edit me">
<p>Message is: {{ message }}</p>

<!-- 多行文本 -->
<span>Multiline message is:</span>
<p style="white-space: pre-line;">{{ message }}</p>
<br>
<textarea v-model="message" placeholder="add multiple lines"></textarea>

<!-- 单个复选框,绑定到布尔值: -->
<input type="checkbox" id="checkbox" v-model="checked">
<label for="checkbox">{{ checked }}</label>

<!-- 对于多个复选框 结合下面的JS -->
<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>
data: {
    checkedNames: []
  }

修饰符

  • .lazy

在默认情况下,v-model 在每次 input 事件触发后将输入框的值与数据进行同步 (除了上述输入法组合文字时)。你可以添加 lazy 修饰符,从而转为在 change 事件_之后_进行同步:(如失去焦点,或者回车键)

  • .number

如果想自动将用户的输入值转为数值类型,可以给 v-model 添加 number 修饰符

<input v-model.number="age" type="number">

这通常很有用,因为即使在 type="number" 时,HTML 输入元素的值也总会返回字符串。如果这个值无法被 parseFloat() 解析,则会返回原始的值。

  • .trim

如果要自动过滤用户输入的首尾空白字符,可以给 v-model 添加 trim 修饰符

<input v-model.trim="msg">
/label>
<input type="checkbox" id="mike" value="Mike" v-model="checkedNames">
<label for="mike">Mike</label>
<br>
<span>Checked names: {{ checkedNames }}</span>
data: {
    checkedNames: []
  }

修饰符

  • .lazy

在默认情况下,v-model 在每次 input 事件触发后将输入框的值与数据进行同步 (除了上述输入法组合文字时)。你可以添加 lazy 修饰符,从而转为在 change 事件_之后_进行同步:(如失去焦点,或者回车键)

  • .number

如果想自动将用户的输入值转为数值类型,可以给 v-model 添加 number 修饰符

<input v-model.number="age" type="number">

这通常很有用,因为即使在 type="number" 时,HTML 输入元素的值也总会返回字符串。如果这个值无法被 parseFloat() 解析,则会返回原始的值。

  • .trim

如果要自动过滤用户输入的首尾空白字符,可以给 v-model 添加 trim 修饰符

<input v-model.trim="msg">