一套用于构建用户界面的渐进式框架, 核心库只关注视图层,易于上手,便于与第三方库或现有项目整合,且轻量。

使用插值表达式,基于 MVVM 来动态的影响页面与变量

  1. # 页面上键入插值表达式
  2. <div id="app">
  3. {{ message }} # View 角色
  4. </div>
  1. # 然后,进行 ViewModle 数据绑定。是 VM 角色
  2. var app = new Vue({ # 新建 Vue 实例
  3. el: '#app', # 通过ID选择器,来接管 div 区域
  4. data: {
  5. message: 'Hello Vue!' # 是 Model 角色
  6. }
  7. })

使用 v-modle 指令实现双向绑定

可以在一个 app 块中绑定多个变量,在赋值的时候使用逗号隔开。这样就渐渐的相当于 angula.js 使用 ng-app 声明在 body上占地为王一样

  1. var app = new Vue({
  2. el:'#app',
  3. data:{
  4. flag:true,
  5. user:"张三"
  6. }
  7. });

并且可以在浏览器调试页,使用 app.变量名 = 值 ,替换变量的值。

当变量的值为 true 时,显示被 v-if 指令所在标签包裹的HTML内容。当值为 false 删除其所在html标签

  1. <div id="app-3">
  2. <span v-if="flag">
  3. 你能看见我吗?
  4. </span>
  5. </div>
  1. var app3 = new Vue({
  2. el:'#app-3',
  3. data:{
  4. flag:true
  5. }
  6. });

当变量的值为 false 时,为DOM的HTML标签添加CSS属性: style=”display: none;”

因此:对于经常需要进行显示/隐藏切换的DOM标签,使用 v-show 性能更加优异

  1. <div id="app">
  2. <ur v-for="user in users">
  3. <li>{{user.name}}---{{user.age}} </li>
  4. </ur>
  5. </div>
  1. var app = new Vue({
  2. el:'#app',
  3. data:{
  4. users:[
  5. {"name":"张三","age":23}, # JSON格式定义对象
  6. {"name":"李四","age":24},
  7. {"name":"王五","age":25},
  8. {"name":"赵六","age":26}
  9. ]
  10. }
  11. });
  • 在调试页中可以使用 app.users.push({“name”:”xxx”,”age”:23}) 动态添加数据
  • 定义一个唯一的字段作为 key ,可以提高遍历效率
  • 在遍历时以如下方式使用 index
  1. <ur v-for="(user, index) in users":key="index">
  2. <li>{{index + 1}} {{user.name}}---{{user.age}}</li>
  3. </ur>

组件:页面上的某一部分,当一个网页非常大时,可以将该网页的内容拆分成几个部分,便于维护

  1. 定义全局组件
  1. Vue.component('todo-item', { # 通过 Vue.component('组件名',{组件内容}) 定义组件
  2. template : "<li>Item</li>" # 通过 template 属性定义组件的内容
  3. });
  1. <ul>
  2. <todo-item></todo-item> <!-- 在页面以标签的方式使用组件 -->
  3. </ul>
  1. 定义局部组件
  1. // 定义局部组件
  2. var TodoList = {
  3. template : "<li>Item</li>"
  4. };
  5. // 注册局部组件
  6. new Vue({
  7. el: '#app',
  8. components : {
  9. "todo-item" : TodoList # 仍然在页面使用 todo-item 这个名字来使用组件
  10. })
  1. <ul>
  2. <!-- 在使用组件的时候,可以进行传值,使用 : 变量名 = “值” -->
  3. <todo-item
  4. v-for="(content, index) in list"
  5. :key="index"
  6. :content="content"
  7. ></todo-item>
  8. </ul>
  1. // 全局组件
  2. Vue.component('todo-item', {
  3. props : ['content'], # 用来接收传过来的值
  4. template: "<li>{{content}}</li>" # 使用插值表达式来显示值
  5. });

一个组件也是一个实例

​ 组件里面也可以写:methods / data / computed 属性

任何Vue项目都是由 n 个实例构成的

​ 对于根实例,虽然没有显式的定义 template 模板属性,但是Vue会根据 el 属性,去找挂载点,将挂载点里面的全部内容作为模板

父子组件之间的交互

父组件向子组件传递数据:

​ 使用 : 属性名 = “值” 的方式传递,子组件 使用 props : [“属性名1″, “属性名2”] 的方式接收

子组件向父组件传递数据:

​ 使用 : this.$emit(“消息名”, 参数) 的方式来发送消息,在父组件的模板中使用 @消息名 = “函数名” 的方式来接收消息并处理。

具体的使用见练习2.

挂载点: el 属性绑定的DOM标签。用来声明Vue的作用域。不包含标签内部的变量

模板: 挂载点内部的HTML内容统称为模板。模板的定义方式有两种:

  • 直接定义在挂载点所在的标签体内
  • 在 Vue 实例里使用 template 定义:
  1. var app = new Vue({
  2. el:'#app',
  3. # 模板内容会覆盖原本挂载点里面的内容,请注意
  4. template:"<h1>Hello {{msg}}</h1>", # 定义模板时,需要用标签来包装内容,否则无法识别
  5. data:{
  6. msg:"Hello World"
  7. }
  8. });

实例:创建的 Vue 对象

Vue.js 不支持IE8及以下版本,因为他使用了IE8不支持的 ECMAScript5 的特性。

  1. <!-- 开发环境下引入完成包,生产环境引 min.js 包 -->
  2. <script src="./vue.js"></script>

以 v- 作为前缀,vue指令会在渲染的DOM上应用特殊的响应行为。

绑定DOM标签内的text文本内容。如果内容中存在HTML标签,会被原样展示

绑定DOM标签内HTML内容

  • 绑定单击事件。注意:单击调用的方法只写方法名,不写小括号
  • 在实例中定义 methods 对象,对象内部可以定义方法
  • 另外, v-on:click 也可以简写成: @click
  1. var app = new Vue({
  2. el:'#app',
  3. data:{
  4. text:"Hello"
  5. },
  6. methods:{ # 这个属性用来定义实例中的方法
  7. changeText : function () {
  8. app.text = "World"
  9. }
  10. }
  11. });
  12. // 或者可以采用 this.text 的方式来更改 text
  13. changeText : function () {
  14. this.text = "World"
  15. }

为 title 属性后面的内容赋予了特殊的意义。例如此例中 “” 内的 title 表示Vue实例中的title变量的值

v-bind: 可以简写为 :

用来对变量进行一些运算操作。

优点:当参与运算的变量没有改变时,结果会采用上一次的缓存值

  1. <div id="app">
  2. 姓:<input v-model="firstName"/>
  3. 名:<input v-model="lastName"/>
  4. <div>{{fullName}}</div>
  5. </div>

使用 computed 属性来定义参计算结果的函数

  1. new Vue({
  2. el:'#app',
  3. data:{
  4. firstName:"", # 必须提前定义为 “” 否则页面会显示fullName为 undefined
  5. lastName:""
  6. },
  7. computed:{ # 定义计算属性
  8. fullName : function () {
  9. return this.firstName + " " + this.lastName; # 返回字符串拼接结果
  10. }
  11. }
  12. });

监听某个数据的变化,当它产生变化时,执行回调函数

  1. watch: { # 定义侦听器
  2. fullName : function () { # 侦听的变量为 fullName
  3. this.count ++ ; # 回调函数方法体
  4. }
  5. }

vue1

需求:如上面的动图,当输入框输入内容后,点击提交就会在下面的列表展示新添加的数据,如果用户没有写任何数据点击提交,提示他应该输入之后才能点击

  1. <div id="app">
  2. <input v-model="num" ref="id"/> <!-- 添加ref属性,以便使用Vue选择器来获取该输入框的 -->
  3. <button @click="add">提交</button>
  4. <ul> <!-- 添加key属性,提高遍历速度 -->
  5. <li v-for="(entity, index) in list":key="index">{{entity.num}}</li>
  6. </ul>
  7. </div>
  1. <script>
  2. var app = new Vue({
  3. el: '#app',
  4. data:{
  5. num:"",
  6. list:[
  7. {num:1},
  8. {num:2},
  9. {num:3},
  10. {num:4}
  11. ]
  12. },
  13. methods:{
  14. add : function () {
  15. if(this.num){
  16. this.list.push({num:this.num});
  17. this.num = ""; # 添加完成后,删除原来的数据
  18. }else {
  19. alert("请输入要添加的内容后重试!");
  20. this.$refs.id.focus(); # vue语法,让输入框获得焦点,提高用户体验
  21. }
  22. }
  23. }
  24. });
  25. </script>

完成 TodoList 中点击某个 li 删除它的功能

  1. <div id="app">
  2. <input v-model="num" ref="id"/>
  3. <button @click="add">提交</button>
  4. <ul>
  5. <todo-item
  6. v-for="(content, index) in list"
  7. :key="index"
  8. :content="content" 父组件向子组件传递数据
  9. :index="index"
  10. @delete = "handleDelete" 父组件的订阅方法
  11. ></todo-item>
  12. </ul>
  13. </div>
  1. <script>
  2. // 全局组件
  3. Vue.component('todo-item', {
  4. props : ['content', 'index'], # 子组件接收数据
  5. template: '<li @click="deleteItem">{{content}}</li>', # 绑定点击事件
  6. methods:{
  7. deleteItem:function () {
  8. this.$emit("delete", this.index); # 子组件向父组件发送消息,携带该 li index 数据
  9. }
  10. }
  11. });
  12. new Vue({
  13. el: '#app',
  14. data: {
  15. num: "",
  16. list: []
  17. },
  18. methods: {
  19. add: function () {
  20. if (this.num) {
  21. this.list.push(this.num);
  22. this.num = "";
  23. } else {
  24. alert("请输入要添加的内容后重试!");
  25. this.$refs.id.focus();
  26. }
  27. },
  28. handleDelete : function (index) { # 父组件收到消息后执行删除方法,删除对应 index li 标签
  29. // alert(index);
  30. this.list.splice(index, 1);
  31. }
  32. }
  33. });
  34. </script>

1564726440925

下载地址:

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下载的依赖包所存放的路径)

使用下面的命令来设置:

  1. npm config set prefix "C:\develop\nodeJS\npm_modules"
  2. npm config set cache "c:\develop\nodeJS\npm_cache"
  1. 安装淘宝的镜像。镜像默认是使用国外的网络来下载的。网速很慢,因此我们配置一个国内的镜像
  1. npm install -g cnpm --registry=https://registry.npm.taobao.org

安装完成后使用:cnpm -v 来查看

注意:如果安装后,出现 cnpm 不是内部或外部命令,也不是可运行的程序。就需要检查cnpm 的路径是否正确。将 cnpm包的所有文件复制和 npm.cmd 文件在同一级目录下即可。

究其原因:是因为环境变量中仅仅配置了 npm.cmd 所在文件夹路径,我们也可以将 npm_modules 目录添加到环境变量中,这样也不会出现这个问题。推荐使用该方法

添加环境变量:

1564731885562

在 PATH 中添加:

1564731919317

cnpm install -g nrm

查看已安装的镜像 : nrm ls 切换镜像 nrm use XXX

npm install –global vue-cli

  1. 创建一个文件夹,用于存放和维护 Vue 项目,这里我创建的是 c:\develop\VueProjects
  2. 切换到该文件夹,打开cmd。然后输入: vue init webpack 项目名
  3. 配置按照下图设置
    1564734104979

最后一行选项选择的是包/依赖安装方式

  1. 创建完成后,切换到项目路径。使用 npm run dev 命令启动项目

这里因为我电脑上只有IDEA并且懒得安装前端编程IDE,所以就使用IDEA来编程

安装后会存在一个问题,IDEA 并不能正确识别 .vue 文件(我是2018.2版本,不知新版解决没有),因此会将.vue文件识别成普通文本文件,给我们编码带来很大的不便,解决办法如图:

1564735407072

另外,IDEA也不能识别ES6语法,我们也需要进行一些配置:

1564735699406

通过上面的两个设置,就可以愉快的使用 IDEA 进行 Vue 项目编程啦!

Vue-Cli 中编辑的项目是支持热部署的,耶!

项目根目录下有一个 index.html

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta charset="utf-8">
  5. <meta name="viewport" content="width=device-width,initial-scale=1.0">
  6. <title>todolist</title>
  7. </head>
  8. <body>
  9. <div id="app"></div> <!-- 这里定义了一个 app 的挂载点 -->
  10. <!-- built files will be auto injected -->
  11. </body>
  12. </html>

src 目录下有 main.js 是 Vue 项目的入口js

  1. // The Vue build version to load with the `import` command
  2. // (runtime-only or standalone) has been set in webpack.base.conf with an alias.
  3. import Vue from 'vue'
  4. import App from './App'
  5. Vue.config.productionTip = false
  6. /* eslint-disable no-new */
  7. new Vue({
  8. el: '#app',
  9. components: { App }, # 这里采用 ES6 的语法,如果某 key 和 value 是一样的,可以简写成 key
  10. template: '<App/>'
  11. })

可以看出,入口文件引入了同目录下的 App.vue 文件,那么这个文件里面有什么内容呢?

  1. <template>
  2. <div id="app">
  3. <img src="./assets/logo.png">
  4. <HelloWorld/>
  5. </div>
  6. </template>
  7. <script>
  8. import HelloWorld from './components/HelloWorld'
  9. export default {
  10. name: 'App',
  11. components: {
  12. HelloWorld
  13. }
  14. }
  15. </script>
  16. <style>
  17. #app {
  18. font-family: 'Avenir', Helvetica, Arial, sans-serif;
  19. -webkit-font-smoothing: antialiased;
  20. -moz-osx-font-smoothing: grayscale;
  21. text-align: center;
  22. color: #2c3e50;
  23. margin-top: 60px;
  24. }
  25. </style>

由此可见,Vue 项目对各个模块进行了拆分,以达到解耦的目的。具体的好处且往下看

使用 vue-cli 实现 TodoList

  1. 打开上面创建的 TodoList 项目,修改 App.vue 文件名称为 TodoList.vue , 并修改其他文件中的引用名
  2. 编辑 TodoList.vue 的模板文件,代码如下:
  1. <template>
  2. <div>
  3. <input>
  4. <button>提交</button>
  5. </div>
  6. <ul>
  7. <li>1</li>
  8. <li>2</li>
  9. <li>3</li>
  10. </ul>
  11. </template>

这时打开浏览器会发现报错了

1565001521769

因此我们对模板文件进行修改,使用一个 div 包裹上面的两个标签,发现浏览器可以正常显示了

在 vue-cli 中,数据绑定采用另外一种语法:此时数据不是直接绑定,而是间接通过函数来返回

  1. <script>
  2. export default {
  3. <!-- 以下是 data : function(){} 的缩写 -->
  4. data(){
  5. return {
  6. inputValue : ""
  7. }
  8. }
  9. }
  10. </script>

给提交按钮添加单击事件:

  1. <button @click="handleClick">提交</button>

定义函数:依然可以采用 ES6 的语法,简略的写成 handleClick(){}

  1. <script>
  2. export default {
  3. methods:{
  4. handleClick (){
  5. alert(123)
  6. }
  7. }
  8. }
  9. </script>

vue-cli 的子组件放在 compontents 目录下:

1565002961390

  1. 复制一份干净的 .vue 代码,起名 TodoItem.vue
  1. <template>
  2. </template>
  3. <script>
  4. export default {
  5. }
  6. </script>
  7. <style>
  8. </style>
  1. 添加模板数据,在 TodoList.vue 实例中引入 TodoItem.vue 组件,并注册
  1. <script>
  2. // 引入组件, import 组件名 from 组件路径
  3. import TodoItem from './components/TodoItem'
  4. export default {
  5. // 注册组件, ‘组件标签名’:组件名
  6. components:{
  7. 'todo-item' : TodoItem
  8. },
  9. ......
  1. 找到合适的位置,添加组件标签
  1. <ul>
  2. <todo-item></todo-item>
  3. </ul>

通过定义属性的方式来给子组件传值

定义 content 属性,index 属性传给子组件

  1. <ul>
  2. <todo-item
  3. v-for="(item, index) of list"
  4. :key="index"
  5. :content="item"
  6. :index="index"
  7. ></todo-item>
  8. </ul>

子组件声明接收的值:

  1. <script>
  2. export default {
  3. props:['content']
  4. }
  5. </script>

通过插值表达式来显示值:

  1. <template>
  2. <li>{{content}}</li>
  3. </template>

通过发布/订阅的方式来实现子组件向父组件传值

在子组件的单击方法中定义发布消息的事件,事件名 delete, 参数:当前 li 元素的 index

  1. handleDelete(){
  2. this.$emit('delete', this.index)
  3. }

父组件接收消息:并触发函数的执行

  1. <ul>
  2. <todo-item
  3. v-for="(item, index) of list"
  4. :key="index"
  5. :content="item"
  6. :index="index"
  7. @delete="handleDelete" // 接收消息
  8. ></todo-item>
  9. </ul>
  10. handleDelete (index){
  11. this.list.splice(index, 1) // 删除对应的元素
  12. }

对于每一个 vue 文件都包含 style 标签,这个 style 标签有一个属性 scoped 如果添加此属性则该标签内所有的样式仅对当前文件有效。开发中尽量都添加上使得文件间的耦合性更低

这个笔记仅涵盖了 Vue 的一点点基础知识,如果读者想要深入学习,可以前往官网参考文档继续学习:https://cn.vuejs.org/v2/guide/

版权声明:本文为keatsCoder原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/keatsCoder/p/11305110.html