Vue配置起步(一)

552 阅读8分钟

这是我参与8月更文挑战的第5天,活动详情查看:8月更文挑战

前言

有小伙伴看见标题开头就可能觉得是水文章的,至于为啥要写个这么基础的文章呢?因为Vue系列的文章也写了有几篇了,有组件、反向传值、Vuex等等,感兴趣的可以在文末查看或前往专栏查阅。所以啊,纯粹是想补全一下Vue系列的知识点罢了,希望能帮助刚踏进Vue大门的hxd。因为可能刚开始看文档肯定是比较的不熟悉的(大佬懂的,不敢说话...)。后面几篇文章也有可能是一些比较基础的文章,然后案例伪代码的话也不是单文件演示的形式,我猜大家一开始不会用脚手架吧,当然也有例外,纯粹个人看法啊(勿喷)。好吧。废话不多说,进入我们的正题。

介绍

是一套基于MVVM设计模式用于构建用户界面的渐进式框架。与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用。Vue 的核心库只关注视图层,不仅易于上手,还便于与第三方库或既有项目整合。另一方面,当与现代化的工具链以及各种支持类库结合使用时,Vue 也完全能够为复杂的单页应用提供驱动。

MVC全名是Model View Controller,是模型(model)视图(view)控制器(controller)的缩写,一种软件设计典范

说起MVC,这里引用斯坦福大学公开课上的这幅图来说明,可以说是最经典和最规范的MVC标准

mvc.png(图片来源于网络)

MVVM全名是Model View ViewModel模型(model)视图(view)视图模型(view-model)的缩写,其实 MVVM真实应该叫做MVCVM

安装

  • 方法一: 在html 文件中引入vue.js
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
  • 方法二: 通过npm下载vue模块
npm i -s vue
  • 方法三: 通过Vue 官方脚手架 vue-cli 搭建vue组件化项目
#全局安装 vue-cli 环境变量中
npm install -g @vue/cli 
# 使用 vue-cli指令搭建单页面应用项目
vue create hello-world

起步

实例化一个Vue对象,后面的话如果没有特别说明也是基于这个模板进行伪代码的演示

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style></style>
</head>

<body>
    <!--引入Vue三方库-->
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>

    <!--创建一个DOM元素-->
    <div id="app"></div>

    <script>
    // 实例化一个Vue对象
    // Vue 构造函数接收配置对象
    new Vue({
           el: '#app' // el 指定页面中DOM元素,Vue就会以这个DOM为挂载对象
    })
    </script>
</body>

</html>

配置

el

提供一个在页面上已存在的 DOM 元素作为 Vue 实例的挂载目标。可以是 CSS 选择器,也可以是一个 HTMLElement 实例。挂载完毕后当前DOM内部渲染将会由当前Vue实例对象所管理与控制

new Vue({
    el: '#app'
})

data

(属性)存放当前Vue实例对象数据的配置。Vue 将会递归dataproperty 转换为 getter/setter,从而让 dataproperty 能够响应数据变化对象必须是纯粹的对象 (含有零个或多个的 key/value 对):浏览器 API 创建的原生对象,原型上的 property 会被忽略。大概来说,data 应该只能是数据 - 不推荐观察拥有状态行为的对象

注意: data 对象自身可以被实例对象的$data所访问,在所有data直接子属性都可以被实例对象直接访问.

var vm = new Vue({
    el: '#app',
    data: {
        name: '小明',
        age: 18,
        detail: {
            tel: 138121345678,
            eMail: helloworld@163.com,
            address: '广州'
        }
    }
})

vm.$data // data对象
vm.age // 等价于 vm.$data.age
vm.detail.tel // vm.$data.detail.tel 因为tel不是直接子属性不能直接访问

Vue数据双向绑定是通过数据劫持结合发布者-订阅者模式的方式来实现的,Vue在初始化使用Object.defineProperty递归的将data的属性添加一个getter/setter (监听器Observer),用来劫持并监听所有属性(Vue 解析器Compile,可以扫描和解析每个节点的相关指令,并根据初始化模板数据以及初始化相应的订阅器即调用当前属性getter方法的元素就是订阅者)。Vue会把所有当前data的订阅者存放在一个dep名单中,如果有变动的,就通过dep名单通知所有订阅者。从而更新视图。 100.png

模板语法

双大括号文本差值

概念: Vue.js 的核心是一个允许采用简洁的模板语法来声明式地将数据渲染进 DOM 的系统:vue使用 {{}} (双大括号语法) 将实例中的属性或者其他js表达式插值绑定到模板的任何文本节点中

语法:

<div id="app">
   内部都由Vue实例对象管理 
   <p>姓名:{{name}}</p>
   <p>年龄:{{age}}</p>
   <p>状态:{{age >= 18 ? '已成年':'未成年'}}</p>
</div>

<script>
   let vm = new Vue({
        el: '#app',
        data: {
            name: '小明',
            age: 18
        }
    })
</script>

注意:

双大括号语法会将内部的表达式以纯文本的形式插入到对应节点内部。这种模式可以预防xss攻击(注入攻击将一段恶意脚本发送到html页面从而获取用户的cookie信息)

<div id="app">
       <p>{{script}}</p> 
        // 这里渲染的结果是'<div>hello world<div>'文本节点,而不是一个dom元素
</div>

<script>
       let vm = new Vue({
            el: '#app',
            data: {
                script: '<div>hello world<div>'
            }
        })
</script>

指令

v-html

可以将文本以html形式插入到指定节点内部而不用向上面一样插入一个纯文本。注意不要把这个方法暴露给用户!

指令语法: 在虚拟DOM标签上 指令="js表达式"

 <div id="app">
   <p>{{script}}</p>   // 纯文本
   <div v-html="script"></div> // h3dom元素
</div>

<script>
   let vm = new Vue({
        el: '#app',
        data: {
            script: '<h3>hello world</h3>'
        }
    })
</script>

v-once

一次性地插值,当数据改变时,插值处的内容不会更新

v-bind属性差值

概念: 使用指令 v-bind:属性 ="js表达式" 形式将实例中的data或者其他js表达式插值绑定到标签的任何属性节点中

语法:

 <div id="app">
       已成年<input type="radio" v-bind:checked="age >= 18"/>
       未成年<input type="radio" v-bind:checked="age < 18"/>
</div>

<script>
       let vm = new Vue({
            el: '#app',
            data: {
                age: 18,
            }
        })
</script>

注意:

  1. v-bind:指令可以简写成一个冒号 ":"
<div id="app">
       已成年<input type="radio" :checked="age >= 18"/>
       未成年<input type="radio" :checked="age < 18"/>
</div>

<script>
       let vm = new Vue({
            el: '#app',
            data: {
                age: 18,
            }
        })
</script>
  1. v-bind 支持动态属性
<div id="app">
       <a v-bind:[attrname]="link"> 百度 </a>
       // <a src="http://www.baidu.com"> 百度 </a>
</div>

<script>
       let vm = new Vue({
            el: '#app',
            data: {
                attrname: 'src',
                link: 'http://www.baidu.com'
            }
        })
</script>

注意:

  1. 动态参数预期会求出一个字符串,异常情况下值为 null。这个特殊的 null 值可以被显性地用于移除绑定。任何其它非字符串类型的值都将会触发一个警告。
  2. 空格和引号,放在 HTML attribute 名里是无效的
<a v-bind:['foo' + bar]="value"> ... </a> // 错误

v-bind绑定class

1. 对象语法

我们观察下面代码,我们给每一段歌词元素都绑定了一个class类。内部js表达式逻辑就是当currentIndex 与歌词下标匹配时,歌词元素的class值就会变成active否则为空。但是我们发现,代码过于繁琐。Vue针对class提供对象语法来简化下面的代码

<div id="app">
    <p v-bind:class="currentIndex === 0 ? 'active': ''">第一段歌词 0</p>
    <p v-bind:class="currentIndex === 1 ? 'active': ''">第二段歌词 1</p>
    <p v-bind:class="currentIndex === 2 ? 'active': ''">第三段歌词 2</p>
    <p v-bind:class="currentIndex === 3 ? 'active': ''">第四段歌词 3</p>
    <p v-bind:class="currentIndex === 4 ? 'active': ''">第五段歌词 4</p>
</div>

<script>

    let vm = new Vue({
        el: '#app',
        data: {
            currentIndex: 3
        }
    })

</script>

v-bind绑定的class支持对象写法: v-bind:class = {class名: 判别式}.当判别式为真时,保留该类名否则删除该类名

上面的代码可以使用class 对象语法简写为

<div id="app">
    <p v-bind:class="{active: currentIndex === 0}">第一段歌词 0</p>
    <p v-bind:class="{active: currentIndex === 1}">第二段歌词 1</p>
    <p v-bind:class="{active: currentIndex === 2}">第三段歌词 2</p>
    <p v-bind:class="{active: currentIndex === 3}">第四段歌词 3</p>
    <p v-bind:class="{active: currentIndex === 4}">第五段歌词 4</p>
</div>

<script>

    let vm = new Vue({
        el: '#app',
        data: {
            currentIndex: 3
        }
    })

</script>

2. 数组语法

Vue还支持v-bind:class数组写法,数组中的每一项都可以是js表达式,并且数组中可以包含class对象写法

<div id="app">
    <p v-bind:class="currentIndex === 0 ? 'active lry ' + className : 'lry '+ className">第一段歌词 0</p>
    <p v-bind:class="[{active: currentIndex === 1}, 'lry', className]">第二段歌词 1</p>
    <p v-bind:class="[{active: currentIndex === 2}, 'lry', className]">第三段歌词 2</p>
    <p v-bind:class="[{active: currentIndex === 3}, 'lry', className]">第四段歌词 3</p>
    <p v-bind:class="[{active: currentIndex === 4}, 'lry', className]">第五段歌词 4</p>
</div>

<script>

    let vm = new Vue({
        el: '#app',
        data: {
            currentIndex: 3,
            className: 'test'
        }
    })

</script>

注意 :

  1. class 的数组语法,对象语法中的数组或对象都可以存放data中绑定给class (data中不要使用this)
  2. 一个dom元素中可以最对同时拥有 一个绑定的class属性和一个普通class属性
<p v-bind:class="[{active: currentIndex === 3}, 'lry', className]">第四段歌词 3</p>
<p class="lry" v-bind:class="[{active: currentIndex === 4}, className]">第五段歌词 4</p>

v-bind绑定style

1. 对象语法

概念: v-bind:style 的对象语法十分直观——看着非常像 CSS,但其实是一个 JavaScript 对象。CSS property 名可以用驼峰式 (camelCase) 或短横线分隔 (kebab-case,记得用引号括起来) 来命名:

<div id="app">

    <p v-bind:style="{
        color,
        backgroundColor,
        // 短横线命名需要加引号
        'font-size': '18px'
    }">我是一段文本</p>

</div>

<script>
    new Vue({
        el: '#app',
        data: {
            color: 'blue',
            backgroundColor: 'orange'
        }
    })
</script>

2. 数组语法

概念: v-bind:style 的数组语法可以将多个样式对象应用到同一个元素上

<div id="app">

    <p v-bind:style="[defaultStyle,{
        color,
        backgroundColor,
        fontSize: '18px'
    }]">我是一段文本</p>

</div>

<script>
    new Vue({
        el: '#app',
        data: {
            color: 'blue',
            backgroundColor: 'orange',
            defaultStyle: {
                fontWeight: 700,
                border: '1px solid #ccc'
            }
        }
    })
</script>

3.v-bind:style的多重值

概念: style 绑定中的 样式属性可以提供一个包含多个值的数组,常用于提供多个带前缀的值,例如:

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

这样写只会渲染数组中最后一个被浏览器支持的值。在本例中,如果浏览器支持不带浏览器前缀的 flexbox,那么就只会渲染 display: flex

4.v-bind:style自动添加前缀

概念: 当 v-bind:style 使用需要添加浏览器引擎前缀的 CSS property 时,如 transform,Vue.js 会自动侦测并添加相应的前缀。

结尾

今天就先到这里啦!我们下期再见!码字不易,觉得不错的可以动动小指头点点赞啥的哟~

系列文章

Vue系列

Vue-Router系列

Vuex系列