vue

Vue.js

vue.js

vue.js 是一套用于构建用户界面的渐进式框架

渐进式

Vue 核心

  • 声明式渲染
  • 组件

引入

我们还是先通过 <script> 的方式来引入 vue

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

组件

vue 的核心功能之一就是组件

组件基本分类

  • 根组件
  • 可复用的功能组件

根组件的创建

通过 vue 提供的构造函数可以实例化出来一个跟组件实例对象

let app = new Vue(创建组件所需要的一些配置选项);
复制代码

可复用的功能组件

通过 Vue 提供的静态方法 component 窗口可复用的功能组件

let component1 = Vue.component(创建组件所需要的一些配置选项)
复制代码

组件配置选项:cn.vuejs.org/v2/api/

组件内容渲染

渲染一个组件的内容可以通过两种方式来进行

  • template 选项
  • render 选项(函数)

template

type : string

组件的模板结构(HTML),模板内容会被 vue 进行渲染,生成最终的 HTML 内容,并替换占位(挂载)元素

el

type : string | Element

提供一个在页面上已存在的 DOM 元素作为 Vue 实例的挂载目标。可以是 CSS 选择器,也可以是一个 HTMLElement 实例,

  • 该选择只对 new 创建的实例有效
  • 如果提供 el ,但是没有提供 template ,则 el 的内容讲作为 template

render

type : (createElement: () => VNode) => VNode

发挥 JavaScript 最大的编程能力,直接创建 VNode (虚拟dom对象),优先级高于 eltemplate

  • 有更强大的编程能力
  • 有更高的性能

cn.vuejs.org/v2/guide/re…

使用 $mount 方法延迟 Vue 实例的挂载

Vue 实例没有 el 选项的时候,它会处于一种 未挂载 的状态,我们可以通过组件 Vue 实例对象的 $mount 方法来手动挂载,通过该方式,我们也可以达到延迟 Vue 实例的挂载的目的

组件中的数据(状态)

data

组件内部使用的数据,data 是一个对象,data 中的值可以中模板中直接访问

  • Vue 实例组件(根组件)的 data 是一个对象
  • 可复用功能组件的 data 必须是一个函数,且该函数必须返回一个对象(因为复用性,避免多个组件实例引用同一个对象。换句话说,组件中使用的数据必须是一个对象,但是可复用组件的这个数据对象必须通过函数返回

data 的访问

data 数据可以直接通过组件实例对象访问,也可以通过实例对象下的 $data 属性进行访问

组件实例对象下有很多的以 $ 开头的属性,这些都是实例对象内置的一些属性和方法,vue 为了区分数据与内置属性方法,内置的属性和方法默认都是以 $ 开始的,所以我们中数据中应该避免使用 $ 开头的数据

模板语法

vue 使用了基于 html 的模板语法,使用声明式的方式把实例中的数据(data)与 DOM 进行绑定,data 中的数据在模板中可以直接使用

Mustache(双大括号,大胡子) 语法

在 vue 中,我们是通过一对双大括号把实例中的数据渲染到模板内容中

插值表达式

在 {{}} 中,我们可以放置表达式值

{{表达式}}
复制代码
new Vue({
  el: '#app',
  data: {
    title: 'vue 框架'
  },
  template: `<div>{{title}}</div>`
});
复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>

    <div id="app">
      {{title}}
  	</div>
    
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>

    <script>
        let app = new Vue({
            el: '#app',
            data: {
              title: 'vue 框架'
            }
        });
    </script>
</body>
</html>
复制代码

数据到视图的更新

vue 会把 data 中的数据挂载到实例属性下,同时对它们进行主动的监听拦截,当数据发生变化的时候,重新渲染模板。我们可以通过实例对象对数据进行修改

app.title = '开课吧';
// or
app.$data.title = '开课吧';
复制代码

检测变化的注意事项

在 vue3 之前,数据的监听是通过 Object.defineProperty 方法来实现的,但是该方法只能监听拦截单个数据,对于对象新增属性无法监听拦截。所以,对于数据对象中新增的属性,我们需要调用 vue 提供的方法来进行处理

扩展

通过 Object.defineProperty 监听拦截中存在一些问题

  • 属性新增属性
  • 数组方法:push、pop、shift、unshift、splice、sort、reverse
  • 数组新增值:[]
  • 数组 length 属性

以上的操作中并不会触发监听拦截

vue 对数组中的 pushpop 等方法进行重新包装,所以在 vue 中调用这些方法,可以对数组的修改进行监听拦截

cn.vuejs.org/v2/guide/li…

使用 Vue.set 方法添加新数据

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>

    <div id="app">
        <p>title: {{title}}</p>
        <p>user.username: {{user.username}}</p>
        <p>user.gender: {{user.gender}}</p>
    </div>
    
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>

    <script>
        let app = new Vue({
            el: '#app',
            data: {
                title: 'vue 框架',
                user: {
                    username: 'zMouse'
                }
            }
        });
    </script>
</body>
</html>
复制代码

在模板中,我们使用了一个不存在的数据 user.gender

如果我们通过 app.user.gender = '男' 的方式来新增,是不会被 vue 拦截监听处理的,我们需要使用

Vue.set(app.user, 'gender', '男');
// 实例.$set 是 Vue.set 的别名
app.$set(app.user, 'gender', '男');
复制代码

这样的方式,set 方法给 app.user 添加 gender 属性的同时,对它进行了 defineProperty

指令

表达式的值除了可以出现内容中,也可以使用在其它位置,比如:属性。但是不能使用 {{}} 语法,而是需要 指令

vue 中,指令是一个带有 v- 前缀的属性,与普通属性不一样的地方在于,指令的值是引号括起来的 表达式,不同的指令有不同的作用,vue 内置了一些常用的指令,后期我们还可以自定义属于自己的指令

  • 内容输出
  • 循环
  • 逻辑
  • 属性绑定
  • 事件
  • 其它

内容输出

通过 {{}} 我们可以很方便的中模板中输出数据,但是这种方式会有一个问题,当页面加载渲染比较慢的时候,页面中会出现 {{}}vue 提供了几个指令来解决这个问题

指令中的表达式不需要使用 {{}}

v-text

<p v-text="title"></p>
复制代码

弊端:v-text 会填充整个 innerHTML

v-cloak

<p v-cloak>{{title}}</p>
复制代码

需要配合 css 进行处理

<style>
[v-cloak] {
  display: none;
}
</style>
复制代码

v-html

为了防止 xss 攻击,默认情况下输出是不会作为 html 解析的,通过 v-html 可以让内容作为 html 进行解析

v-once

只渲染元素和组件一次,后期的更新不再渲染

v-pre

忽略这个元素和它子元素内容的编译

逻辑处理

v-show

根据表达式的值(布尔值),切换元素的显示与隐藏(display 属性)

适用于状态切换比较频繁的情况

v-if

根据表达式的值(布尔值),创建或销毁元素

适用于状态切换不频繁的情况

v-else / v-else-if

v-else 配合

循环与列表

v-for

根据数据循环渲染 v-for 指令所在的元素及其子元素

可以循环的数据:Array | Object | number | string | Iterable (2.6 新增)

<div v-for="(item, index) in items"></div>
<div v-for="(val, key) in object"></div>
<div v-for="(val, key, index) in object"></div>
复制代码

v-for 中也可以使用 of 语法,在 vue 中两者没有什么区别

:key

默认情况下,在渲染 DOM 过程中使用 原地复用 ,这样一般情况下会比较高效,但是对于循环列表,特别是依赖某种状态的列表,会有一些问题,我们可以通过 :key 属性,来给每个循环节点添加一个标识

属性绑定

v-bind

绑定数据(表达式)到指定的属性上,<div v-bind:参数="值/表达式"></div>,这里的参数就是指定的属性名称

<div id="app">
  <div v-bind:id="'box1'"></div>
  <div v-bind:id="myId"></div>
</div>

<script>
	new Vue({
    el: '#app',
    data: {
      myId: 'kaikeba'
    }
  })
</script>
复制代码

缩写

有的一些常用指令会有对应的缩写,v-bind 对应的缩写为::

<div :id="myId"></div>
复制代码

样式

针对样式属性,v-bind 值有一些特殊的写法

style

原生普通写法

<div style="width: 100px; height: 100px; background: red"></div>
复制代码

v-bind 写法

<div :style="'width: 100px; height: 100px; background: red'"></div>
复制代码

对象写法

<div :style="style1"></div>

...
<script>
new Vue({
	el: '#app',
	data: {
		style1: {
      width: '100px',
      height: '100px',
      background: 'green'
    }
	}
});
</script>
复制代码

数组写法

<div :style="[style1, style2]"></div>

...
<script>
new Vue({
	el: '#app',
	data: {
		style1: {
      width: '100px',
      height: '100px',
      background: 'green'
    }
	},
  style2: {
    border: '1px solid black'
  }
});
</script>
复制代码

class

原生普通写法

<div class="box1 box2"></div>
复制代码

v-bind 写法

<div :class="'box1 box2'"></div>
复制代码

数组写法

<div :class="['box1', 'box2']"></div>
复制代码

对象写法

<div :class="{'box1': isActive, 'box2': isChecked}"></div>
复制代码

使用对象写法,可以根据值(boolean)动态添加对应的 class

单向数据流

通过上面的知识点和案例,我们可以看到,当数据更新的时候,页面视图就会更新,但是页面视图中绑定的元素更新的时候,对应的数据是不会更新的

<input type="text" :value="title" />
复制代码

我们称为:单向数据流 数据 -> 视图

在 vue 中,还有一种双向数据流绑定的方式

v-model

<input type="text" v-model="title" />
复制代码

数据 title 更新,视图中 inputvalue 就会更新。同时,当 input 中的 value 更新的时候,数据 title 也会更新,这就是我们说的 数据双向绑定 [与 React 中的受控组件类似]

表单

针对一般元素,比如 div、span、p、img 等,采用的是单向绑定:v-bind,只需要把数据绑定到视图中就可以,但是对于表单这种交互性比较强的元素或组件,我们一般可能需求双向绑定,即:用户对视图元素的操作同时更新数据

v-model 在内部为不同的输入元素使用不同的属性和事件来处理数据

  • texttextarea
  • checkboxradio
  • select

texttextarea

texttextarea 元素使用 value 属性和 input 事件

<div id="app">
  <input type="text" v-model="v1" />
  <textarea v-model="v2" cols="30" rows="10"></textarea>
</div>
复制代码
let app = new Vue({
  el: '#app',
  data: {
    v1: 'aaa',
    v2: 'bbb'
  }
});
复制代码

checkboxradio

checkboxradio 使用 checked 属性和 change 事件

单选框绑定一个值

<div id="app">
  <input type="radio" v-model="v3" value="男" /><input type="radio" v-model="v3" value="女" /></div>
复制代码
let app = new Vue({
  el: '#app',
  data: {
    v3: '女',
  }
});
复制代码

多选框绑定到一个布尔值或数组

<div id="app">
  <input type="checkbox" v-model="v4" /> 同意
  <hr/>
  <input type="checkbox" v-model="v5" value="足球" /> 足球
  <input type="checkbox" v-model="v5" value="音乐" /> 音乐
</div>
复制代码
let app = new Vue({
  el: '#app',
  data: {
    v4: true,
    v5: ['足球', '音乐']
  }
});
复制代码

select

select 字段将 value 作为 prop 并将 change 作为事件

单选绑定到值,多选绑定到数组

<div id="app">
  <select v-model="v3">
    <option value="男"></option>
    <option value="女"></option>
  </select>
  <select v-model="v5" multiple>
    <option value="足球">足球</option>
    <option value="音乐">音乐</option>
  </select>
</div>
复制代码

指令修饰符

一个指令可以包含的内容包括:

  • 指令名称
  • 指令值
  • 指令参数
  • 指令修饰符
<组件 指令:参数.修饰符1.修饰符2="值" />
复制代码

.lazy

取代 input 监听 change 事件

.number

输入字符串转为有效的数字

.trim

输入首尾空格过滤

自定义指令

我们还可以通过 Vue 提供的方法来自定义指令

注册指令

vue 提供了两种指令注册方式

  • 全局指令
  • 局部指令

全局指令

Vue.directive('指令名称', {指令配置});
复制代码

局部指令

new Vue({
  el: '#app',
  directives: {
    '指令名称': {指令配置}
  }
});
复制代码

在使用指令的时候,需要使用 v-指令名称 的方式来调用

指令生命周期(钩子函数)

指令的运行方式很简单,它提供了一组指令生命周期钩子函数,我们只需要在不同的生命周期钩子函数中进行逻辑处理就可以了

  • bind : 只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置
  • inserted : 被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文档中)
  • update : 所在组件更新的时候调用
  • componentUpdated : 所在组件更新完成后调用
  • unbind : 只调用一次,指令与元素解绑时调用

不同的生命周期钩子函数在调用的时候同时会接收到传入的一些不同的参数

  • el : 指令所绑定的元素,可以用来直接操作 DOM
  • binding : 一个对象,包含以下属性:
    • name : 指令名,不包括 v- 前缀
    • value : 指令的绑定值(作为表达式解析后的结果)
    • expression : 指令绑定的表达式(字符串)
    • arg : 传给指令的参数,可选
    • modifiers : 传给指令的修饰符组成的对象,可选,每个修饰符对应一个布尔值
    • oldValue : 指令绑定的前一个值,仅在 update 和 componentUpdated 钩子中可用,无论值是否改变都可用

案例

官网的例子

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>

    <div id="app">
        <input type="text" v-focus>
    </div>
    
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>

    <script>

        Vue.directive('focus', {
            inserted(el) {
                el.focus();
            }
        });
        
        let app = new Vue({
            el: '#app'
        });
    </script>
</body>
</html>
复制代码

扩展:自定义拖拽指令

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
        .box {
            position: absolute;
            left: 100px;
            top: 100px;
            width: 100px;
            height: 100px;
            background: red;
        }
    </style>
</head>
<body>

    <div id="app">
        <button @click="canDrag = !canDrag">Drag : {{canDrag}}</button>
        <div class="box" v-drag.limit="canDrag"></div>
    </div>
    
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>

    <script>

        Vue.directive('drag', {
            bind(el, {modifiers,value}) {
                let isDragStart = false;
                let disX = 0;
                let disY = 0;
                el.canDrag = value;
                el.addEventListener('mousedown', e => {
                    if (!el.canDrag) return;
                    disX = e.clientX - el.offsetLeft;
                    disY = e.clientY - el.offsetTop;
                    isDragStart = true;

                    e.preventDefault();
                });
                document.addEventListener('mousemove', e => {
                    if (isDragStart) {
                        let x = e.clientX - disX;
                        let y = e.clientY - disY;

                        if (modifiers.limit) {
                            if (x < 0) {
                                x = 0;
                            }
                            if (y < 0) {
                                y = 0;
                            }
                        }

                        el.style.left = x + 'px';
                        el.style.top = y + 'px';
                    }
                });
                document.addEventListener('mouseup', e => {
                    isDragStart = false;
                });
            },
            componentUpdated(el, {value}) {
                console.log('componentUpdated', value);
                el.canDrag = value;
            }
        });
        
        let app = new Vue({
            el: '#app',
            data: {
                canDrag: false
            }
        });
    </script>
</body>
</html>
复制代码

事件

vue 中,事件通过指令 v-on 进行绑定,v-on 缩写 @

<组件 v-on:事件名称="表达式" />
<组件 @事件名称="表达式" />
复制代码

组件的 methods 选项

在组件选项中,提供了一个 methods 选项,用来存放组件中使用的函数方法,且存放在 methods 中的函数方法可以通过组件实例(this)进行访问

通过内联方式绑定事件处理函数

<组件 @事件名称="fn" />

<script>
new Vue({
  ...,
  methods: {
  	fn() {
  		//...	
		}
	}
})
</script>
复制代码
  • 事件绑定函数中的 this 指向组件实例
  • 事件绑定函数中的第一个参数默认为 event 对象
<组件 @事件名称="fn('kaikeba', $event)" />

<script>
new Vue({
  ...,
  methods: {
  	fn(name, ev) {
  		//...	
		}
	}
})
</script>
复制代码

也可以在事件绑定中直接调用函数(并不会立即执行,也是通过事件触发执行的)

  • 事件对象需要手动传入,名称为 $event

事件修饰符

在事件函数中,我们可以通过 ev.preventDefault()ev.stopPropagation() 来阻止默认行为,阻止冒泡,但是中 vue 中提供一些更加方便的方式来处理这些问题,这就是事件修饰符

.stop

.prevent

.capture

.self

.once

.passive

按键修饰符

vue 还提供了许多按键修饰符

.keyCode

<组件 @keyup.13="fn" />
复制代码

.enter

.down

.exact

原生事件

自定义组件中可以自定义一些事件,可以通过 .native 修饰符来指定监听原生中的事件,而不是组件自定义事件

computed

在实际的应用中,我们会有一些原始数据,同时在应用中又会有一些数据是根据某些原始数据派生出来的,针对这样的一种情况,vue 定义了一个专门用来处理这种派生数据的选项:computed

<div id="app">
  <label><input type="radio" v-model="gender" value="" /> 所有</label>
  <label><input type="radio" v-model="gender" value="男" /></label>
  <label><input type="radio" v-model="gender" value="女" /></label>
  <hr>
  <ul>
    <li v-for="user of showUsers">
      {{user.username}}
    </li>
  </ul>
</div>
复制代码
let app = new Vue({
  el: '#app',
  data: {
    gender: '',
    users: [
      {id: 1, username: 'baogege', gender: '男'},
      {id: 2, username: 'mt', gender: '男'},
      {id: 3, username: 'haigege', gender: '男'},
      {id: 4, username: 'zMouse', gender: '男'},
      {id: 5, username: 'reci', gender: '女'},
      {id: 6, username: 'lisi', gender: '女'}
    ]
  },
  computed: {
    showUsers() {
      return this.gender === '' ? [...this.users] : this.users.filter(user=>user.gender===this.gender);
    }
  }
});
复制代码
  • 计算属性类似 gettersetter ,当访问某个计算属性的时候,就会调用 computed 中同名的函数,函数的返回值将作为该计算属性的值
  • 计算属性的值依赖计算函数中依赖的其它响应式数据
  • 计算属性的值可以缓存,如果依赖的其它响应式数据没有发生变化,但多次访问该计算属性,得到结果是最近一次变化产生的值(相对于调用方法得到结果在某些时候性能要好一些)
<div id="app">
  <p>{{now}}</p>
  <button @click="showDate=true">showDate</button>
  <p v-if="showDate">{{now}}</p>
</div>
复制代码
let app = new Vue({
  el: '#app',
  data: {
		showDate: false
  }
  computed: {
    now() {
      return Date.now();
    }
  }
});
复制代码

计算属性的 gettersetter

默认情况下,计算属性函数是一个 getter 函数,如果计算属性只有 get 需求,则可以简写

computed: {
  now() {
    return Date.now();
  }
  // 等于
  now: {
    get() {
      return Date.now();
    }
  }
}
复制代码

但是有的时候,这种派生数据既有 get 需求,也有 set 需求

<div id="app">
  <label><input type="radio" v-model="gender" value="" /> 所有</label>
  <label><input type="radio" v-model="gender" value="男" /></label>
  <label><input type="radio" v-model="gender" value="女" /></label>
  <hr>
  <ul>
    <li v-for="user of showUsers">
      <input type="checkbox" v-model="user.checked" />
      {{user.username}}
    </li>
  </ul>
  <label><input type="checkbox" v-model="checkAll">全选</label>
</div>
复制代码
let app = new Vue({
  el: '#app',
  data: {
    gender: '',
    users: [
      {id: 1, username: 'baogege', gender: '男',checked:false},
      {id: 2, username: 'mt', gender: '男',checked:false},
      {id: 3, username: 'haigege', gender: '男',checked:false},
      {id: 4, username: 'zMouse', gender: '男',checked:false},
      {id: 5, username: 'reci', gender: '女',checked:false},
      {id: 6, username: 'lisi', gender: '女',checked:false}
    ]
  },
  computed: {
    showUsers() {
      return this.gender === '' ? [...this.users] : this.users.filter(user=>user.gender===this.gender);
    },
    checkAll: {
      get() {
        return this.users.every(user=>user.checked);
      },
      set(newValue) {
        this.users = this.users.map(user=>{
          return {
            ...user,
            checked: newValue
          }
        });
      }
    }
  }
});
复制代码

watch

有的时候,我们需要的派生数据是通过异步的方式处理的,这个时候,计算属性就不太好用了(不能处理异步)。

我们可以使用另外一个选项:watch

<div id="app">
  <input type="text" v-model="keyWord">
  <hr>
  <ul>
    <li v-for="user of showUsers">
      {{user.username}}
    </li>
  </ul>
</div>
复制代码
let app = new Vue({
  el: '#app',
  data: {
    keyWord: '',
    users: [
      {id: 1, username: 'baogege', gender: '男',checked:false},
      {id: 2, username: 'mt', gender: '男',checked:false},
      {id: 3, username: 'haigege', gender: '男',checked:false},
      {id: 4, username: 'zMouse', gender: '男',checked:false},
      {id: 5, username: 'reci', gender: '女',checked:false},
      {id: 6, username: 'lisi', gender: '女',checked:false}
    ],
    showUsers: []
  },
  watch: {
    keyWord(newVal, oldVal) {
      // 模拟网络请求
      setTimeout(_=>{
        this.showUsers = this.users.filter(user=>user.username.includes(newVal));
      }, 1000);
    }
  }
});
复制代码

多层监听

对于多层数据的监听,可以使用字符串+点语法

watch: {
  'a.b.c': function() {
    //...
  }
}
复制代码

深度监听

默认情况下,watch 只对当前指定的值进行一层监听,如果需要对对象进行深度监听

watch: {
  a: {
    handler() {
      console.log('a deep');
    },
    deep: true
  }
}
复制代码

过滤器

过滤器是一个使用在 双大括号插值v-bind 中,用于过滤输出内容的函数

假设有一个用于把内容转为大写的过滤器函数 toUpperCase

{{content|toUpperCase}}
复制代码
  • | : 管道符,表示数据从左至右通过管道符进行传递
  • 过滤器可以有多个,执行顺序从左至右,过滤器函数第一个参数的值就是其管道符前一个的结果

注册过滤器

全局过滤器

Vue.filter('过滤器名称', 过滤器函数);
复制代码

局部过滤器

Vue.component('组件', {
  ...,
  filters: {
  	'过滤器名称': 过滤器函数	
	}
})
复制代码

实例

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
    <div id="app">
        {{title|toUpperCase|slice(3)}}
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>
        new Vue({
            el: '#app',
            data: {
                title: 'kaikeba'
            },
            filters: {
                toUpperCase: function(val) {
                    return val.toUpperCase();
                },
                slice(val, n) {
                    return val.slice(n);
                }
            }
        })
    </script>
</body>
</html>
复制代码

脚手架

Vue 提供了一个脚手架工具,帮助我们快速搭建本地项目:vue-cli

cli.vuejs.org/zh/

安装

npm install -g @vue/cli
# OR
yarn global add @vue/cli
复制代码

创建项目

vue-cli 提供了两种使用方式

  • 命令行
  • UI
# 命令行
vue create 项目名称
# UI
vue ui
复制代码

运行命令以后,根据提示进行选择

目录结构

- node_modules/
- public/
- src/
	- assets/
	- components/
	- app.vue
	- main.js
- ...
复制代码

单文件组件

vue 也是基于组件的开发模式,我们知道一个 UI 组件包含

  • 结构
  • 样式
  • 行为

为了能够更加方便的编写组件,vue 提供了一个特殊的组件定义文件:.vue 文件,我们也称为 单文件组件

组成

一个单文件组件的 结构、样式、行为 分别通过三个标签来进行定义和划分

  • <html>
  • <script>
  • <style>
© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享