1_vue基本_插件

html 复制代码
vue 的最重要的 技术点(本章): 
        
                数据的 响应式 -> 即 数据 发生了改变,则 视图 自动跟随改变。



{{ 表达式 }} 的用法


v-bind 的各种用法(包括: class 和 style)

01_JS和三阶段的关系

html 复制代码
<script>
  // https://gitee.com/

  // JS - 在整个前端 中,绝对基础且重要的 知识领域。
  // JS 类比为 内功。
  // 三阶段 - vue/react 更多的算「招式」。
  // JS 基础,一定要 好好掌握:
  // 函数、数组、ES6相关...
</script>

02_vue前置知识

就是框架,飞法法提高开发效率,原生js有时还要考虑浏览器兼容性阻止冒泡写一堆代码

JS => JQuery =>框架时代(React、Vue)

  • JS:原生 JS 直接操作DOM元素
  • JQuery库:(流行事件2005年~2015年):提供的大量的函数简化操作DOM 并且解决DOM操作的浏览器兼容性问题。
  • 框架:(Angular-谷歌出品-现在国内几乎不使用了、React- Facebook 出品、Vue):提供了一整套全新的、高效的前端开发方案:
html 复制代码
 <head>
    <style>
      .box {
        width: 100px;
        height: 100px;
        background-color: pink;
      }
    </style>
  </head>

  <body>
    <div class="box"></div>
  </body>
</html>

<script>
  /*  JS 开发的缺点:DOM操作麻烦,且 需要考虑兼容性

  const box = document.querySelector(".box");

  // 考虑 浏览器的兼容性
  box.addEventListener("click", (e) => {
    // 事件对象 的 兼容性 写法:
    e = e || window.event;

    // 阻止 冒泡 - 阻止事件冒泡也 需要兼容性写法:
    e.stopPropagation(); // 阻止事件冒泡
    e.cancelBubble = true; // 阻止事件冒泡 的 兼容性写法

    console.log("点击了 box...");
  });

*/

  /* 框架 所 提供的 功能 / 框架的优势:
  - ** 数据的响应式(数据驱动视图)
  - 组件化
  - 渐进式
*/
</script>

1.3 前端框架与库的区别?

  • 功能层面

jquery库:操作DOM+网络请求后端数据

框架:提供全方位功能,齐全

如果把库比作肯德基的小套餐的话,框架就类似于KFC的全家桶级别的

  • 代码层面

库:是为了实现某个页面功能,而调用某个函数:

框架:在框架提供的语法和规则下完成页面功能的开发

  • 总结

库:在JS的基础上,引入和使用库的各种函数,

框架:大而沉,有自己完整的语法,相比库的学习成本更高,但开发效率也更高。

框架所提供的重要功能和特性:

  • 如 数据的响应式(数据驱动视图)
  • 组件化
  • 渐进式

03-JS案例:手动执行绘制render

html 复制代码
  <body>
    <div id="app">//我这个地方给你了一个div?
      <!-- 人家规定 :  h1 标签 必须 渲染在 #app 的 div 下面 -->
    </div>
  </body>
</html>

<script>
  // render - 渲染/绘制

  // 后端返回的数据:
  const model = {
    content: "欢迎来到页面", 
  };

  // 思路:写一个 render 函数,通过 执行 render 函数,将 后台返回的数据 绘制在页面中
  function render() {
    document.querySelector("#app").innerHTML = ` //拿到人家写好的div
        <h1>${model.content}</h1> //在div绘制到h1标签
      `;
  }

  // 页面刷新, 要执行一次 render()
  render();
</script>
html 复制代码
<script>

    // 思考2:若 model 的数据发生改变,如何 将改变后的数据,更新至 视图(页面)中
    // ->再执行一次 render 函数,(render 函数的 作用:根据 model 绘制页面)


    const model ={// 注: model 表示数据(data)
        content:'数据被改变...'

</script>


<div id="app'>
    <h1>${model.content}</h1>
</div>


//思考:上述]S操作缺点是什么?
      ->数据被改变了,需要 人工/手动 执行 render 函数。
       - ->不能自动执行,所以 非常麻烦。

// 理想状态,应该怎样?
//-> 数据被改变,自动 执行 render 函数;
     -> 上述的自动化的过程,即数据的响应式(数据驱动视图)

MVVM 架构模式(Vue 实现 数据响应式 的 设计模式)

M,Moder就是数据

V,View就是render()函数当中html代码就是view

VM,(ViewModer)就是vue

html 复制代码
MVVM 其实是指三部分:
M 指的是:Model层是数据模型,即用来存储后端返回的数据;
V 指的是:View层 是视图层(即浏览器页面),展示Model后端数据层的数据,
VM 指的是:ViewModel(视图模型),其同时监测Model层和Vew层,只要一方发生变化,
                              则VM便会自动更改另一方、最终使两方的内容保持一致。
html 复制代码
特性:

1,数据驱动视图
    好处:当Model层发生数据变化时,页面会自动重新渲染。开发人员只维护好数据的变化,页面结构被VM会自动渲染出来。

2,双向数据绑定
    举个栗子:当视图中有<input />若其值发生变化,则 vm 会自动把最新的值取出来,更新到数据。
    好处:开发人员不再需要手动操作DOM元素,来获取表单元索输入的最新值;is数据的变化,会被自动染到页面

Vue.js 是一个提供了 MVVM 风格的双向数据绑定的 Javascript 库,专注于View 层。

它的核心是 MVVM 中的 VM,也就是 ViewModel.

VewModel负责连接 Vew 和 Model,保证视图和数据的一致性,这种轻量级的架构让前端开发更加高效、便捷。

04-vue介绍

简介:

Vue 是一个国产框架,

之前所学的JQuery库、Bootstrap,基本都诞生于国外。像Vue这种优秀的国产框架少之又少

它的作者是国内大神一尤雨溪。

这人学的是艺术设计,并非科班出身,

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

html 复制代码
兼容性:Vue 不支持 IE8,及以下版本,因为 Vue 使用了 IE8 无法模拟的 ECMAScript5 特性。但它支持所有兼容ECMAScript 5 的浏览器。

IE:它是一个用来下载其他浏览器的好工具

市场地位

html 复制代码
Vue.js 是前端的主流框架之一,和Angular.js、React.js 一起,并成为前端三大主流框架!

React 和 Vue 有许多相似之处,它们都有:
    使用 Virtual DOM
    提供了 嗞应式(Reactive) 和 组件化(Composable)的视图组件
    将注意力集中保持在核心库,而将其他功能如路由和全局状态管理交给相关的库。

Vue.js的优点:
    1.体积小,压缩后只有33kb
    2.更高的运行效率,基于虚拟dom原理。
        一种可以预先通过JavaScript进行各种计算,把最终的DOM操作计算出来并优化的技术,由于这个DOM操作属于预处理操作,并没有真实的操作DOM,所以叫做虚拟DOM。

3.双向数据绑定原理。
    让开发者不用再去操作dom对象,把更多精力投入到业务逻辑上

4.生态丰富、学习成本低。
    市面上成熟、稳重的基于vue.js的UI框架、常用组件多。
    基于以上原因,Vue.is对初学者友好,容易上手。国内中小企业用的较多

vue2和vue3

html 复制代码
  Virtual DOM - 虚拟DOM
    -> vue 和 react 都有 虚拟DOM 


  vue 现在有两个 大的版本:
    vue2

    和 

    vue3

  vue3 几乎兼容 vue2;
    我们节奏是 先讲 vue2,再讲 vue3。


Vue2 的编程范式(风格):典型够 面向对象-->new 构造函数()
Vue3 的编程范式(风格):面向对象 + 面向函数

05-vue初体验

Vue引用方式

  • 方式一:直接CDN引入

以选择引入开发环境版本还是生产环境版本

html 复制代码
<!-- 开发环境版本,包含了有帮助的命令行警告-->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<!--生产环境版本,优化了尺寸和速度 -->
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
  • 方式二:下载并引入(==初学者推荐==)
html 复制代码
       开发环境: https://v2.cn.vuejs.org/js/vue.js
       生产环境: https://v2.cn.vuejs.org/js/vue.min.js (min是最小的版本)

Vue 使用

html 复制代码
    <!-- 
      MVVM -  
        Model -> 数据层 -> data 中的属性,是「数据层」
        View  -> 视图层 -> <div id="app"> 内部的 代码,被称为「视图层」
        VM    -> 可以认为 VM就是 vue 的实例对象。
    -->

Vue.js 的html代码写法,是一个允许采用简洁的 模板语法 来声明式地将数据渲染进 DOM 的系统

html 复制代码
<!-- View 层 -->
<!-- 注意: vue 写 html 代码, 有一个特性 - 双花括号 - {{ JS代码 }}-->
<!-- content 即 data 对象属性的 content -->


    <div id="app
        h1>{{content}}</h1> //就是将后端数据渲染到vue提供的页面
    </div>
html 复制代码
<!-- vue层 -->
可以写 vue 代码
console.log(Vue);
el DOM元素  #app 是DOM元素的id
model数据
data 中的属性,会被直接挂载到 vm模型 中,称为 vm模型的一个属性
html 复制代码
  <body>
    <!-- View 层 -->
    <div id="app">//渲染点
      <h1>{{content}}</h1>
    </div>
  </body>
</html>

<!-- vue层 -->
<script src="./vue.js"></script>
<script>
  const vm = new Vue({//创建vm
    el: "#app", //挂载点
    data: {// model数据挂载
      content: "欢迎来到页面",
    },
  });
</script>


 el: "#app", // 将 vue 的代码 生效的「挂载点」

0607-vue模板语法+常见指令

  • 开发者工具

在使用 Vue 时,我们推荐在你的浏览器上安装 Vue Devtools

它允许你在一个更友好的界面中审査和调试 Vue 应用

安装chrome插件的方式:

https://juejin.cn/post/6966106927990308872#Volar VSCode插件

模板语法

html 复制代码
     Vue.js 使用了基于 HTML的模板语法 ->"Mustache"语法,胡须-被俗称为「大胡子」

    模板语法的作用: new Vue 下很多 JS 数据可以直接在 模板语法中被使用->如 data 中的属性,且 模板语法中的数据具有响应性。
    
    数据绑定最常见的形式就是使用"Mustache"语法(双大括号) 的文本插值:
html 复制代码
<div id="app"
    {{ message }}
</div>
html 复制代码
<div id="app"
    {{content}} - {{message}} //挂载到
</div>




  const vm = new Vue({//VM
    el: "#app", // VM挂载
    data: {//数据
      content: "欢迎来到页面",
      message: "Hello Vue!",
    },
  });

{ } 可以放什么?

  • data 中的 任意数据类型
html 复制代码
- 数组
- 对象
  • 表达式

什么是 表达式?

javascript 复制代码
["a", "b", "c"].map(d => d + '1')
html 复制代码
  <body>
    <div id="app">
      <h1>{{content}} - {{message}}</h1>
      <p>数组:{{arr}}</p>
      <p>对象:{{obj}}</p>
      <p>表达式 - 数组的map方法:{{arr.map(d => d + '1')}}</p>
      <p>数字相加的表达式 {{11 + 22}}</p>
    </div>
  </body>
</html>


<script src="./vue.js"></script>
<script>
  const vm = new Vue({
    el: "#app", 
    data: {
      content: "欢迎来到页面",
      message: "Hello Vue!",
      arr: ["a", "b", "c"],
      obj: {
        name: "姓名",
        age: 33,
      },
    },
  });
</script>

指令语法

html 复制代码
// 概念约定
标签的属性:属性名、  标签的属性值 分别的英文 和 简写

<div title="xxx">


    title 被称为:「属性名」
    英文 和 简写: attributr
    attrName
    'xxx' 被称为:「属性值」
     英文 和 简写: attrValue

</div>

vue中定义好的一些以"v-"开头+具体的名称的 属性,这些属性都有特定的功能。

  • 说明

指令加在标签,在Vue中凡是以 v-开头的通通都叫做指令,加上就会有特定的功能。

  • 常见用法
html 复制代码
<div v-xx></div>
<div v-xx='表达式 或 data中的属性'></div>
<div v-xx:yy='表达式'> </div>
  • 注意

指令分:自定义指令和内置指令(Vue自带)

内置指令: Vue自带 的,能直接使用的 指令

自定义指令: 就是用户自己定义的。扩展功能

下述列举 常用的 内置指令:

文本绑定
v-html、v-text
html 复制代码
v-html、v-text

双大括号会将数据解释为普通文本,而非HTML代码。为了输出真正的 HTML,需要用到v-html

html 复制代码
<p>Using mustaches: f{ rawHtml }}</p>
<p>Using v-html directive: <span v-html="rawHtml"></span></p>
<!-- v-text -->
<p>Using v-text directive: <span v-text="rawHtml"></span></p>
html 复制代码
<!-- 注: {{}} 需要被 vue 解析,所以 刷新的 瞬间 `{{}}` 会闪现,因为 vue 还没将 {{}} 解析完成 -->
<!-- 注:v-cloak 作用:解决 刷新时的 闪现问题 -->
<!-- v-pre 的作用:组织 vue 解析 大胡子中的 表达式 -->
<!-- v-html 其作用 等价于 `innerHTML` -->
<!-- v-text 其作用 等价于 `innerText` -->
v-cloak

cloak:[kleuk]笼罩,覆盖;隐藏,掩饰的意思

用于隐藏尚未完成编译的 DOM 模板。{}

当使用直接在 DOM 中书写的模板时,可能会出现一种叫做"未编译模板闪现"的情况:用户可能先看到的是还没编译完成的双大括号标签,直到挂载的组件将它们替换为实际渲染的内容。

v-cloak 会保留在所绑定的元素上,直到相关组件实例被挂载后才移除。配合像[v-cloak]{display:none } 这样的 CSS 规则,它可以在组件编译完毕前隐藏原始模板。

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


<!-- 直到编译完成前,`<div>' 将不可见-->
<div v-cloak>
    {{ message }}
</div>
v-pre

元素内具有 v-pre,所有 Vue 模板语法按原样渲染(不解析)。

html 复制代码
<div v-pre{{ rawHTML }}</div>
html 复制代码
    <style>
      [v-cloak] {
        display: none;
      }
    </style>
  </head>

  <body>
    <div id="app">
      <h1 v-cloak>{{content}} - {{message}}</h1>
      <h1 v-pre>{{content}} - {{message}}</h1>
      <div v-html="rawHtml"></div>
      <div v-text="rawHtml"></div>
    </div>
  </body>

</html>
<script src="./vue.js"></script>
<script>
  const vm = new Vue({
    el: "#app",
    data: {
      content: "后台登录页面",
      message: "Hello Vue!",
      rawHtml: `<p>我是 字符串的 p 文本</p>`,
    },
  });
</script>

08+09-class+style属性绑定

写法 适用情况 示例
字符串 绑定单个 class :class="'active'"
对象 绑定多个 class(动态) :class="{ active: isActive, 'text-danger': hasError }"
数组 绑定多个 class(混合) :class="['active', 'text-danger']"
对象(style) 绑定多个样式(动态) :style="{ color: textColor, fontSize: fontSize + 'px' }"
数组(style) 组合多个样式对象 :style="[baseStyle, additionalStyle]"

为什么绑定?

绑定(v-bind)的作用 就是让 HTML 里的 classstyle 变得 动态可变,而不是固定不变的

这个绑定其实很简单,就是根据原生的html css js各种标签写法。在前面加个冒号: 和语法填充就可以了。

  1. 如果不用 v-bind,只能手写固定的 classstyle
html 复制代码
html

<div class="active" style="color: red;">Hello Vue</div>

这种方式是 固定的,无法根据数据的变化自动修改。

  1. v-bind,可以根据数据自动修改 classstyle
html 复制代码
vue

<div :class="{ active: isActive }" :style="{ color: textColor }">Hello Vue</div>
javascript 复制代码
js

data() {
  return {
    isActive: false,
    textColor: 'blue'
  };
}

如果 isActivefalse,那么 class="active" 不会被添加 ,颜色也会变成 blue

如果 isActive = true,Vue 就会自动给 div 加上 class="active",让样式生效。

实际应用场景

  • 动态高亮选中项
html 复制代码
vue

<li v-for="item in items" :key="item.id" :class="{ active: selectedItem === item }">
  {{ item.name }}
</li>

selectedItem 变化时,对应的 li 会自动加上 active 这个 class,比如点击时变色。

  • 切换暗黑模式
html 复制代码
vue

<div :class="{ darkMode: isDark }">切换模式</div>
<button @click="isDark = !isDark">切换</button>

isDark = true 时,class="darkMode" 会被加上,页面样式会变暗。

  • 根据状态改变颜色
html 复制代码
vue

<div :style="{ color: isError ? 'red' : 'green' }">状态信息</div>

总结

如果 classstyle 是固定的 ,你可以直接写在 HTML 里,但如果需要根据数据变化 ,就要用 v-bind 来绑定,让 Vue 自动控制样式,减少手写 CSS 的麻烦。

这样写的代码更灵活,维护起来也更简单!💡

属性绑定- v-bind

思考: 若 给标签内的 属性值 也能像`{{ 表达式 }}`一样,具有响应性,岂不美哉..

->而 v-bind:attrName-"表达式"就是 为了 实现 标签属性的 响应性的

  • v-bind(简写为 :)可以用于绑定 classstyle,并支持对象数组计算属性等不同写法
  • a标签举例:<a href='xxxxxxx'>百度一下</a>
html 复制代码
<div id="app">
    <a v-bind:href="link">{{title}}</a>
</div>

<script>
    new Vue({
        el:'#app',
        data: {
            link: "http://mww.baidu.com',
            title:'百度一下',
        }
})
</script>
html 复制代码
  </head>
  <body>
    <div id="app">
      <!-- 注: 使用 `v-bind` 指定,可以使得 attrValue 也能使用「表达式」 -->
      <a v-bind:href="link">{{title}}</a>
      <h1 :title="title">{{title}}</h1>
    </div>
  </body>
</html>

<script src="./vue.js"></script>
<script>
  const vm = new Vue({
    el: "#app", // 将 vue 的代码 生效的「挂载点」
    data: {
      link: "http://www.baidu.com",
      title: "百度一下",
    },
  });
</script>
动态绑定class属性

操作元素的 class 列表和联样式是数据绑定的一个常见需求。

但字符串拼接 class 和 style,操作麻烦且容易出错

因此,在将v-bind 用于 class 和 style 时,Vue.js 做了专门的增强。

表达式结果的类型除了字符串之外,还可以是对象或数组

Vue 允许动态绑定 class,可以使用字符串、对象或数组的形式。

(1)字符串写法
html 复制代码
<div :class="'active'">Hello Vue</div>

相当于:

html 复制代码
<div class="active">Hello Vue</div>
(2)对象写法
html 复制代码
<div :class="{ active: isActive, 'text-danger': hasError }">Hello Vue</div>

如果 isActivetrue,则 class="active"; 如果 hasErrortrue,则 class="text-danger"

(3)数组写法
html 复制代码
<div :class="['active', 'text-danger']">Hello Vue</div>

或者:

html 复制代码
<div :class="['active', { 'text-danger': hasError }]">Hello Vue</div>

hasErrortrue 时,会额外添加 text-danger

html 复制代码
<style>
.box {
    width: 100px;
    height: 100px;
    background-color: pink;
}

.bold {
    font-weight: 900;
}

</style>


<div id="app">

    <!-- 注意:在vue 当中 静态class和动态绑定class可以同时存在 -->
    <div class="" v-bind:class="{box:flag}">对象方式</div>
    <!-- 简写: -->
    <div class="bold" :class="{box:flag}">对象方式</div>

    <!--第二种:数组方式 active:是个变量,它的值是类名-->
    <div v-bind:class="[active, {bold: flag}]">数组方式</div>

</div>
注意:

==>在vue 当中 静态class和 动态绑定clas 可以同时存在==

html 复制代码
注意:在vue 当中 静态class和动态绑定class可以同时存在-->
<div class="title" v-bind:class="{box:flag,size:3>2}">对象方式</div>
动态绑定style属性
  • 对象语法

v-bind:style 的对象语法十分直观--看着非常像 CSS,但其实是一个JavaScript对象。

CSS property 名可以

用驼峰式(cameICase)或短横线分隔(kebab-case,记得用引号括起来) 来命名:

v-bind:style 允许动态绑定内联样式,可以使用对象或数组的形式。

(1)对象写法
html 复制代码
vue

<div :style="{ color: textColor, fontSize: fontSize + 'px' }">Hello Vue</div>
javascript 复制代码
js

data() {
  return {
    textColor: 'red',
    fontSize: 20
  }
}

会被解析为:

html 复制代码
html

<div style="color: red; font-size: 20px;">Hello Vue</div>
(2)数组写法
html 复制代码
vue

<div :style="[baseStyle, additionalStyle]">Hello Vue</div>
javascript 复制代码
js

data() {
  return {
    baseStyle: { color: 'blue', fontSize: '18px' },
    additionalStyle: { backgroundColor: 'yellow' }
  }
}

最终渲染:

html 复制代码
html

<div style="color: blue; font-size: 18px; background-color: yellow;">Hello Vue</div>
(3)自动加前缀

Vue 会自动为某些 CSS 属性添加浏览器前缀:

html 复制代码
vue

<div :style="{ transform: 'rotate(30deg)' }"></div>

Vue 会自动添加 -webkit-transform-ms-transform 等前缀以兼容不同浏览器。

结合 computed 计算属性

如果 classstyle 需要根据更复杂的逻辑计算,可以使用 computed

html 复制代码
vue

<template>
  <div :class="classObject" :style="styleObject">Hello Vue</div>
</template>

<script>
export default {
  data() {
    return {
      isActive: true,
      hasError: false,
      textColor: 'green',
      fontSize: '16px'
    };
  },
  computed: {
    classObject() {
      return {
        active: this.isActive,
        'text-danger': this.hasError
      };
    },
    styleObject() {
      return {
        color: this.textColor,
        fontSize: this.fontSize
      };
    }
  }
};
</script>

html 复制代码
<div v-bind:style_"{ color: activeColor, fontSize: fontSize + 'px' }"></div>
html 复制代码
data:{
    activeColor: 'red'
    fontSize: 30
}
  • 数组语法

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

html 复制代码
<div v-bind:style="[baseStyles, overridingstyles]"></div>
html 复制代码
  <body>
    <div id="app">
      <div v-bind:style="{ color: 'red', fontSize }">对象写法</div>
      <div :style="[baseStyles, overridingStyles]">数组写法</div>
    </div>
  </body>
</html>

<script src="./vue.js"></script>
<script>
  const vm = new Vue({
    el: "#app", // 将 vue 的代码 生效的「挂载点」
    data: {
      fontSize: "100px",
      baseStyles: {
        color: "blue",
        fontSize:300
      },
      overridingStyles: {
        background: "black",
        color: "pink", //覆盖
      },
    },
  });
</script>
相关推荐
冬天vs不冷20 分钟前
EasyExcel导出自动回显中文,读取自动转换码值(基于全局转换器与自定义注解)
java·excel
阿里云云原生23 分钟前
RAG 调优指南:Spring AI Alibaba 模块化 RAG 原理与使用
java·人工智能·spring
天上掉下来个程小白27 分钟前
Redis-12.在Java中操作Redis-Spring Data Redis使用方式-操作字符串类型的数据
java·redis·spring·springboot·苍穹外卖
ん贤1 小时前
2023第十四届蓝桥杯大赛软件赛省赛C/C++ 大学 B 组(真题&题解)(C++/Java题解)
java·c语言·数据结构·c++·算法·蓝桥杯
在京奋斗者3 小时前
spring boot自动装配原理
java·spring boot·spring
明天不下雨(牛客同名)6 小时前
为什么 ThreadLocalMap 的 key 是弱引用 value是强引用
java·jvm·算法
多多*6 小时前
Java设计模式 简单工厂模式 工厂方法模式 抽象工厂模式 模版工厂模式 模式对比
java·linux·运维·服务器·stm32·单片机·嵌入式硬件
qq. 28040339847 小时前
CSS层叠顺序
前端·css
喝拿铁写前端7 小时前
SmartField AI:让每个字段都找到归属!
前端·算法
猫猫不是喵喵.7 小时前
vue 路由
前端·javascript·vue.js