web14.Vue.js基础

介绍

Vue.js 是什么

是一套用于构建用户界面的渐进式框架;自底向上逐层应用,它的设计思想、编码技巧也被众多的框架借鉴、模仿。Vue 的核心库只关注视图层

历史介绍

Vue 1.0

设计思想

是一种“渐进式框架”,淡化框架本身的主张,降低框架作为工具的复杂度,从而降低对使用者的要求

主要改进

  1. 提供指令的缩写:针对v-bind和v-on提供缩写形式

    <!-- v-bind -->
      <div v-bind:class="box">全写</div>
      <div :class="box">缩写</div>
      <!-- v-on -->
      <button v-on:click="btn">全写</button>
      <button @click="btn">缩写</button>
    
  2. 清理精简所提供的接口

  3. 提高初始化的渲染效率:将v-repeat指令换成了v-for指令。同时优化了这个指令的渲染,效率提升一倍

  4. 两个官方工具的增强:vue-loader和vuetify

Vue 2.0

性能上的改进

用一个fork自snabbdom的轻量 Vitual DOM实现对渲染层进行了重写

在其上层,Vue的模板编译器能够在编译时做一些智能的优化处理,例如分析并提炼出静态子树以避免界面重绘时不必要的比对

有新的渲染层

服务器上的渲染

Vue2.0支持服务器渲染(SSR),并且是流式的,可以做组件级的缓存,这使得极速渲染成为可能

Vue3.0

3.0进行了非常大的重构,源码使用TypeScript重写,目前的代码98%以上使用TypeScript编写

前端框架与库的区别

  1. jQuery库->DOM(操作DOM)+请求

    art-template库->模板引擎

    库=小而精

    框架=全方面功能齐全=简易的DOM体验+发请求+模板引擎+路由功能

  2. KFC的世界里,库就是一个小套餐,框架就是全家桶

  3. 代码不同

    • 一般使用库的代码,是调用某个函数,我们自己来把控库的代码
    • 一般使用框架,其框架在帮我们运行我们编写好的代码
      • 框架:初始化自身的一些行为
      • 执行你所编写的代码
      • 施放一些资源

声明式渲染

vue.js 的核心是一个允许采用简洁的模板语法来声明式地将数据渲染进 DOM 的系统

文本插值(设置定时器和清除定时)

<div id="counter">
    Counter: {{ counter }}<br>
    <button id="btn" @click="clear()">stopTimer</button>
</div>
<script src="https://unpkg.com/vue@next"></script>
<script>
    const Counter = {
        data() {
            return {
                counter: 0
            }
        },
        mounted() {
            this.timer = setInterval(() => {
                this.counter++
            }, 1000)
        },
        methods: {
            clear() {
                window.clearInterval(this.timer);
                console.log(this.timer);
            }
        }
    }
    Vue.createApp(Counter).mount('#counter')
</script>

qqboCjEJ7h

绑定元素的 attribute(悬浮出现信息)

v-bind attribute 被称为指令,指令带有前缀 v-,以表示它们是 Vue 提供的特殊 attribute

<div id="bind-message" class="demo">
    <span v-bind:title="message">
        鼠标悬停几秒钟查看此处动态绑定的提示信息!
    </span>
</div>
<script src="https://unpkg.com/vue@next"></script>
<script>
    const bindMessage = {
        data() {
            return {
                message: "加载页面" + new Date().toLocaleString()
            }
        }
    }
    Vue.createApp(bindMessage).mount('#bind-message')
</script>
TWEcE5uRBR

处理用户输入v-on&&v-model

v-on

v-on 指令添加一个事件监听器,通过它调用在实例中定义的方法

<div id="event-handling">
        <p>{{ message }}</p>
        <button v-on:click="reverseMessage()">反转 Message</button>
      </div>
    <script src="https://unpkg.com/vue@next"></script>
    <script>
       const EventHandling ={
           data(){
               return{
                   message:"hello Vue.js"
               }
           },
           methods: {
            reverseMessage(){
                   this.message=this.message
                   .split('')
                   .reverse()
                   .join('')
               }
           }
       }
       Vue.createApp(EventHandling).mount('#event-handling')

AHG3t9lyEI

v-model

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

<div id="binding">
    <p>{{ message }}</p>
    <input v-model="message" />
  </div>
<script src="https://unpkg.com/vue@next"></script>
<script>
   const vmodelBind={
        data(){
            return {
                message:"hello vue"
            }
        }
   }
   Vue.createApp(vmodelBind).mount('#binding')
</script>

KeXdvL1uA5

条件与循环v-if

例如:控制切换一个元素是否显示,不仅可以把数据绑定到 DOM 文本或 attribute,还可以绑定到 DOM 的结构,可以在 Vue 插入/更新/移除元素时自动应用过渡效果

<div id="vIf">
    <span v-if="seen">现在你看到我了</span><br>
    <button @click="change">change</button>
  </div>
<script src="https://unpkg.com/vue@next"></script>
<script>
   const con={
       data(){
           return{
               seen:true
           }
       },
       methods: {
           change(){
               this.seen=!this.seen
           }
       }
   }
   Vue.createApp(con).mount('#vIf')
</script>

 指令可以绑定数组的数据来渲染一个项目列表

v-for

v-for 指令可以绑定数组的数据来渲染一个项目列表

<div id="list-rendering">
  <ol>
    <li v-for="todo in todos">
      {{ todo.text }}
    </li>
  </ol>
</div>

const ListRendering = {
  data() {
    return {
      todos: [
        { text: 'Learn JavaScript' },
        { text: 'Learn Vue' },
        { text: 'Build something awesome' }
      ]
    }
  }
}

Vue.createApp(ListRendering).mount('#list-rendering')

image-20210920121944418

组件化应用构建

  1. 允许我们使用小型、独立和通常可复用的组件构建大型应用

  2. 组件本质上是一个具有预定义选项的实例

  3. 创建组件过程

    // 创建 Vue 应用
    const app = Vue.createApp(...)
    
    // 定义名为 todo-item 的新组件
    app.component('todo-item', {
      template: `<li>This is a todo</li>`
    })
    
    // 挂载 Vue 应用
    app.mount(...)
    

    子单元通过 prop 接口与父单元进行了良好的解耦

应用 & 组件实例

根组件

传递给 createApp 的选项用于配置根组件。当我们挂载应用时,该组件被用作渲染的起点。

一个应用需要被挂载到一个 DOM 元素中。例如,如果我们想把一个 Vue 应用挂载到 <div id="app"></div>,我们应该传递 #app

const RootComponent = { /* 选项 */ }
const app = Vue.createApp(RootComponent)
const vm = app.mount('#app')

mount返回的是根组件实例;通常会使用vm这个变量名标识组件实例

组件实例 property

data 中定义的 property 是通过组件实例暴露的;也暴露了一些内置property,如 $attrs$emit

组件实例的所有 property,无论如何定义,可以在组件的模板中访问。

const app = Vue.createApp({
    data() {
        return {
            count: 4
        }
    }
})
const vm = app.mount('#app')
console.log(vm.count)//4

还有各种其他的组件选项:methodspropscomputedinjectsetup

生命周期钩子

组件创建时的初始化过程:需要设置数据监听、编译模板、将实例挂载到 DOM 并在数据变化时更新 DOM 等,也会运行一些叫做生命周期钩子的函数

  1. created钩子

    const app = Vue.createApp({
        data() {
            return {
                count: 1
            }
        },
        created() {
            // `this` 指向 vm 实例
            console.log('count is: ' + this.count) //"count is: 1"
        }
    })
    const vm = app.mount('#app')
    
  2. 其他钩子: mountedupdatedunmounted

在选项property或回调上不能使用this箭头函数并没有 this,,this 会作为变量一直向上级词法作用域查找,直至找到为止

模板语法

允许开发者声明式地将 DOM 绑定至底层组件实例的数据

插值

文本插值

形式:Mustache 标签将会被替代为对应组件实例中 msg property 的值

<p>Using mustaches: {{ msg }}</p>
  • v-once:只渲染元素和组件一次,当数据改变时,插值处的内容不会更新。用于优化更新性能

原始 HTML

双大括号会将数据解释为普通文本,而非 HTML 代码,所以我们得使用v-html

动态渲染任意的 HTML 容易导致XSS攻击

<div id="example1" class="demo">
    <p>Using mustaches: {{ rawHtml }}</p>
    <p>Using v-html directive: <span v-html="rawHtml"></span></p>
</div>

const RenderHtmlApp = {
    data() {
        return {
            rawHtml: '<span style="color: red">This should be red.</span>'
        }
    }
}
Vue.createApp(RenderHtmlApp).mount('#example1')

image-20210920142916557

Attribute

对于布尔 attribute (它们只要存在就意味着值为 true),值是 nullundefined没有作用

避免使用大写字符来命名键名,因为浏览器会把 attribute 名全部强制转为小写

使用 JavaScript 表达式

每个绑定都只能包含单个表达式

{{ number + 1 }} 
{{ ok ? 'YES' : 'NO' }} 
{{ message.split('').reverse().join('')}}

<div v-bind:id="'list-' + id"></div>

指令

指令 (Directives) 是带有 v- 前缀的特殊 attribute

指令的职责

当表达式的值改变时,将其产生的连带影响,响应式地作用于 DOM

参数

一些指令能够接收一个“参数”,v-bind 指令可以用于响应式地更新 HTML attribute;v-on 指令,它用于监听 DOM 事件

动态参数

在指令参数中使用 JavaScript 表达式,方法是用方括号括起来

<a v-bind:[attributeName]="url"> ... </a>

可以使用动态参数为一个动态的事件名绑定处理函数

修饰符

修饰符 (modifier) 是以半角句号.指明的特殊后缀;例如,.prevent 修饰符告诉 v-on 指令对于触发的事件调用 event.preventDefault()

缩写

v-bind 缩写

<!-- 完整语法 -->
<a v-bind:href="url"> ... </a>
<!-- 缩写 -->
<a :href="url"> ... </a>
<!-- 动态参数的缩写 -->
<a :[key]="url"> ... </a>

v-on 缩写

<!-- 完整语法 -->
<a v-on:click="doSomething"> ... </a>
<!-- 缩写 -->
<a @click="doSomething"> ... </a>
<!-- 动态参数的缩写 (2.6.0+) -->
<a @[event]="doSomething"> ... </a>

Data Property 和方法

Data Property

data 选项是一个函数,返回一个对象,该对象的任何顶级 property 也直接通过组件实例暴露出来

  1. 修改 vm.count的值也会更新 $data.count
  2. 修改 $data.count 的值也会更新vm.count

方法methods

Vue 自动为 methods 绑定 this,以便于它始终指向组件实例;

methodsdata property一样可以在组件的模板中被访问;

通常被当做事件监听使用。

防抖和节流

Vue 没有内置支持防抖和节流,但可以使用 Lodash 等库来实现。

计算属性和侦听器

计算属性

对于任何包含响应式数据的复杂逻辑,通常使用计算属性

<div id="computed-basics">
    <p>书的数量:</p>
    <span>{{ publishedBooksMessage }}</span>//YES
</div>
<script src="https://unpkg.com/vue@next"></script>
<script>
    Vue.createApp({
        data() {
            return {
                author: {
                    name: 'John Doe',
                    books: ['语文','数学','英语']
                }
            }
        },
        computed: {
            // 计算属性的 getter
            publishedBooksMessage() {
                // `this` points to the vm instance
                return this.author.books.length > 0 ? 'Yes' : 'No'
            }
        }
    }).mount('#computed-basics')
</script>

计算属性缓存 vs 方法

不同的是计算属性是基于它们的反应依赖关系缓存的

计算属性只在相关响应式依赖发生改变时它们才会重新求值(author.books不变,多次访问publishedBookMessage 计算属性会立即返回之前的计算结果)

计算属性的 Setter

计算属性默认只有 getter,不过在需要时你也可以提供一个 setter:

侦听器

watch 选项提供了一个更通用的方法,来响应数据的变化。

当需要在数据变化时执行异步或开销较大的操作时,watch 方式最有用

使用 watch 选项允许我们执行异步操作 (访问一个 API),限制我们执行该操作的频率,并在我们得到最终结果前,设置中间状态

<script src="https://cdn.jsdelivr.net/npm/axios@0.12.0/dist/axios.min.js"></script>
<script>
  const watchExampleVM = Vue.createApp({
    data() {
      return {
        question: '',
        answer: 'Questions usually contain a question mark. ;-)'
      }
    },
    watch: {
      // whenever question changes, this function will run
      question(newQuestion, oldQuestion) {
        if (newQuestion.indexOf('?') > -1) {
          this.getAnswer()
        }
      }
    },
    methods: {
      getAnswer() {
        this.answer = 'Thinking...'
        axios
          .get('https://yesno.wtf/api')
          .then(response => {
            this.answer = response.data.answer
          })
          .catch(error => {
            this.answer = 'Error! Could not reach the API. ' + error
          })
      }
    }
  }).mount('#watch-example')
</script>

计算属性 vs 侦听器

观察和响应当前活动的实例上的数据变动:侦听属性

<div id="demo">{{ fullName }}</div>
<script src="https://unpkg.com/vue@next"></script>
<script>
    const vm = Vue.createApp({
        data() {
            return {
                firstName: 'Foo',
                lastName: 'Bar'
            }
        },
        computed: {
            fullName() {
                return this.firstName + ' ' + this.lastName
            }
        }
    }).mount('#demo')
</script>

Class 与 Style 绑定

绑定 HTML Class

对象语法

可绑定到data property里面也可以绑定到返回对象的计算属性computed里面

<div :class="{ active: isActive, 'text-danger': hasError }"></div>
data() {
  return {
    isActive: true,
    hasError: false
  }
}
//渲染的结果为:<div class="active"></div>

数组语法

<div :class="[activeClass, errorClass]"></div>
<div :class="[isActive ? activeClass : '', errorClass]"></div>

在组件上使用

绑定内联样式

对象语法

CSS property 名可以用驼峰式 (camelCase) 或短横线分隔 (kebab-case,记得用引号括起来) 来命名

<div :style="{ color: activeColor, fontSize: fontSize + 'px' }"></div>

数组语法

自动添加前缀

多重值

条件渲染

  1. v-if:用于条件性地渲染一块内容
  2. v-else来表示 v-if 的“else 块”
  3. v-show用于根据条件展示元素的选项是 v-show 指令(带有 v-show 的元素始终会被渲染并保留在 DOM 中)
    • 注意,v-show 不支持 <template> 元素,也不支持 v-else
    • v-ifv-for一起使用,v-if优先级高,这意味着 v-if 将没有权限访问 v-for 里的变量

v-if 和 v-show的区别

  1. v-if是“真正”的条件渲染,因为它会确保在切换过程中条件块内的事件监听器和子组件适当地被销毁和重建
  2. v-if是惰性的,在渲染条件为假时,什么也不做,直到为真时才会开始渲染条件快
  3. v-show不管条件是什么都会渲染,并且只是简单的基于css进行切换
  4. 若切换频繁,则v-show较好,若运行条件很少,则v-if较好

列表渲染

  1. v-for 把一个数组对应为一组元素
  • v-for="item in items"
    //第二个参数作为索引
    v-for="(item, index) in items"
    
  1. v-for 里使用对象

    • v-for="value in myObject"
      //第二个的参数为 property 名称
      v-for="(value, name) in myObject"
      //第三个参数作为索引
      v-for="(value, name, index) in myObject"
      
  2. 维护状态

    • Vue 正在更新使用 v-for 渲染的元素列表时,它默认使用“就地更新”的策略。

    • 只适用于不依赖子组件状态或临时 DOM 状态 (例如:表单输入值) 的列表渲染输出

  3. 数组更新检测

    • 变更方法:push()pop()shift()unshift()splice()sort()reverse()
      • example1.items.push({ message: ‘Baz’ })
    • 替换数组:filter()concat()slice()
  4. <template> 中使用 v-for

事件处理

监听事件v-on

可以使用 v-on 指令 (通常缩写为 @ 符号) 来监听 DOM 事件,并在触发事件时执行一些 JavaScript

用法

  1. v-on:click="methodName"
  2. @click="methodName"

事件处理方法

在methods里面写事件处理方法

内联处理器中的方法

  1. 除了直接绑定到一个方法,也可以在内联 JavaScript 语句中调用方法

  2. 用特殊变量 $event 把它传入方法

    •  @click="warn('Form cannot be submitted yet.', $event
      methods: {
        warn(message, event) {
          // now we have access to the native event
          if (event) {
            event.preventDefault()
          }
          alert(message)
        }
      }
      

多事件处理器

事件处理程序中可以有多个方法,这些方法由逗号运算符分隔

<button @click="one($event), two($event)">Submit</button>

事件修饰符

修饰符是由点开头的指令后缀来表示的。

.stop.prevent.capture.self.once.passive

<!-- 阻止单击事件继续传播 -->
<a @click.stop="doThis"></a>

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

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

<!-- 只有修饰符 -->
<form @submit.prevent></form>

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

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

按键修饰符

<!-- 只有在 `key` 是 `Enter` 时调用 `vm.submit()` -->
<input @keyup.enter="submit" />

处理函数只会在 $event.key 等于 'PageDown' 时被调用

按键别名

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

系统修饰键

.ctrl.alt.shift.meta

.exact 修饰符

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

表单输入绑定

基础用法

可以用 v-model 指令在表单 <input><textarea><select> 元素上创建双向数据绑定。它负责监听用户的输入事件以更新数据,并对一些极端场景进行一些特殊处理。

  1. 文本 (Text)
<input v-model="message" placeholder="edit me" />
<p>Message is: {{ message }}</p>
  1. 多行文本 (textarea)

  2. 复选框 (Checkbox)

  3. 单选框 (Radio)

  4. 选择框 (Select)

修饰符

  1. .lazy:在“change”时而非“input”时更新(v-model.lazy=“msg”)
  2. .number:自动将用户的输入值转为数值类型(v-model.number=“age”)
  3. .trim:自动过滤用户输入的首尾空白字符(v-model.trim=“msg”)

组件基础

因为组件是可复用的组件实例,所以它们与 new Vue 接收相同的选项,例如 datacomputedwatchmethods 以及生命周期钩子等。仅有的例外是像 el 这样根实例特有的选项。

组件的复用

为了能在模板中使用,这些组件必须先注册以便 Vue 能够识别。这里有两种组件的注册类型:全局注册局部注册

全局注册的组件可以在随后创建的 app 实例模板中使用,也包括根实例组件树中的所有子组件的模板中。

通过 Prop 向子组件传递数据

一个组件默认可以拥有任意数量的 prop,任何值都可以传递给任何 prop。

我们可以使用 v-bind 来动态传递 prop。

<div id="blog-posts-demo">
    <blog-post
      v-for="post in posts"
      :key="post.id"
      :title="post.title"
      :id="post.id"
    ></blog-post>
  </div>
<script src="https://unpkg.com/vue@next"></script>
<script>
    const app = Vue.createApp({
        data() {
            return {
                posts: [{id: 1,title: 'My journey with Vue'},{id: 2,title: 'Blogging with Vue'},{id: 3,title: 'Why Vue is so fun'}]
            }
        }
    })
    app.component('blog-post', {
        props: ['title','id'],
        template: `<h4>{{id}}-{{ title }}</h4>`
    })
    app.mount('#blog-posts-demo')
</script>

监听子组件事件

  1. 父级组件通过 v-on@ 监听子组件实例的任意事件
  2. 子组件通过调用内建的 $emit并传入事件名称来触发一个事件
  3. 通过 @enlarge-text="postFontSize += 0.1" 监听器,父级将接收事件并更新 postFontSize

使用事件抛出一个值

  1. 子组件使用 $emit 的第二个参数来抛出这个值(@click="$emit('enlarge-text', 0.1)")
  2. 父级组件通过 $event 访问到被抛出的这个值(@enlarge-text="postFontSize += $event")

通过插槽分发内容

Vue 自定义的 <slot> 元素实现分发内容

app.component('alert-box', {
  template: `
    <div class="demo-alert-box">
      <strong>Error!</strong>
      <slot></slot>
    </div>
  `
})
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值