0%

vue

vue-cli

vue-cli 是 Vue.js 开发的标准工具。它简化了程序员基于 webpack 创建工程化的 Vue 项目的过程。
中文官网:https://cli.vuejs.org/zh/
https://cn.vuejs.org/v2/guide/

安装和使用

vue-cli 是 npm 上的一个全局包,使用 npm install 命令,即可方便的把它安装到自己的电脑上:
npm install -g @vue/cli
基于 vue-cli 快速生成工程化的 Vue 项目:
vue create 项目的名称

vue 项目中 src 目录的构成:

1
2
3
4
assets 文件夹:存放项目中用到的静态资源文件,例如:css 样式表、图片资源
components 文件夹:程序员封装的、可复用的组件,都要放到 components 目录下
main.js 是项目的入口文件。整个项目的运行,要先执行 main.js
App.vue 是项目的根组件。

vue 项目的运行流程

在工程化的项目中,vue 要做的事情很单纯:通过 main.js 把 App.vue 渲染到 index.html 的指定区域中。
其中:
① App.vue 用来编写待渲染的模板结构
② index.html 中需要预留一个 el 区域
③ main.js 把 App.vue 渲染到了 index.html 所预留的区域中

vue 组件

  • vue 是一个支持组件化开发的前端框架。

  • vue 中规定:组件的后缀名是 .vue。之前接触到的 App.vue 文件本质上就是一个 vue 的组件。

  • vue 组件的三个组成部分(其中,每个组件中必须包含 template 模板结构,而 script 行为和 style 样式是可选的组成部分。)

    • template -> 组件的模板结构
1
2
3
4
5
6
// vue 规定:每个组件对应的模板结构,需要定义到 <template> 节点中。
// template 是 vue 提供的容器标签,只起到包裹性质的作用,它不会被渲染为真正的 DOM 元素
// template 中只能包含唯一的根节点
<template>
// 内容
</template>
  • script -> 组件的 JavaScript 行为
1
2
3
4
5
// vue 规定:开发者可以在 <script> 节点中封装组件的 JavaScript 业务逻辑。
// vue 规定:.vue 组件中的 data 必须是一个函数,不能直接指向一个数据对象
<script>
export default {}
</script>
  • style -> 组件的样式
1
2
3
4
5
6
7
8
9
10
11
12
// vue 规定:组件内的 <style> 节点是可选的,开发者可以在 <style> 节点中编写样式美化当前组件的 UI 结构。
// 在 <style> 标签上添加 lang="less" 属性,即可使用 less 语法编写组件的样式:
<style lang="less">
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style>
  • 使用组件的三个步骤

    • 使用 import 语法导入需要的组件
1
import HelloWorld from './components/HelloWorld.vue'
  • 使用 components 节点注册组件
1
2
3
4
5
6
export default {
name: 'App',
components: {
HelloWorld
}
}
  • 以标签形式使用刚才注册的组件
1
2
3
4
5
6
<template>
<div id="app">
<img alt="Vue logo" src="./assets/logo.png">
<HelloWorld msg="Welcome to Your Vue.js App"/>
</div>
</template>
  • 通过 components 注册的是私有子组件

    例如:在组件 A 的 components 节点下,注册了组件 F。则组件 F 只能用在组件 A 中;不能被用在组件 C 中。

  • 在 vue 项目的 main.js 入口文件中,通过 Vue.component() 方法,可以注册全局组件。

1
2
import App from '@/components/App.vue'
Vue.component('MyApp',App)
  • 组件的 props

  • props 是组件的自定义属性,允许使用者通过自定义属性,为当前组件指定初始值

  • vue 规定:组件中封装的自定义属性是只读的,程序员不能直接修改 props 的值。否则会直接报错,要想修改 props 的值,可以把 props 的值转存到 data 中,因为 data 中的数据都是可读可写的

  • props 的 default 默认值

  • 解决组件样式冲突

1
2
3
4
5
6
7
8
9
10
11
<style lang='less' scoped>
//
//
//
</style>
//如果给当前组件的 style 节点添加了 scoped 属性,则当前组件的样式对其子组件是不生效的。如果想让某些样式对子组件生效,可以使用 /deep/ 深度选择器。
<style lang='less' scoped>
/deep/ .title{
color:blue
}
</style>
  • 组件之间的数据共享

    • 父组件向子组件共享数据需要使用自定义属性
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// 子组件
<template>
<div>
<h5>Son 组件</h5>
<p>父组件传递过来的 msg 值是: f{ msg </p>p>父组件传递过来的 user值是: {{ user }}</p>
</div>
</template>
props:[ 'msg ', 'user ']

// 父组件
<Son :msg="message" :user="userinfo"></Son>
data() {
return {
message: "hello vue.js ',
userinfo: { name: 'zs ', age: 20 }
}
}

  • 子组件向父组件共享数据
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
// 子组件
export default {
data() {
return { count: o }},
methods : {
add() {
this.count += 1
//修改数据时,通过$emit()触发自定义事件
this.$emit( 'numchange' , this.count)}
}
}

// 父组件
<Son @numchange="getNewCount"></ Son>
export default {
data() {
return {
countFromSon: 0
}
},
methods: {
getNewCount(val){
this.countFromSon = val
}
}
}

  • 兄弟组件之间的数据共享

    • 在 vue2.x 中,兄弟组件之间数据共享的方案是 EventBus。

      ① 创建 eventBus.js 模块,并向外共享一个 Vue 的实例对象
      ② 在数据发送方,调用 bus.$emit(‘事件名称’, 要发送的数据) 方法触发自定义事件
      ③ 在数据接收方,调用 bus.$on(‘事件名称’, 事件处理函数) 方法注册一个自定义事件

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
34
//eventBus.js
import Vue from 'vue'
// 向外共享 Vue 的实例对象
export default new Vue()

// 兄弟1
import bus from './eventBus.js’
export default {
data() {
return {
msg: 'hello vue.js'
}
},
methods: {
sendMsg() {
bus.$emit( ' share', this.msg)
}
}
}

// 兄弟2
import bus from './eventBus.js
export default {
data() {
return {
msgFromLeft: ''
}
},
created() {
bus.$on('share', val => {
this.msgFromLeft = val
})
}
}
  • ref 引用

    ref 用来辅助开发者在不依赖于 jQuery 的情况下,获取 DOM 元素或组件的引用。每个 vue 的组件实例上,都包含一个 $refs 对象,里面存储着对应的 DOM 元素或组件的引用。默认情况下,组件的 $refs 指向一个空对象。

    • 使用 ref 引用 DOM 元素
1
2
3
4
5
6
7
8
9
10
11
12
<!--使用ref属性,为对应的DOM添加引用名称-->
<h3 ref="myh3">MyRef 组件</h3>
<button @click="getRef">获取$refs引用</button>
methods: {
getRef() {
//通过 this.$refs.引用的名称可以获取到DOM元素的引用
console.log(this.$refs.myh3)
//操作DOM元素,把文本颜色改为红色
this.$refs.myh3.style.color = 'red'
},
}

  • 使用 ref 引用组件实例
1
2
3
4
5
6
7
8
9
10
11
12
<!--使用ref属性,为对应的“组件"添加引用名称-->
<my-counter ref="counterRef"></my-counter>
<button @click="getRef">获取$refs 引用</button>
methods: {
getRef() {
//通过 this.$refs.引用的名称可以引用组件的实例
console.log(this.$refs.counterRef()
//引用到组件的实例之后,就可以调用组件上的 methods方法
this.$refs.counterRef.add()
},
}

  • this.$nextTick(cb) 方法

    组件的 $nextTick(cb) 方法,会把 cb 回调推迟到下一个 DOM 更新周期之后执行。通俗的理解是:等组件的DOM 更新完成之后,再执行 cb 回调函数。从而能保证 cb 回调函数可以操作到最新的 DOM 元素。

1
2
3
4
5
6
7
8
9
10
11
12
<input type="text" v-if="inputVisible" ref="ipt">
<button v-else @click="showInput">展示input输入框</button>
methods: {
showInput() {
this.inputvisible = true
//把对input文本框的操作,推迟到下次DOM更新之后。否则页面上根本不存在文本框元素
this.$nextTick(() => {
this.$refs.ipt.focus()
})
},
}

赏口饭吃吧!