[toc]

Vue2学习

1.Vue基础

渐进式JavaScript 框架

  1. 构造用户界面
    • 用vue向html页面填充数据
  2. 框架,现成的解决方法
    • 语法
    • 指令、组件、路由、Vuex
  3. vue特性
    • 数据驱动视图
      • 页面依赖的数据—>vue监听—>页面结构
      • 页面数据发生变化,页面重新渲染
    • 双向数据绑定
      • form表单负责采集数据,Ajax负责提交数据
      • 在填写表时,不操作dom,自动把用户填写的内容同步带数据源中

        MVVM

        M:model—当前页面渲染时所依赖的数据源
        V:view—页面结构(视图)
        VM:ViewModel—Vue实例
        :warning: 数据驱动视图和双向数据绑定的底层原理是MVVM

基本使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<!-- view -->
<div id="app">{{username}}</div>
<!-- 导入vue 全局就有了Vue这个构造函数 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>

<script>
// 实例化对象 ViewModel
const vm = new Vue({
// 固定写法,表示当前vm实例要控制页面上的那个区域,接受的值是一个选择器
el: '#app',
// model 数据源
data: {
username: 'lang'
},
})
</script>

指令与过滤器

  1. 指令 模板语法 内容渲染
  • v-text 渲染数据,但原数据会被覆盖
  • {{}} 插值表达式,占位符,用的最多
  • v-html 将带标签的字符串渲染html内容

属性绑定指令

  • v-bind 简写:

事件绑定

  • v-on 简写@

实际属性绑定用:,事件绑定用@

:warning:==事件原对象==
$event表示原生对象e,防止默认事件被覆盖
语法

1
2
3
4
5
6
7
<button @click="add($event,1)">click</button>
methods:{
add(e,n){
count=0;
this.count+=1
}
}

事件修饰符

阻止默认和冒泡
e.preventDefault(),e.stopPropagation()
在Vue中
@click.stop="",@click.prevnet=""
语法

1
2
3
4
<a href="" @click.prevent=""></a>
<div @click="divenvnt">
<button @click.stop="btnevnet">点我</button>
</div>

双向绑定

  1. 源数据与表单数据互相影响
    用于表单元素

    • v-model=""
  2. v-bind

    • v-bind

条件渲染

v-if,v-show
值为:false 时
v-if:动态移除元素
实际开发多用v-if
v-show:动态为元素设置 display:none

循环v-for

1
2
3
4
5
6
7
8
9
10
<tbody>
<tr
v-for="(item,index) in list"
:key="item.id"
:title="item.name+index">
<td>{{item.id}}</td>
<td>{{item.name}}</td>
<td>{{item.sex}}</td>
</tr>
</tbody>

:warning: v-for

  1. 要加key的绑定,拿当前的id,需为字符串或数字,key的值不能
    重复
  2. key值必须唯一
  3. 不建议index,它不具有唯一性
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    <script>
    const vm = new Vue({
    el: "#app",
    data: {
    list: [{
    id: 1,
    name: 'lang',
    sex: '男'
    },
    {
    id: 2,
    name: 'zhang',
    sex: '女'
    },
    {
    id: 3,
    name: 'lisi',
    sex: '男'
    }
    ]

    }
    })
    </script>

    过滤器filter

  4. 局部过滤器
    • 在当前绑定的el下定义
  5. 全局过滤器
    • 全局通过Vue.filter()定义
  6. 如果全局过滤器与私有过滤器重名则使用私有的。
  7. 过滤器传参
    Vue.filter(‘’,function(msg,arg1,arg2){})

侦听器watch

  1. 方法格式
    • 无法在刚进入页面的时候,自动触发
    • 如果侦听器是一个对象,若对象中的属性发生了变化,不会触发侦听器
  2. 对象格式
    • 可通过immediate让侦听器自动触发
    • 可通过deep选项,让侦听器深度监听每个属性的变化

计算属性computed

  1. 需要在computed里面定义为方法
  2. 当做普通的属性使用即可(会被挂载到vm上)
  3. 实现了代码复用

axios

专注以网络请求
官方解释:Axios 是一个基于 promise 的网络请求库,可以用于浏览器和 node.js

  1. GET请求
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    <script>
    axios({
    method: 'GET',
    url: '',
    // get url传参
    params: {
    id: 1
    },

    }).then(function (res) {
    console.log(res);
    })
    </script>
    2.POST请求
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    <script>
    (async function () {
    // 解构
    var {
    data
    } = await axios({
    method: 'POST',
    url: 'http://www.liulongbin.top:3006/api/post',
    data: {
    name: 'ls',
    age: 90
    }
    })
    console.log(data);
    }())
    </script>

    如果调用某个方法返回值是promise实例,则前面可以添加await,且只能用在async修饰的方法中

2.Vue-cli

单页面应用程序
专注开发,不在专注于webpack的配置

  1. 安装
    1
    npm install -g @vue/cli
  2. 创建项目
    1
    vue create projectName

    注意:项目名称必须为英文且均为小写,不然会报错

3.项目运行流程

通过main.js把App.vue渲染到index.html指定区域中

4.Vue组件

每个.vue组件由三部分组成

  • template组件的模板结构
  • script组件的JavaScript行为
  • style组件样式

组件之间的关系

  1. 组件在封装好之后彼此之间是相互独立的,不存在父子关系。
  2. 使用的时候才行形成父子或兄弟关系。

使用组件

使用import导入需要的组件

在根组件App.vue中
import Test from '@/components/Test.vue'

‘@’代表scr目录

引入scr目录在webpack.config.js中的写法

1
2
3
4
5
6
7
8
webpack.config.js
module.exports={
resolve:{
alias:{
@:path.join(__dirname,'/scr')
}
}
}

使用components结点注册组件
1
2
3
4
5
export default{
components:{
Test
}
}

以标签形式使用刚注册的Test组件
1
2
3
4
5
<template>
<div>
<Test></Test>
</div>
</template>

私有组件

全局组件

注册全局组件:
在vue项目的main.js文件中,通过Vue.components('myTest',Test)方法,可以注册全局组件

组件的props

  1. 自定义属性,使用者自定义属性,为当前组件指定初始值
  2. 在封装通用组件的时候,合理的使用props可以提高组件之间的复用性

用法:
props:['init1','init2','inti2','init4',...]

prop只读

样式冲突

  1. 在style中加入scoped<style scoped></style>只渲染自己的样式
  2. 父组件改变子组件的样式在元素前面加/deep/
1
2
3
/deep/h2 {
color: white;
}

.vue模板

最终都会被vue-template-compiler编译为js文件

组件的生命周期

  1. 创建一个组件的实例
  2. 生命周期
    • 一个组件从创建->运行->销毁
    • 卡时间点(卡bug)
      • beforeCreate->created->breforeMount->mounted
      • breforeUpdate->update
      • breforeDestory->destory
        https://cn.vuejs.org/assets/lifecycle.16e4c08e.png

beforeCreate

  1. 此阶段props,data,methods不能访问

created

  1. 此阶段可发起ajax请求
  2. 不能操作DOM,文档还没创建

beforeMount

  1. 将要将内存中编译好的HTML结构进行渲染
  2. 不能操作DOM

mounted

  1. 浏览器已包含DOM结构

breforeUpdate

组件之间的数据共享

  1. 父向子
    自定义属性
  2. 子向父
    自定义事件
  3. 兄弟之间
    eventBus
  • 创建eventBus.js模块,并向外共享Vue实例对象。
  • 在数据发送方,调用bus.$emit(事件名称,要发送的数据)方法,触发自定义事件。
  • 在数据接收方,调用bus.$on(事件名称,事件处理函数)方法,注册一个自定义事件。

ref引用

在不依赖JQuery的情况下,获取DOM元素或组件的引用

购物车案例

5.动态组件

<component is=""></component>

保证组件不会被销毁

将内部组件进行缓存—不销毁

1
2
3
<keep-alive>
<component is=""></component>
</keep-alive>

is:值要渲染的组件名字,是组件在components结点下的注册名称
include:指定哪些组件可以被缓存
exclude:哪些组将不需要缓存

组件的“注册名称”的主要应用场景是,以标签的形式,把注册好的组件,渲染和使用到页面的结构中

组件声明时的name名称主要应用场景:结合<keep-alive>标签实现组件的缓存功能,以及在调试工具中看到的组件的name名称

插槽

<solt></solt>

vue为组件的封装者提供的能力,允许开发者在封装组件时,把不确定的,希望有用户指定的部分定义为插槽

默认情况下,在使用组件的时候,提供的内容都会被填充到default的插槽中

  1. 如果要把指定的内容填充到指定名称的插槽中,需要使用v-slot
  2. v-slot:后面跟上插槽的名字
  3. v-slot:不能直接用在元素上,必须在template标签上
  4. template这个标签,他是一个占位标签,只能能起到包裹的作用,不会被渲染为任何html元素
  5. v-slot:简写#
  6. 作用域插槽
1
2
<slot name="content" msg="hello" :user="userInfo"></slot>
<template #content="{msg,user}"></template>

自定义指令

在某个组件中

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

directives:{
// 定义名为color的指令,指向一个配置对象
/* color:{
// 当指向第一次被绑定倒元素上的时候,会立即触发bind函数
// el 表示color绑定的元素
bind(el){
el.style.color='red'
},
// 第一次不生效
update(el, binding) {

el.style.color = binding.value
},
} */
// 当color和update里面一样时,可以用以下方式
color(el,binding){
el.style.color = binding.value
}
}

全局自定义指令

在mian.js文件中

1
2
3
4
// 全局自定义指令v-color
Vue.directive('color', (el, binding) => {
el.style.color = binding.value
})

6.ESLint

可组装的JavaScript和JSX检查工具
插件的安装

  • ESLint
  • prettier

配置,在settings.json文件中加入

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
29
30
31
32
33
// ESlint插件的配置
"editor.codeActionsOnSave": {
"source.fixAll": true
},
// .prettierrc文件的位置(最好在C盘Users目录下)
"prettier.configPath": "C:\\Users\\ThinkPad\\.prettierrc",
"eslint.alwaysShowStatus":true,
"prettier.trailingComma": "none",
"prettier.semi":false,
// 每行文字超出此限制,强制换行
"prettier.printWidth":300,
// 使用单英引号替换双引号
"prettier.singleQuote": true,
"prettier.arrowParens": "avoid",
// 设置.vue文件中,html代码的格式插件
"vetur.format.defaultFormatter.html": "js-beautify-html",
// 忽略警告
"vetur.ignoreProjectWarning":true,
"vetur.format.defaultFormatterOptions": {
"prettier": {
"trailingComma":"none",
"semi":false,
"singleQuote":true,
"arrowParens":"avoid",
"printWidth":300
},
"js-beautify-html": {
"wrap_attributes": false,
},
},
"[vue]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
}

7.axios

全局使用
main.js

1
2
3
4
5
6
7
8
9
10
11
// 全局使用axios
import axios from 'axios'
// 全局配置axios的请求根路径
axios.defaults.baseURL = 'http://www.xxx/xxx'
// 将axios挂载到Vue原型对象身上
// Vue.prototype.axios=axios
Vue.prototype.$http = axios
// 但是吧axios挂载到Vue的原型链上有一个缺点,不利于API接口的复用

// 在组将中可以直接使用,方式:
let { data: res } = await this.$http.get('/get')

8.路由

  1. SPA和路由
  2. 前端路由
    • Hash地址与组件之间的对应关系
  3. 路由的工作方式
    • 用户点击的页面上的路由模块
    • 当Url地址栏中的Hash值发生了变化
    • 前端路由监听到了Hash地址的变换
    • 前端路由把当前Hash地址对应的组件渲染到浏览器中
      Hash——>component

安装和使用

  1. 安装
    官网
    npm install vue-router@4
  2. 使用
    scr目录下新建router/index.js
    index.js内容
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    //scr/router/index.js 路由地址
    import Vue from 'vue'
    // 1、导入
    import VueRouter from 'vue-router'

    // 2、调用Vue.use()函数,把xxx安装为Vue的插件
    Vue.use(VueRouter)
    // 3、实例化对象
    const router = new VueRouter()
    // 4、实例对象共享出去
    export default router
    main.js中导入并挂载
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    import Vue from 'vue'
    import App from './App.vue'

    // 导入路由模块,拿到实例对象router
    import router from '@/router/index.js'
    Vue.config.productionTip = false

    new Vue({
    render: h => h(App),
    // 将路由的实例对象挂在到Vue上
    // router:实例对象
    router:router
    }).$mount('#app')

动态路由

  1. 路径参数值this.$route.params.id
  2. 通过props拿到路径参数props:['id']
  3. 查询参数this.$route.query
  4. 完整路径参数this.$route.fullPath

导航

  1. 声明式导航(点击链接)
  2. 编程式导航(调用API)
    1
    2
    3
    4
    5
    6
    // 跳转到指定hash地址,并增加一条历史记录
    this.$router.push()
    // 跳转到指定hash地址,并替换掉当前的历史记录
    this.$router.replace()
    // 后退或前进
    this.$router.go()

导航守卫

全局前置守卫

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// 为router实例对象,声明全局前置导航守卫
router.beforeEach((to, from, next) => {
// to:将要访问路由的信息对象
// from:将要离开的路由的信息对象
// next()放行
// console.log(to);

if (to.path === '/main') {
// 要访问后台主页,需要判断
const token = localStorage.getItem('token')
// 若有token,证明登录,放行
if (token) {
next()
// 否则要登录
} else {
next('/login')
}
} else {
next()
}
})

头条案例

https://gitee.com/lang-xiaohu/demo-toutiao

tab示例

This is Tab 1.

This is Tab 2.

This is Tab 3.

10.总结

  1. 了解了Vue的基本使用方法(指令、条件、循环…)
  2. 如何基于Vue-cli创建和开发工程化的Vue项目
  3. 能够运用组件化的开发思想,进行企业级的项目开发
  4. 能够使用指令、侦听器、插槽、生命周期、组件通讯等技术,完成业务开发
  5. 掌握在Vue项目中如何封装和使用axios来请求后端的API接口
  6. 使用vue-router实现单页面应用程序开发
  7. 在Vue项目中使用VantElement-UI组件库
  8. 运用vue-devtools来调试自己的Vue项目