Vue.js 是一套构建用户界面的渐进式框架。本文将介绍一些重要入门的知识点,比如:运行环境的搭建、定义组件的方式、引用模板、动态组件和父子组件间数据通信等等。本文首发地址为 GitHub 博客, 写文章不易,请多多支持与关注!
一、运行环境搭建
Vue 引入方式一般有三种:
第一种 CDN 引入
<script src=”[https://cdn.jsdelivr.net/npm/vue](https://cdn.jsdelivr.net/npm/vue)”></script>
第二种使用 NPM 安装
$ npm install vue// 安装最新稳定版
第三种搭建脚手架 CLI 所谓脚手架是通过 webpack 搭建的开发环境,用于快速搭建大型单页面应用程序。能够为现代前端开发的工作流程,带来持久强力的基础架构。只需几分钟,就可以建立并运行一个带有“热重载、保存时代码检查以及可直接用于生产环境的构建配置”的项目。
首先必须先安装 node.js,Node.js 在 0.6.3 版本开始内建 npm,所以安装好 node.js 后,npm 也就装好。然后在通过 git bash 操作以下命令行:
$ node -v// 检查是否已经装好了 node
$ npm -v// 检查是否已经装好了 npm
$ npm install –global vue-cli // 安装 vue-cli
$ vue init webpack project// 进入目标文件夹创建一个新项目
$ cd project// 进入新项目
$ npm install// 安装 package.json 中依赖的 node_modules
$ npm run dev// 运行该项目
对于大陆用户,建议将 npm 的注册表源设置为国内的镜像,可以大幅提升安装速度。推荐使用这种安装脚手架。
npm config set registry https://registry.npm.taobao.org// 配置淘宝镜像
npm config get registry// 验证是否成功
npm install -g cnpm –registry=https://registry.npm.taobao.org// 安装 cnpm
cnpm install -g vue-cli//cnpm 安装脚手架
vue init webpack my-project
cd my-project
cnpm install
cnpm run dev
最后打开 http://localhost:8080,就出现下面的页面,标志着脚手架搭建完成了。
二、介绍 SRC 文件流程及根组件 App
脚手架搭建完成后,project 里面各个文件夹及文件,如下图:
1.src 文件流程介绍
index.html(入口文件)=>main.js=>App.vue(根组件),根组件中模板内容就直接插入到入口文件中 #app 处,然后再将页面呈现出来。
2. 根组件 App 介绍
主要由三部分组成,分别为模板(html 结构),行为(处理逻辑)和样式(解决样式)
三、定义组件的方式
通常可以分为组件全局定义和组件局部定义,后者比较常见。
1. 组件全局定义
一般以下两个步骤:
①main.js 引入子组件
②App.vue 组件中 template 调用
//main.js
import Vue from ‘vue’
import App from ‘./App’
import Users from “./components/Users”;// 引入子组件 Users
Vue.config.productionTip = false
Vue.component(“users”,Users);// 自定义名字便于 App.vue 组件调用,后者为组件名
new Vue({
el: ‘#app’,
components: {App},
template: ‘<App/>’
})
//App.vue 组件
<template>
<div id=”app”>
<users></users>// 在这里调用,自定义名字是小写的
</div>
</template>
还可以先创建组件构造器,然后由组件构造器创建组件,不过这种比较少用:
<div id=”itany”>
<hello></hello>
</div>
…
// 使用 Vue.extend() 创建一个组件构造器
var MyComponent=Vue.extend({
template:'<h3>Hello World</h3>’
});
// 使用 Vue.component(标签名, 组件构造器),根据组件构造器来创建组件
Vue.component(‘hello’,MyComponent);
var vm=new Vue({// 这里的 vm 也是一个组件,称为根组件 Root
el:’#itany’,
data:{
msg:’ 前端 ’
}
});
2. 组件局部定义
一般以下三个步骤:
①import 引入子组件
②export default 注册子组件
③template 模板中加入子组件
四、引用模板和动态组件
1. 引用模板
通过标签 <template></template> 包裹起来来创建一个组件模板,示例如下:
<template id=”app”>
<!– <template> 必须有且只有一个根元素 –>
<h1>hello</h1>
</template>
Vue.component(“component-name”,{
template:’#app’// 在此引入
})
2. 动态组件
多个组件使用同一个挂载点,然后动态的在它们之间切换。根据 v-bind:is=” 组件名 ” 中的组件名去自动匹配组件,如果匹配不到则不显示。
动态切换掉的组件(非当前显示的组件)是被移除掉了,如果想把切换出去的组件保留在内存中,可以保留它的状态或避免重新渲染,可以添加一个 keep-alive 指令参数。
<div id=”itany”>
<button @click=”flag=’my-hello'”> 显示 hello 组件 </button>
<button @click=”flag=’my-world'”> 显示 world 组件 </button>
<div>
<!– 使用 keep-alive 组件缓存非活动组件,可以保留状态,避免重新渲染,默认每次都会销毁非活动组件并重新创建 –>
<keep-alive>
<component :is=”flag”></component>
</keep-alive>
</div>
</div>
<script>
var vm = new Vue({
el: ‘#itany’,
data: {
flag: ‘my-hello’
},
components: {
‘my-hello’: {
template: ‘<h3> 我是 hello 组件:{{x}}</h3>’,
data() {
return {
x: Math.random()
}
}
},
‘my-world’: {
template: ‘<h3> 我是 world 组件:{{y}}</h3>’,
data() {
return {
y: Math.random()
}
}
}
}
});
</script>
五、父组件向子组件传值
在一个组件内部定义另一个组件,称为父子组件。子组件只能在父组件内部使用。默认情况下,子组件无法访问父组件中的数据,每个组件实例的作用域是独立的。
接下来我们通过一个例子,说明父组件如何向子组件传递值:在子组件 Users.vue 中如何获取父组件 App.vue 中的数据 users:[“Henry”,”Bucky”,”Emily”]
1. 创建子组件,在 src/components/ 文件夹下新建一个 Users.vue 子组件
2. 在 App.vue 中注册 Users.vue 组件,并在 template 中加入 users 标签
//App.vue 父组件
<template>
<div id=”app”>
<users v-bind:users=”users”></users>// 前者自定义名称便于子组件调用,后者要传递数据名
</div>
</template>
<script>
import Users from “./components/Users”
export default {
name: ‘App’,
data(){
return{
users:[“Henry”,”Bucky”,”Emily”]
}
},
components:{
“users”:Users
}
}
3.Users.vue 的中创建 props,然后创建一个 users 的属性
//users 子组件
<template>
<div class=”hello”>
<ul>
<li v-for=”user in users”>{{user}}</li>// 遍历传递过来的值,然后呈现到页面
</ul>
</div>
</template>
<script>
export default {
name: ‘HelloWorld’,
props:{
users:{// 这个就是父组件中子标签自定义名字
type:Array,
required:true
}
}
}
</script>
总结:父组件通过 props 向下传递数据给子组件。注:组件中的数据共有三种形式:data、props、computed
六、子组件向父组件传值(通过事件形式)
接下来我们通过一个例子,说明子组件如何向父组件传递值:当我们点击“Vue.js Demo”后,子组件向父组件传递值,文字由原来的“传递的是一个值”变成“子向父组件传值”,实现子组件向父组件值的传递。
1. 在子组件(header 组件)中文字部分绑定一个点击事件
<template>
<header>
<h1 @click=”changeTitle”>{{title}}</h1>// 绑定一个点击事件
</header>
</template>
<script>
2. 子组件中响应该点击事件的函数中使用 $emit 来触发一个自定义事件,并传递一个参数
<script>
export default {
name: ‘app-header’,
data() {
return {
title:”Vue.js Demo”
}
},
methods:{
changeTitle() {
this.$emit(“titleChanged”,” 子向父组件传值 ”);// 自定义事件 传递值“子向父组件传值”
}
}
}
</script>
3. 在父组件(App 根组件)中的子标签中监听该自定义事件并添加一个响应该事件的处理方法
<template>
<div id=”app”>
<app-header v-on:titleChanged=”updateTitle” ></app-header>// 与子组件 titleChanged 自定义事件保持一致,updateTitle($event) 接受传递过来的文字
<h2>{{title}}</h2>
</div>
</template>
<script>
import Header from “./components/Header”
export default {
name: ‘App’,
data(){
return{
title:” 传递的是一个值 ”
}
},
methods:{
updateTitle(e){// 声明这个函数
this.title = e;
}
},
components:{
“app-header”:Header,
}
}
</script>
总结:子组件通过 events 给父组件发送消息,实际上就是子组件把自己的数据发送到父组件。
七、总结
在通信中,无论是子组件向父组件传值还是父组件向子组件传值,他们都有一个共同点就是都有中间介质,子向父的介质是自定义事件,父向子的介质是 props 中的属性。