一套用于构建用户界面的渐进式框架, 核心库只关注视图层,易于上手,便于与第三方库或现有项目整合,且轻量。html
使用插值表达式,基于 MVVM 来动态的影响页面与变量前端
# 页面上键入插值表达式 <div id="app"> {{ message }} # View 角色 </div>
# 而后,进行 ViewModle 数据绑定。是 VM 角色 var app = new Vue({ # 新建 Vue 实例 el: '#app', # 经过ID选择器,来接管 div 区域 data: { message: 'Hello Vue!' # 是 Model 角色 } })
使用 v-modle 指令实现双向绑定vue
能够在一个 app 块中绑定多个变量,在赋值的时候使用逗号隔开。这样就渐渐的至关于 angula.js 使用 ng-app 声明在 body上占地为王同样node
var app = new Vue({ el:'#app', data:{ flag:true, user:"张三" } });
而且能够在浏览器调试页,使用 app.变量名 = 值 ,替换变量的值。webpack
当变量的值为 true 时,显示被 v-if 指令所在标签包裹的HTML内容。当值为 false 删除其所在html标签web
<div id="app-3"> <span v-if="flag"> 你能看见我吗? </span> </div>
var app3 = new Vue({ el:'#app-3', data:{ flag:true } });
当变量的值为 false 时,为DOM的HTML标签添加CSS属性: style="display: none;"vue-cli
所以:对于常常须要进行显示/隐藏切换的DOM标签,使用 v-show 性能更加优异npm
<div id="app"> <ur v-for="user in users"> <li>{{user.name}}---{{user.age}} </li> </ur> </div>
var app = new Vue({ el:'#app', data:{ users:[ {"name":"张三","age":23}, # JSON格式定义对象 {"name":"李四","age":24}, {"name":"王五","age":25}, {"name":"赵六","age":26} ] } });
<ur v-for="(user, index) in users":key="index"> <li>{{index + 1}} {{user.name}}---{{user.age}}</li> </ur>
组件:页面上的某一部分,当一个网页很是大时,能够将该网页的内容拆分红几个部分,便于维护编程
Vue.component('todo-item', { # 经过 Vue.component('组件名',{组件内容}) 定义组件 template : "<li>Item</li>" # 经过 template 属性定义组件的内容 });
<ul> <todo-item></todo-item> <!-- 在页面以标签的方式使用组件 --> </ul>
// 定义局部组件 var TodoList = { template : "<li>Item</li>" }; // 注册局部组件 new Vue({ el: '#app', components : { "todo-item" : TodoList # 仍然在页面使用 todo-item 这个名字来使用组件 })
<ul> <!-- 在使用组件的时候,能够进行传值,使用 : 变量名 = “值” --> <todo-item v-for="(content, index) in list" :key="index" :content="content" ></todo-item> </ul>
// 全局组件 Vue.component('todo-item', { props : ['content'], # 用来接收传过来的值 template: "<li>{{content}}</li>" # 使用插值表达式来显示值 });
一个组件也是一个实例浏览器
组件里面也能够写:methods / data / computed 属性
任何Vue项目都是由 n 个实例构成的
对于根实例,虽然没有显式的定义 template 模板属性,可是Vue会根据 el 属性,去找挂载点,将挂载点里面的所有内容做为模板
父子组件之间的交互
父组件向子组件传递数据:
使用 : 属性名 = “值” 的方式传递,子组件 使用 props : ["属性名1", "属性名2"] 的方式接收
子组件向父组件传递数据:
使用 : this.$emit("消息名", 参数) 的方式来发送消息,在父组件的模板中使用 @消息名 = “函数名” 的方式来接收消息并处理。
具体的使用见练习2.
挂载点: el 属性绑定的DOM标签。用来声明Vue的做用域。不包含标签内部的变量
模板: 挂载点内部的HTML内容统称为模板。模板的定义方式有两种:
var app = new Vue({ el:'#app', # 模板内容会覆盖本来挂载点里面的内容,请注意 template:"<h1>Hello {{msg}}</h1>", # 定义模板时,须要用标签来包装内容,不然没法识别 data:{ msg:"Hello World" } });
实例:建立的 Vue 对象
Vue.js 不支持IE8及如下版本,由于他使用了IE8不支持的 ECMAScript5 的特性。
<!-- 开发环境下引入完成包,生产环境引 min.js 包 --> <script src="./vue.js"></script>
以 v- 做为前缀,vue指令会在渲染的DOM上应用特殊的响应行为。
绑定DOM标签内的text文本内容。若是内容中存在HTML标签,会被原样展现
绑定DOM标签内HTML内容
var app = new Vue({ el:'#app', data:{ text:"Hello" }, methods:{ # 这个属性用来定义实例中的方法 changeText : function () { app.text = "World" } } }); // 或者能够采用 this.text 的方式来更改 text changeText : function () { this.text = "World" }
为 title 属性后面的内容赋予了特殊的意义。例如此例中 “” 内的 title 表示Vue实例中的title变量的值
v-bind: 能够简写为 : :
用来对变量进行一些运算操做。
优势:当参与运算的变量没有改变时,结果会采用上一次的缓存值
<div id="app"> 姓:<input v-model="firstName"/> 名:<input v-model="lastName"/> <div>{{fullName}}</div> </div>
使用 computed 属性来定义参计算结果的函数
new Vue({ el:'#app', data:{ firstName:"", # 必须提早定义为 “” 不然页面会显示fullName为 undefined lastName:"" }, computed:{ # 定义计算属性 fullName : function () { return this.firstName + " " + this.lastName; # 返回字符串拼接结果 } } });
监听某个数据的变化,当它产生变化时,执行回调函数
watch: { # 定义侦听器 fullName : function () { # 侦听的变量为 fullName this.count ++ ; # 回调函数方法体 } }
需求:如上面的动图,当输入框输入内容后,点击提交就会在下面的列表展现新添加的数据,若是用户没有写任何数据点击提交,提示他应该输入以后才能点击
<div id="app"> <input v-model="num" ref="id"/> <!-- 添加ref属性,以便使用Vue选择器来获取该输入框的 --> <button @click="add">提交</button> <ul> <!-- 添加key属性,提升遍历速度 --> <li v-for="(entity, index) in list":key="index">{{entity.num}}</li> </ul> </div>
<script> var app = new Vue({ el: '#app', data:{ num:"", list:[ {num:1}, {num:2}, {num:3}, {num:4} ] }, methods:{ add : function () { if(this.num){ this.list.push({num:this.num}); this.num = ""; # 添加完成后,删除原来的数据 }else { alert("请输入要添加的内容后重试!"); this.$refs.id.focus(); # vue语法,让输入框得到焦点,提升用户体验 } } } }); </script>
完成 TodoList 中点击某个 li 删除它的功能
<div id="app"> <input v-model="num" ref="id"/> <button @click="add">提交</button> <ul> <todo-item v-for="(content, index) in list" :key="index" :content="content" 父组件向子组件传递数据 :index="index" @delete = "handleDelete" 父组件的订阅方法 ></todo-item> </ul> </div>
<script> // 全局组件 Vue.component('todo-item', { props : ['content', 'index'], # 子组件接收数据 template: '<li @click="deleteItem">{{content}}</li>', # 绑定点击事件 methods:{ deleteItem:function () { this.$emit("delete", this.index); # 子组件向父组件发送消息,携带该 li 的index 数据 } } }); new Vue({ el: '#app', data: { num: "", list: [] }, methods: { add: function () { if (this.num) { this.list.push(this.num); this.num = ""; } else { alert("请输入要添加的内容后重试!"); this.$refs.id.focus(); } }, handleDelete : function (index) { # 父组件收到消息后执行删除方法,删除对应 index 的 li 标签 // alert(index); this.list.splice(index, 1); } } }); </script>
下载地址:
https://nodejs.org/en/download/
下载对应系统的版本,双击安装便可。安装完成后会自动添加全局变量。使用 node -v 来确认是否安装成功
(Node Package Manager)他是node包管理和分发的工具,使用NPM能够对应用的依赖进行管理,NPM的功能和服务端项目构建工具maven差很少,咱们经过npm 能够很方便地下载js库,打包js文件。
node.js已经集成了npm工具,在命令提示符输入 npm -v 可查看当前npm版本
包路径就是npm从远程下载的js包所存放的路径。使用 npm config ls 查询NPM管理包路径(NPM下载的依赖包所存放的路径)
使用下面的命令来设置:
npm config set prefix "C:\develop\nodeJS\npm_modules" npm config set cache "c:\develop\nodeJS\npm_cache"
npm install -g cnpm --registry=https://registry.npm.taobao.org
安装完成后使用:cnpm -v 来查看
注意:若是安装后,出现 cnpm 不是内部或外部命令,也不是可运行的程序。就须要检查cnpm 的路径是否正确。将 cnpm包的全部文件复制和 npm.cmd 文件在同一级目录下便可。
究其缘由:是由于环境变量中仅仅配置了 npm.cmd 所在文件夹路径,咱们也能够将 npm_modules 目录添加到环境变量中,这样也不会出现这个问题。推荐使用该方法
添加环境变量:
在 PATH 中添加:
cnpm install -g nrm
查看已安装的镜像 : nrm ls 切换镜像 nrm use XXX
npm install --global vue-cli
最后一行选项选择的是包/依赖安装方式
这里由于我电脑上只有IDEA而且懒得安装前端编程IDE,因此就使用IDEA来编程
安装后会存在一个问题,IDEA 并不能正确识别 .vue 文件(我是2018.2版本,不知新版解决没有),所以会将.vue文件识别成普通文本文件,给咱们编码带来很大的不便,解决办法如图:
另外,IDEA也不能识别ES6语法,咱们也须要进行一些配置:
经过上面的两个设置,就能够愉快的使用 IDEA 进行 Vue 项目编程啦!
Vue-Cli 中编辑的项目是支持热部署的,耶!
项目根目录下有一个 index.html
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width,initial-scale=1.0"> <title>todolist</title> </head> <body> <div id="app"></div> <!-- 这里定义了一个 app 的挂载点 --> <!-- built files will be auto injected --> </body> </html>
src 目录下有 main.js 是 Vue 项目的入口js
// The Vue build version to load with the `import` command // (runtime-only or standalone) has been set in webpack.base.conf with an alias. import Vue from 'vue' import App from './App' Vue.config.productionTip = false /* eslint-disable no-new */ new Vue({ el: '#app', components: { App }, # 这里采用 ES6 的语法,若是某 key 和 value 是同样的,能够简写成 key template: '<App/>' })
能够看出,入口文件引入了同目录下的 App.vue 文件,那么这个文件里面有什么内容呢?
<template> <div id="app"> <img src="./assets/logo.png"> <HelloWorld/> </div> </template> <script> import HelloWorld from './components/HelloWorld' export default { name: 'App', components: { HelloWorld } } </script> <style> #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>
因而可知,Vue 项目对各个模块进行了拆分,以达到解耦的目的。具体的好处且往下看
使用 vue-cli 实现 TodoList
<template> <div> <input> <button>提交</button> </div> <ul> <li>1</li> <li>2</li> <li>3</li> </ul> </template>
这时打开浏览器会发现报错了:
所以咱们对模板文件进行修改,使用一个 div 包裹上面的两个标签,发现浏览器能够正常显示了
在 vue-cli 中,数据绑定采用另一种语法:此时数据不是直接绑定,而是间接经过函数来返回
<script> export default { <!-- 如下是 data : function(){} 的缩写 --> data(){ return { inputValue : "" } } } </script>
给提交按钮添加单击事件:
<button @click="handleClick">提交</button>
定义函数:依然能够采用 ES6 的语法,简略的写成 handleClick(){}
<script> export default { methods:{ handleClick (){ alert(123) } } } </script>
vue-cli 的子组件放在 compontents 目录下:
<template> </template> <script> export default { } </script> <style> </style>
<script> // 引入组件, import 组件名 from 组件路径 import TodoItem from './components/TodoItem' export default { // 注册组件, ‘组件标签名’:组件名 components:{ 'todo-item' : TodoItem }, ......
<ul> <todo-item></todo-item> </ul>
经过定义属性的方式来给子组件传值:
定义 content 属性,index 属性传给子组件
<ul> <todo-item v-for="(item, index) of list" :key="index" :content="item" :index="index" ></todo-item> </ul>
子组件声明接收的值:
<script> export default { props:['content'] } </script>
经过插值表达式来显示值:
<template> <li>{{content}}</li> </template>
经过发布/订阅的方式来实现子组件向父组件传值
在子组件的单击方法中定义发布消息的事件,事件名 delete, 参数:当前 li 元素的 index
handleDelete(){ this.$emit('delete', this.index) }
父组件接收消息:并触发函数的执行
<ul> <todo-item v-for="(item, index) of list" :key="index" :content="item" :index="index" @delete="handleDelete" // 接收消息 ></todo-item> </ul> handleDelete (index){ this.list.splice(index, 1) // 删除对应的元素 }
对于每个 vue 文件都包含 style 标签,这个 style 标签有一个属性 scoped 若是添加此属性则该标签内全部的样式仅对当前文件有效。开发中尽可能都添加上使得文件间的耦合性更低
这个笔记仅涵盖了 Vue 的一点点基础知识,若是读者想要深刻学习,能够前往官网参考文档继续学习:https://cn.vuejs.org/v2/guide/