VUE

vue 2.0

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

Vue 是一套用于构建用户界面的渐进式框架,Vue 的核心库只关注视图层。使用 Vue 可以快速高效的搭建出单页面应用程序。

MVC

  • M:致据层,处理数据的增删改查
  • V:视图层,前端页面
  • C:业务逻辑层

MVVM 双向数据绑定

MVVM是前端分层开发理念,总共分为3层,包括M层、V层、VM层,其中 VM层是核心,也是M层和V层的调度者。

  • M层是每个页面中存储的数据,也称作数据层Model;
  • V层是每个页面中的 HTML代码,也叫作视图层View;
    一般是把M层中的数据渲染到V层。M层中的数据并不能直接渲染到V层,需要通过VM层调度,同样地,在V层中修改了数据,也不能直接同步到M层,还是需要VM层来调度,所以VM层是M层和V层的调度者是核心。
    mvvm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<body>
<div id="app">
<!-- V层 -->
<h1>{{msg}}</h1>
<h1>{{obj.name}}</h1>
<h1>{{f1()}}</h1>
<h1>{{ num > 10 ? 'ok':'no'}}</h1>
</div>

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
var vm = new Vue({
el: '#app',
data: {
// M层
msg: 'Hello Vue1',
obj:{
name:"小明"
},
f1:function(){
return 10
},
num:5,
}
})
</script>
</body>

以数据驱动界面渲染

npm安装

  • npm install vue --save

该命令必须在项目的根目录下执行。

  • 修改 package.json 文件添加1"vue": "^2.6.8" 执行命令 npm install

插值

{{value}} value需要定义在datavalue可以是任意类型

指令

  • v-for 列表渲染
  • v-if v-else-if v-else 条件渲染
  • v-show 条件渲染

v-if显示或隐藏时会动态的添加或删除DOM元素,而v-show显示或隐藏只是修改css属性display:none实现的。
如果频繁那么请使用v-show,反之使用v-if

  • v-html 插入数据到指令所在的标签元素(插入的值如果是标签结构的字符串,那么会被解析为标签)
  • v-text 插入数据到指令所在的标签元素(插入的值如果是标签结构的字符串,那么不会被解析为标签)

  • v-on 给标签元素添加事件

    • @ 缩写
    • 支持所有的原生JS事件,事件类型前的on不可以添加
    • 支持动态事件 v-on:[clicktype]='btnClick' 方括号中变量名称必须使用小写。
  • v-bind 给标签元素的属性绑定值

    • : 缩写
    • 绑定class``style属性时值支持json格式和数组。
  • v-model 表单控件<input> <select> <textarea> 设置或获取数据

    • .number - 输入字符串转为有效的数字
    • .trim - 输入首尾空格过滤
  • v-pre 指令所在的标签元素及子元素中vue语法将不解析。

  • v-cloak 配合css样式使用,在vue实例所绑定的模板没有渲染完成前该标签元素是隐藏,只有当渲染完成后才显示。

    1
    2
    3
    [v-cloak] {
    display: none;
    }

计算属性

本质是一个函数, 在vue实例中添加到 computed ,计算属性没有参数,有返回值,返回的数据中会响应式依赖(data中数据),
只有当响应式依赖发生变化时计算属性才会重新调用否则返回上次的计算结果(结果会缓存)

侦听属性

本质也是一个函数,在vue实例中添加到watch,有两个参数,第一个参数是 数据变化的新值,第二个参数是数据化之前的值。只要数据变化就会触发侦听属性

过滤器

过滤器可被用于一些常见的文本格式化。过滤器可以用在两个地方:双花括号插值和 v-bind 表达式 (后者从 2.1.0+ 开始支持)。过滤器应该被添加在 JavaScript 表达式的尾部由“管道”符号指示

  • filters 过滤中会接收一个参数(使用过滤器,管道符号左侧的值会传入该参数中)返回值为处理好的数据

组件

组件是可复用的 Vue 实例。

组件有两种注册方法

  1. 全局注册:全局注册的组件,在所有位置(vue)都可以使用。注册必须放在根实例之前
    • Vue.component
  2. 局部注册:在组件内注册,只有在当前注册的组件中才可以使用该组件。

DOM 模板:视图写在html标签元素中,使用el属性与vue实例进行关联 ,多用在根组件中。
字符串模板 :写在 template 属性值后面的字符串中,多用在子组件

组件命名:

组件名可以使用驼峰或者中 - (横杠),驼峰命名只有在字符串模板中才能被识别。命名使用横框可以在DOM或字符串模板中都可以使用。

  • template 定义组件视图。只能有一个根节点。语法必须使用严格模式(必须按照标签语法写)。

为了书写方便推荐使用模板字符串

  • data 组件中的data是一个返回对象的函数。数据定义在返回的对象中。

根实例中可以用的指令和方法在组件中同样可以使用。

动态组件

使用 <component> 配合 is 特殊属性使用

动态组件的缓存

使用 <keep-alive>,只有当第一次加载组件时会创建该组件的实例,后续动态组件再次激活时交使用缓存的组件。

prop传递数据

通过 prop 父组件可以向子组件传递数据。

在dom 模板中使用 prop属性时不允许 驼峰命名。字符串模板中是可以的。

  • 单向数据流 父级组件可以向子级组件传递,但子级组件不能通过prop传递数据给父级。

Prop 验证

插槽

父组件可以向子组件传递数据

  • 具名插槽:带有名称的插槽
    给组件传递数据时使用 <template v-slot:tp2> v-slot 指令后跟的就是插槽的名称。在组件内部使用时<slot name='tp1'></slot> 内置组件必须在name中标明所使用的插槽名称。

prop 通过属性方式向子组件传递数据。插槽是通过标签值的方式向子组件传递数据。

自定义事件

利用自定义事件可以让子组件向父组件传递数据。

  • 触发自定义事件使用 this.$emit()(触发当前实例上的事件。附加参数都会传给监听器回调)

脚手架 CLI

2.x 3.x

  1. 安装 nodejs
    • node --version 查看版本
  2. 安装node时会自动安装npm
    • npm --version
    • 淘宝镜像源: npm config set registry http://registry.npm.taobao.org
  • 2.x CLI

    • npm i vue-cli -g
    • vue -V 查看版本
      vue-版本
  • 2.9.6 CLI 创建工程(网端下载工程模板)

    • vue init webpack xx-xx
    • npm run devnpm start 启动项目(必须在项目的根目录下执行该命令)
  • CLI 2.X工程打包

    • npm run build

    打包完成后 在项目根目录下会生成一个dist目录,该目录中内容就是要部署到服务器的代码。
    如果部署到服务器时并不是服务器的根目录,需要修改配置 config\index.js中的 build选项中的 assetsPublicPath: './'

  • CLI2.x 工程结构:

    • package.json
      • dependencies 项目依赖
      • devDependencies 开发依赖
    • index.html html主入口文件
    • static 放静态资源
    • node_modules 工程中依赖的安装目录
    • config webpack 配置目录
    • build webpack 打包的相关配置
    • src 工作目录
      • main.js js主入口文件
      • App.vue 主入口组件
      • ‘components’ 编写的组件都应该放在这个目录中
      • assets 放资源文件
  • 3.x CLI

    • npm install @vue/cli -g

    CLI 2.X与3.x只能安装一个。卸载 2.x npm uninstall vue-cli -g ,卸载3.X npm uninstall @vue/cli -g

    • vue -V 查看版本 3.11.0
    • vue ui 打开图形工具
  • CLI3.X 工程结构

    • package.json
      • dependencies 项目依赖
      • devDependencies 开发依赖
    • node_modules 工程中依赖的安装目录
    • public 静态资源,该目录内容不会编译,打包是只是复制。
      • index.html html主入口文件
      • src 工作目录
        • main.js js主入口文件
        • App.vue 主入口组件
        • ‘components’ 编写的组件都应该放在这个目录中
        • assets 放资源文件

单文件组件

单方件组件就是一个文件就是一个组件。 文件后缀 .vue
.vue中 html 、css 、javascript

  • <template> 组件视图(只能有一个根节点)
  • <script> 组件的数据及逻辑(javascript)必须export default将组件导入给调用者,export default返回组件实例
  • <style> 组件视图中所要用到的样式
    • <style> 添加scoped属性,这样,组件中的样式只能在当前组件中使用

组件生命周期

  • 组件生命周期
  1. beforeCreate 在实例初始化之后,数据观测 (data observer) 和 event/watcher 事件配置之前被调用
  2. created 在实例创建完成后被立即调用。然而,挂载阶段还没开始,$el 属性目前不可见。
    • 可以对data中的数据进行填充操作。
  3. beforeMount 在挂载开始之前被调用.
  4. mounted 挂载结束之后会被调用
  5. beforeUpdate 数据更新时调用,发生在虚拟 DOM 打补丁之前。
  6. updated 更新完成后调用
  7. beforeDestroy 实例销毁之前调用。
    • 保存数据操作。
  8. destroyed Vue 实例销毁后调用。

父子组件嵌套时生命周期的调用。

  1. 创建时:
    父组件 beforeCreate
    父组件 created
    父组件 beforeMount
    子组件 beforeCreate
    子组件 created
    子组件 beforeMount
    子组件 mounted
    父组件 mounted

  2. 更新时: 父组件更新,子组件不新
    父组件 beforeUpdate
    父组件 updated

  3. 父组件更新,子组件更新
    父组件 beforeUpdate
    子组件 beforeUpdate
    子组件 updated
    父组件 updated

  4. 组件卸载
    父组件 beforeDestroy
    子组件 beforeDestroy
    子组件 destroyed
    父组件 destroyed

$destroy() 强制卸载。$forceUpdate() 强制更新。不建议使用

混入

局部混入: 组件中使用 mixin 混入数据。

混入 (mixin) 提供了一种非常灵活的方式,来分发 Vue 组件中的可复用功能。组件中所有选项都可以混入。

  1. 数据混入时(data)数据对象在内部会进行递归合并,数据有重复时以组件中数据优先
  2. 生命周期钩子函数将合并为一个数组,都将被调用。混入对象的生命周期钩子函数将优先调用
  3. 值为对象的选项,例如 methodscomponentsdirectives对象中成员有重复时组件中优先

全局混入: Vue.mixin(),必须放在 new Vue() 根实例之前。

一旦使用全局混入,它将影响每一个之后创建的 Vue 实例。

自定义指令

  1. 全局注册指令
    • Vue.directive()
  2. 组件内局部注册指令
    • 组件内使用 directives 注册组件。

DOM 操作

使用 ref在标签上或组件中绑定一个字符串,那么在父级组件中使用$refs就可以获取到这个DOM

如果要在生命周期函数中使用请在 mounted 中使用。

路由

Vue RouterVue.js 官方的路由管理器。

  • 单页面应用程序
  • 安装路由 npm install vue-router --save

路由

  1. 在组件中设置路由出口 <router-view>

  2. 设置路由规则:routes

    1
    2
    3
    const routes=[
    {path:'/home',component:Home}
    ]
  3. 根据路由规则实例化路由对象: new VueRouter({routes})

  4. 将路由对象注入vue实例 router

  • <router-link> 渲染成为A标签

    • exact-active-class精确匹配(匹配 /和后面的字符) 路由规则匹配成功会给当前的 <router-link> 渲染的A 标签添加一个类名,
    • active-class

    以上两个属性是如果设置在<router-link>时需要每个都设置,可以在实例化路由对象中统一设置:linkActiveClass linkExactActiveClass

    • exact 设置当前规则匹配所对应的类名,是否是精确模式。

路由规则只要匹配成功后面的规则将不再执行。

路由重定向

1
{path:'/*', redirect:'/'}

动态路由

一个“路径参数”使用冒号 : 标记。例如:{ path: '/user/:id', component: User } ,像/user/foo/user/bar都会匹配到该路由规则,路径参数 在组件中可以通过 $route.params获取。

嵌套路由

在路由规则所对应的组件中再放入一个路由出口,也就是路由包含了子路由。

1
2
3
4
5
6
7
8
9
10
11
// 嵌套路由
{
path: '/about', component: About,
//子路由配置
children:[
{ path:'ft',component: Fruits},
{ path:'vt',component: Vegetables},
// 重定向
{ path:'/', redirect:'ft' }
]
},

编程式导航

除了使用 <router-link> 创建 a 标签来定义导航链接,我们还可以借助 router 的实例方法,通过编写代码来实现。

使用js的方式控制路由间的跳转

  • this.$router.push() 跳转到指定路径或名称的路由规则
  • this.$router.replace()push不同 replace并不会将跳转页面加入到页面栈中。
  • this.$router.back() 页面栈后退一步(页面栈中如果有)
  • this.$router.forward() 页面栈前进一步(页面栈中如果有)
  • this.$router.go(n) 页面栈前进或后退(页面栈中如果有) 参数n是一个数字可以是正数也可以是负数,为正数前进为负数时后退。

命名路由

命名式路由就是在路由规则中指定name属性,在使用编程式导航时可以通过这个name属性进行页面的跳转。

命名视图

命名视图就是在一个组件中有多个路由出口,并且每个<router-view> 都拥有name属性。在设置路由规则时需要使用 components属性为每一路由出口指定所要渲染的组件。

滚动行为

在路由实例中设置scrollBehavior 的返回值可以设置路由页面在跳转后的默认位置。

路由懒加载

把不同路由对应的组件分割成不同的代码块,然后当路由被访问的时候才加载对应组件,这样就更加高效了。
结合 Vue 的异步组件和 Webpack 的代码分割功能,轻松实现路由组件的懒加载

1
2
component:() => import('./views/About.vue'), 
component: resolve => require(['./views/About.vue'], resolve)

路由懒加载中importrequire都可以实现路由的懒加载。推荐使用 import

导航守卫

完整的导航解析流程

  1. 导航被触发。
  2. 在失活的组件里调用离开守卫。
  3. 调用全局的 beforeEach 守卫。
  4. 在重用的组件里调用 beforeRouteUpdate 守卫 (2.2+)。
  5. 在路由配置里调用 beforeEnter
  6. 解析异步路由组件。
  7. 在被激活的组件里调用 beforeRouteEnter
  8. 调用全局的 beforeResolve 守卫 (2.5+)。
  9. 导航被确认。
  10. 调用全局的 afterEach 钩子。
  11. 触发 DOM 更新。
  12. 用创建好的实例调用 beforeRouteEnter 守卫中传给 next 的回调函数。

Vuex

Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。

用户管理vue中的数据的。用于数据共享。

State

用于存储数据,且是vuex唯一存储数据的对象

  • 要访问 state 中数据使用 $store.state.xxxx

Mutation

用于修改state中数据且只能在 Mutation修改

  • 触发Mutation中方法使用$store.commit(name,args)
    • 第一个参数是要触发的方法名称,字符串类型。必填
    • 第二个参数是传递给触发方法的参数。任意类型,选填。建议使用对象(对象中可以封装多个数据)。

Action

用于匹量提交 Mutation

  • 触发 action中方法使用 $store.dispatch(name,args)
    • 第一个参数是要触发的方法名称,字符串类型。必填
    • 第二个参数是传递给触发方法的参数。任意类型,选填。建议使用对象(对象中可以封装多个数据)。

Getter

就像计算属性一样,getter 的返回值会根据它的依赖被缓存起来,且只有当它的依赖值发生了改变才会被重新计算。

  • 使用 getter 中数据 $store.getters.xxxx

Module

Moudle允许 开发工作中将每个组件都切割为独立的模块,每个模板中都有 state mutation getter action 对象,为方便管理每个模块将作为独立的文件存储。将该文件以模板的形式注入到vuex实例对象中。

  • 为了开发便利 在使用模板时需要开启 namespaced 命名空间。

开启命名空间后访问vuex中方法时需要加模块前缀。

1
2
3
4
5
6
// 使用getters
$store.getters['Home/getText']
// 触发mutations
this.$store.commit('Home/setText',{text:this.homeText})
// 触发action
this.$store.dispatch('Home/setTextAction',{text:this.homeText})

国际化 vue-i18n

i18n(其来源是英文单词 internationalization的首末字符i和n,18为中间的字符数)是“国际化”的简称。
在信息技术领域,国际化与本地化(英文:internationalization and localization)是指修改软件使之能适应目标市场的语言、地区差异以及技术需要。

  • Vue I18nVue.js 的国际化插件
  • 安装 npm i vue-i18n --save
  • i18n文档

使用 vue-i18n

  1. 创建语言配置文件

    • src/i18n/en.js
    1
    2
    3
    4
    5
    export default {
    hello: 'hello',
    home: 'home',
    about: 'about'
    }
    • src/i18n/zh.js
    1
    2
    3
    4
    5
    export default {
    hello: '你好',
    home: '主页',
    about: '关于'
    }
    • src/i18n/ja.js
    1
    2
    3
    4
    5
    export default {
    hello: 'こんにちは',
    home: 'ホームページ',
    about: 'について'
    }
  2. src目录下创建 src/i18n/index.js 文件。

    • index.js 文件中创建 i18n实例。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    import Vue from 'vue'
    //引入i18n插件
    import VueI18n from 'vue-i18n'
    import en from './en'
    import ja from './ja'
    import zh from './zh'
    //安装插件
    Vue.use(VueI18n)
    //导出 i18n 实例。
    export default new VueI18n({
    locale:'zh', //设置当前默认语言
    messages:{ // 配置各语言信息
    en, ja, zh
    }
    })

  3. main.js 中引入i18n配置并注入到根实例。

    1
    2
    3
    // 导入i18n配置
    import i18n from './i18n'
    new Vue({i18n})
  4. 在组件中使用

    1
    <h2>{{$t("hello")}}</h2>

VueI18n 配置

  • locale 设置默认语言
  • messages 本地化语言
  • fallbackLocale 语言匹配不到时,使用指定的语言。
  • silentFallbackWarn:true 清除 fallbackLocale 时警告
  • 使用国际化

    • $t()
    • v-t=''
  • 具名格式:

1
2
3
4
//本地化语言文件中使用 `{变量名}`
main:{
hello:'{msg} 世界!'
}
1
2
<!-- $t 传入第二个参数,对象类型。该参数将传递给本地化语言文件中的变量 -->
<h2>{{$t('main.hello',{msg:'hello'})}}</h2>
  • 列表格式:
1
2
3
4
//{下标}
main:{
hello:'{0} 世界!'
}
1
2
<!-- $t 传入第二个参数类型为数组 -->
<h2>{{$t('main.hello',['hello'])}}</h2>
  • html 格式化
1
2
3
4
main:{
// 在本地化文件中加入标签
tag:'你好 <s>世界</s>'
}
1
2
<!--要想正确解析为标签,那么必须在v-html指令中绑定的$t() -->
<h3 v-html="$t('main.tag')"></h3>
  • 单文件组件

CLI 2.x

  • 配置: 在 webpack.base.conf.js 找到 vue-loader 配置项添加以下内容。
  • 以下配置为 vue-loader v14配置项
1
2
3
4
5
6
7
8
9
10
11
12
{
test: /\.vue$/,
loader: 'vue-loader',
// options: vueLoaderConfig,
options: {
vueLoaderConfig,
loaders: {
// 你需要指定 `i18n` 的值为 `vue-i18n-loader`
i18n: '@kazupon/vue-i18n-loader'
}
}
}

CLI 3.X

  • 安装 i18n-loader npm i --save-dev @kazupon/vue-i18n-loader

  • 配置 i18n-loader 在根目录打开文件 vue.config.js(如果没有可以新新建该文件)

  • 注意 查看 vue-loader 版本 在文件 package-lock.json vue-loader v15及以上版本

1
2
3
4
5
6
7
8
9
10
11
module.exports = {
chainWebpack: config => {
config.module
.rule("i18n")
.resourceQuery(/blockType=i18n/)
.type('javascript/auto')
.use("i18n")
.loader("@kazupon/vue-i18n-loader")
.end();
}
}
  • 在单文件组件中添加 <i18n><template>保持同级及可。

  • <i18n>中写本地文语言配置,严格的JSON格式

vue3.0

vue3.0官方文档

使用Vue3.0

  • cdn <script src="https://unpkg.com/vue@next"></script>

根实例

  • 创建根实例使用 Vue.createApp

    1
    const app = Vue.createApp({ /* options */ })
  1. 第一个vue3.0 实例

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    <div id="app">
    {{msg}}
    </div>

    <script src="https://unpkg.com/vue@next"></script>
    <script>
    // 创建根组件
    const app = Vue.createApp({
    data() {
    return {
    msg: 'hello msg!'
    }
    },
    })
    // 为根组件指定渲染点
    app.mount('#app')

    </script>
    1. 在3.0中不再使用 new Vue() 创建根实例
    2. 所有组件中的 data 都是返回对象的函数,包括根组件。

语法

插值

1
<span>Message: {{ msg }}</span>

组件

  1. 组件名称 ,DOM模板中不支持驼峰命名,多个单词可以使用 - 连字符。字符串模板支持驼峰命名。
  2. template 定义模板时不再是只有一个根标签。可以有多个标签元素。

组件定义

1
2
3
4
5
6
const Home = {
template: `<div>
<h2>home</h2>
</div>
<div>123</div>`,
}

全局注册组件

  1. 使用 app.component()注册组件。
  2. app.component() 必须 在 app.mount('#app') 之前调用。
1
2
3
4
const app = Vue.createApp({})
//全局注册组件
app.component('home' , Home)
app.mount('#app')

局部注册组件

  1. 在组件内部使得 components
1
2
3
4
5
6
const app = Vue.createApp({
//局部注册组件
components:{
'top-bar':TopBar
}
})

生命周期

  1. destroyed 生命周期的选项已更名为 unmounted
  2. beforeDestroy 生命周期的选项已更名为 beforeUnmount
  3. $destroy实例方法已经删除。用户不应再手动管理各个Vue组件的生命周期

过滤器Filters

Filters已经删除不再支持

插件

  1. 实例方法不再使用 Vue.prototype.$myMethod, 改为 app.config.globalProperties.$myMethod
1
2
3
4
5
6
7
export default {
install: (app, options) => {
app.config.globalProperties.$myMethod = key => {

}
}
}

使用插件

1
2
3
4
5
6
import i18nPlugin from './plugins/i18n'

const app = createApp(Root)
//使用插件
app.use(i18nPlugin)
app.mount('#app')

使用插件必须在 mount 之前。