Vue.js基础手册

Vue.js是什么

Vue.js(读音 /vjuː/, 类似于 view) 是一套构建用户界面的 渐进式框架。与其他重量级框架不同的是,Vue 采用自底向上增量开发的设计。

Vue 的核心库只关注视图层,并且非常容易学习,非常容易与其它库或已有项目整合。另一方面,Vue 完全有能力驱动采用单文件组件Vue生态系统支持的库开发的复杂单页应用。

Vue.js 的目标是通过尽可能简单的 API 实现响应的数据绑定组合的视图组件

Vue.js安装

1、独立版本

我们可以在 Vue.js 的官网上直接下载 vue.min.js 并用 <script> 标签引入。

下载地址: https://vuejs.org/js/vue.min.js

2、使用CDN方法

以下推荐国外比较稳定的两个 CDN,国内还没发现哪一家比较好,目前还是建议下载到本地。

(1)在桌面建立一个 Vue.html文件, 并添加HTML页面的架构,然后引入 vue.js的CDN地址
<script src="https://unpkg.com/vue/dist/vue.js"></script>
(2)在Vue.html文件中插入一个id为firstVue的div标签
<div id="firstVue"></div>
(3)在Vue.html文件中插入如下js代码
<script>
    new Vue({
        el: "#firstVue",
    })
</script>

完整代码如下:

<!DOCTYPE html>
<html>
    <head>
        <title>Vue Demo</title>
        <script src="https://unpkg.com/vue/dist/vue.js"></script>
    </head>
    <body>
        <div id="firstVue"></div>
    <body>
    <script>
        new Vue({
            el: "#firstVue",
        })
    </script>
</html>

new Vue({})就是Vue创建的一个对象,可以理解成把<div id="firstVue></div>和这个标签里面包含的所有DOM都实例化成了一个JS对象 。

el是Vue的保留字,用来指定实例化的DOM的id号, #firstVue这句话就是id选择器,告诉Vue要实例化id="firstVue"的这个标签。

(4)在创建 vue实例的代码中加入下面数据声明:
data: {
    my_data: "hello world"
}
(5)在标签中通过{{}}来引用变量值:
<div id="firstVue">{{my_data}}</div>

双大括号的语法叫做mustache 语法,大括号里面的是作为变量形式出现的。

完整代码如下:

<!DOCTYPE html>
<html>
    <head>
        <title>Vue Demo</title>
        <script src="https://unpkg.com/vue/dist/vue.js"></script>
    </head>
    <body>
        <div id="firstVue">{{my_data}}</div>
    <body>
    <script>
        new Vue({
            el: "#firstVue",
            data: {
                my_data: "hello world"
            }
        })
    </script>
</html>

data参数用来绑定VUE实例的数据变量,每个不同变量之间用逗号分隔,上面我们绑定了自定义变量my_data,并赋初值"hello world"。

完成数据绑定工作,<div>标签里的 {{myData}} 数据会随着myVue实例里的my_Data数据的变动而变动,浏览器查看当前页面,会出现"hello world"字符串,说明数据绑定成功。

VUE这个框架的数据流向是单向的,数据绑定后的数据流向是从vue实例——>DOM文档

3、NPM方法

(1)国内使用npm速度较慢,使用淘宝定制的cnpm(gzip压缩支持)命令行工具代替默认的npm:
$ npm install -g cnpm --registry=https://registry.npm.taobao.org
$ npm config set registry https://registry.npm.taobao.org
(2)npm 版本需要大于 3.0,如果低于此版本需要升级它:
# 查看版本
$ npm -v
5.6.0

#升级 npm
$ cnpm install npm -g
(3)在用 Vue.js 构建大型应用时推荐使用 NPM 安装:
# 最新稳定版
$ cnpm install vue
(4)创建项目并安装运行

Vue.js 提供一个官方命令行工具,可用于快速搭建大型单页应用。

# 全局安装 vue-cli
$ cnpm install --global vue-cli

# 创建一个基于 webpack 模板的新项目
$ vue init webpack my-project

# 这里需要进行一些配置,默认回车即可
? Project name  my-project
? Project description  A Vue.js project
? Author  thd
? Vue build (Use arrow keys)
? Vue build   standalone
? Install vue-router?   Yes
? Use ESLint to lint your code?   Yes
? Pick an ESLint preset   Standard
? Set up unit tests   Yes
? Pick a test runner   jest
? Setup e2e tests with Nightwatch?   Yes

   vue-cli · Generated "my-project".
   
To get started:
  cd my-project
  npm run dev
 
#进入项目,安装并运行
  $ cd my-project
  $ cnpm run dev
  

成功执行以上命令后访问 http://localhost:8080/,输出结果如下所示:

第一个Vue项目.png

Vue.js 目录结构

1、项目目录

项目目录结构.png
  • build:项目构建(webpack)相关代码 ,用来保存文本pack的初始化配置。
  • config:配置目录,保存项目初始化配置,包括端口号等。我们初学可以使用默认的 。
  • node_modules:npm 加载的项目依赖模块
  • src: 这里是我们要开发的目录,基本上要做的事情都在这个目录里。
    • assets:放置一些图片,如logo等。
    • components:放置组件文件,可以不用。
    • router:前端路由配置
    • App.vue:项目入口文件,可以直接将组件写这里,而不使用 components 目录。
    • main.js:项目的核心文件。
  • static:静态资源目录,如图片、字体等。
  • test: 初始测试目录,可删除
  • index.html:首页入口文件,可以添加一些 meta 之类的信息。
  • package.json:项目配置文件
  • README.md:项目的说明文档,Markdown格式。

2、相关文件

(1)index.html

项目的入口页面,可以像普通的html文件一样引入文件和书写基本信息,添加meta标签等。

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1.0">
    <title>my-project</title>
  </head>
  <body>
    <div id="app"></div>
  </body>
</html>

(2)main.js

项目的入口文件,可以引入一些插件或静态资源,当然引入之前要先安装了该插件,在package.json文件中有记录。

import Vue from 'vue'
import App from './App'
import router from './router'

//设置为 false 表示阻止启动生产消息,常用作指令。
Vue.config.productionTip = false

new Vue({
  el: '#app',
  router,
  components: { App },
  template: '<App/>'
})
/*
el: '#app' ---表示将所有的组件都放在id为app的元素中
router---配置路由,路由允许我们通过不同的 URL 访问不同的内容
components: { App }---表示引入的文件,此处就是App.vue这个文件,也就是组件
template: '<App/>'---模板将会替换挂载的元素。挂载元素的内容都将被忽略,template的值表示要使用的组件名称,并将这个组件显示在html页面中,在组件中通过export default中的name来声明组件名称
*/
(3)App.vue

这是一个标准的vue组件,包含三个部分,一个是模板,一个是script,一个是样式。

<!-- 模板 -->
<template>
  <div id="app">
    <img src="./assets/logo.png">
    <router-view/>
  </div>
</template>

<!-- script -->
<script>
    export default {
      name: 'App'
    }
</script>

<!-- style -->
<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>

(4)修改第一个项目中显示的内容
  • 在components目录下定义一个Hello.vue组件文件,代码如下:
<template>
    <div>
        <h1>{{ msg }}</h1>
    </div>
</template>
<script>
    export default {
      name: 'hello',
      data () {
        return {
          msg: '欢迎来到Vue'
        }
      }
    }
</script>
  • 打开 APP.vue 文件,在模板template中添加一个Vue组件,并在script中将该组件导入,如下:
<template>
  <div id="app">
    <img src="./assets/logo.png">
    <!--添加的Vue组件-->
    <hello></hello>
  </div>
</template>

<script>
// 导入组件
import Hello from './components/Hello'
export default {
  name: 'App',
  components: {
    Hello
  }
}
</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>

启动项目,重新打开 http://localhost:8080/ ,显示效果如下:

第一个Vue项目1.png

Vue.js 构造器

每个 Vue 应用都需要通过实例化 Vue 来实现(创建Vue对象 new Vue({ })),而实例化时就要使用构造器。构造器格式如下:

var vm = new Vue({
  // 选项
})

构造器中可以有以下选项:

  • el:用来表示DOM元素的id
  • data:用于定义属性
  • methods:用于定义函数,可以通过return来返回函数值

在DOM元素中可以使用 {{ }} 来输出对象属性和函数返回值

示例:

<!DOCTYPE html>
<html>
    <head>
        <title>Vue Demo</title>
        <script src="https://unpkg.com/vue/dist/vue.js"></script>
    </head>
    
    <body>
        <div id="myDiv">
            <h2>site: {{site}}</h2>
            <h2>url: {{url}}</h2>
            <h2>{{details()}}</h2>
        </div>
    <body>
    
    <script>
        new Vue({
            el: "#myDiv",
            data: {
                site: "百度一下,你就知道",
                url: "http://www.baidu.com",
                desc: "全球最大的中文搜索引擎、致力于让网民更便捷地获取信息,找到所求。百度超过千亿的中文网页数据库,可以瞬间找到相关的搜索结果。"
            },
            methods: {
                details: function() {
                    return this.site + "--" + this.desc;
                }
            }
        })
    </script>
</html>

Vue.js 模板语法

Vue.js 使用了基于 HTML 的模版语法,允许开发者声明式地将 DOM 绑定至底层 Vue 实例的数据。

Vue.js 的核心是一个允许你采用简洁的模板语法来声明式的将数据渲染进 DOM 的系统。

结合响应系统,在应用状态改变时, Vue 能够智能地计算出重新渲染组件的最小代价并应用到 DOM 操作上。

1、插值

(1)文本

文本通常是作为数据绑定的值,数据绑定采用{{ }}

  • 文本插值
<div id="app">
  <p>{{ message }}</p>
</div>

<script>
    new Vue({
        el: '#app',
        data: {
            message: '数据'
        }
    })
</script>
  • v-html指令:读取HTML标签
<div id="app">
    <div v-html="message"></div>
</div>    
<script>
    new Vue({
      el: '#app',
      data: {
         message: '<h1>我的青春我做主</h1>'
      }
    }) 
</script>
(2)属性

HTML 属性中的值应使用 v-bind 指令,该指令用于双向数据绑定

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>Vue 属性</title>
        <script src="https://cdn.bootcss.com/vue/2.2.2/vue.min.js"></script>
    </head>
    <body>
        <div id="app">
            修改颜色:<input type="checkbox" v-model="change"><br><br>
            <div v-bind:class="{'newClass': change}">v-bind:class</div>
        </div>

    </body>
    <script>
        new Vue({
            el: '#app',
            data:{
                change: false    //false表示没有勾选,true表示勾选上
            }
        });
    </script>
    <style>
        .newClass{
            background: #444;
            color: #eee;
        }
    </style>
</html>
(3)表达式

Vue.js 都提供了完全的 JavaScript 表达式支持。

<div id="app">
    {{5+5}}<br>
    {{ ok ? 'YES' : 'NO' }}<br>
    {{ message.split('').reverse().join('') }}
</div>

<script>
    new Vue({
      el: '#app',
      data: {
        ok: true,
        message: 'HELLO',
      }
    })
</script>

2、指令

指令是带有 v- 前缀的特殊属性。 指令用于在表达式的值改变时,将某些行为应用到 DOM 上 。

(1)v-if

条件渲染指令,根据其后表达式的bool值进行判断是否渲染该元素。v-if指令只渲染其后表达式值为true的元素 。

<div id="app">
    <p v-if='seen'>看到我了</p>
</div>

<script type="text/javascript">
    new Vue({
        el: '#app', 
        data: {
            seen: true
        }
    })
</script>
(2)v-show

v-show指令是根据表达式的值来显示或者隐藏HTML元素。当v-show赋值为false时,元素被隐藏。

<div id="app">
    <p v-show='seen'>看到我了</p>
</div>

<script type="text/javascript">
    new Vue({
        el: '#app', 
        data: {
            seen: true
        }
    })
</script>

注意:注:v-show不支持<template>语法。

一般来说,v-if有更高的切换消耗,而v-show有更高的初始渲染消耗。因此,如果需要频繁的切换,则使用v-show较好;如果在运行时条件不大可能改变,则使用v-if较好。

(3)v-else

v-else就是JavaScript中的else的意思,它必须跟着v-if或者v-show使用。

<div id="app">
    <P v-if="ok">我是对的</P>
    <p v-else="ok">我是错的</p>
</div>
<script type="text/javascript">
    var exampleVM2 = new Vue({
        el: '#app',
        data: {
            ok: false
        }
    })
</script>
(4)v-else-if

v-else-if 在 2.1.0 新增,顾名思义,用作 v-if 的 else-if 块,可以链式的多次使用

<div id="app">
    <div v-if="type === 'A'">  A  </div>
    <div v-else-if="type === 'B'">  B  </div>
    <div v-else-if="type === 'C'">  C  </div>
    <div v-else>  Not A/B/C  </div>
</div>

<script>
    new Vue({
        el: '#app',
        data: {
            type: 'C'
        }
    })
</script>
(5)v-bind

v-bind指令用于响应更新HTML特性,将一个或者多个attribute,或者一个组件prop动态绑定到表达式

<div id="app">
    <a v-bind:href="url">百度一下</a>
</div>

<script type="text/javascript">
    new Vue({
        el: '#app', 
        data: {
            url: 'https://www.baidu.com'
        }
    })  
</script>
  • v-bind缩写
<!-- 完整语法 -->
<a v-bind:href="url"></a>
<!-- 缩写 -->
<a :href="url"></a>
  • 给元素绑定href时可以也绑一个target,新窗口打开页面。
<script>
    new Vue({
      el: '#app',
      data: {
        url: 'http://www.runoob.com',
        target:'_blank'
      }
    })
</script>
  • 在绑定class或者style时,支持其他类型的值,如数组或对象。
<div id="app">
    <div v-bind:class="[classA,{classB:isB,classC:isC}]">hahaha</div>
</div>

<script type="text/javascript">
    new Vue({
        el: '#app',
        data: {
            classA: 'A',
            isB: false,
            isC: true
        }
    })
</script>

<style type="text/css">
    .A {
        color: red;
    }
    .classC {
        font-size: 50px;
    }
</style>
(6)v-model

v-model指令用来在input、select、text、checkbox、radio等表单控件元素上创建双向数据绑定的。根据控件类型v-model自动选取正确的方法更新元素 。

<div id="app">
    <input type="text" v-model='msg' />
    <p>{{msg}}</p>
</div>

<script type="text/javascript">
    new Vue({
    el: '#app',
        data: {
            msg: 'hello'
        }
    })
</script>
(7)v-on

v-on指令用于绑定事件监听器。事件类型由参数指定。

<div id="app">
    <button v-on:click='reverse'>点击按钮</button><br />
    <p>{{msg}}</p>
</div>

    
<script type="text/javascript">
    new Vue({
        el: '#app', 
        data: {
            msg: 'hello'
        },
        methods: {
            reverse: function() {
                this.msg = this.msg.split('').reverse().join('')
            }
        }       
    })  
</script>
  • v-on缩写
<!-- 完整语法 -->
<a v-on:click="doSomething"></a>
<!-- 缩写 -->
<a @click="doSomething"></a>
(8)v-for

v-for指令用于循环遍历显示一个数组或者对象 。用法形如 v-for="item in items", items为数组或对象,item为数组中的每一项元素

  • v-for遍历整数
<div id="app">
  <ul>
    <li v-for="n in 10">
        {{ n }}
    </li>
  </ul>
</div>

<script>
    new Vue({
      el: '#app'
    })
</script>       
  • v-for遍历数组
<div id="app">
    <ol>
        <li v-for='site in sites'>
            {{site.name}}
        </li>
    </ol>
</div>

<script>
    new Vue({
        el: '#app',
        data: {
            sites: [
                {name: 'baidu'},
                {name: 'sina'},
                {name: 'qq'}
            ]
        }
    })
</script>

/*注意:数组也可以定义在v-for的属性值中*/
<ul>
    <li v-for='n in [1,3,5,7]'>
        {{ n }}
    </li>
</ul>
  • v-for遍历数组带索引
<div>
    <ul>
        <li v-for='(site, index) in sites'>
            {{index}} : {{site.name}}
        </li>
    </ul>
</div>
<script>
    new Vue({
        el: '#app',
        data: {
            sites: [
                {name: 'baidu'},
                {name: 'sina'},
                {name: 'qq'}
            ]
        }
    })
</script>
  • v-for遍历对象
<div id='#app'>
    <ul>
        <li v-for='value in website'>
            {{value}}
        </li>
    </ul>
</div>

<script>
    new Vue({
        el: '#app',
        data: {
            website: {
                name: '百度一下',
                url: 'http://www.baidu.com',
                desc: '全球最大的中文搜索引擎、致力于让网民更便捷地获取信息,找到所求。百度超过千亿的                      中文网页数据库,可以瞬间找到相关的搜索结果。'
            }
        }
    })
</script>
  • v-for遍历对象key-value
<div>
    <ul>
        <li v-for='(value, key) in website'>
            {{key}} : {{value}}
        </li>
    </ul>
</div>
<script>
    new Vue({
        el: '#app',
        data: {
            website: {
                name: '百度一下',
                url: 'http://www.baidu.com',
                desc: '全球最大的中文搜索引擎、致力于让网民更便捷地获取信息,找到所求。百度超过千亿的                      中文网页数据库,可以瞬间找到相关的搜索结果。'
            }
        }
    })
</script>
  • v-for遍历对象key-value 带索引
<div>
    <ul>
        <li v-for='(value, key, index) in website'>
            {{index}} : {{key}} : {{value}} 
        </li>
    </ul>
</div>
<script>
    new Vue({
        el: '#app',
        data: {
            website: {
                name: '百度一下',
                url: 'http://www.baidu.com',
                desc: '全球最大的中文搜索引擎、致力于让网民更便捷地获取信息,找到所求。百度超过千亿的                      中文网页数据库,可以瞬间找到相关的搜索结果。'
            }
        }
    })
</script>

Vue.js构造器(2)

构造器的格式如下:

<script>
    var vm = new Vue({
        el: '#id',
        data: {
            //数据
        },
        methods: {
            //函数
        },
        computed: {
            //计算属性
        },
        watch: {
            //监听属性
        }
    })
</script>

1、计算属性

计算属性关键词: computed。计算属性在处理一些复杂逻辑时是很有用的。

(1) computed getter

<div id="app">
  <p>原始字符串: {{ msg }}</p>
  <p>计算后反转字符串: {{ reversedMsg }}</p>
</div>
<script>
    new Vue({
        el: '#app',
        data: {
            msg: 'Hello!'
        },
        computed: {
            reversedMsg: function () {
                return this.msg.split('').reverse().join('')
            }
        }
    })
</script>

我们可以使用 methods 来替代 computed,效果上两个都是一样的,但是 computed 是基于它的依赖缓存,只有相关依赖发生改变时才会重新取值。而使用 methods ,在重新渲染的时候,函数总会重新调用执行。

可以说使用 computed 性能会更好,但是如果你不希望缓存,你可以使用 methods 属性。

(2)computed setter

<script>
    var vm = new Vue({
        el: '#app',
        data: {
            name: '百度',
            url: 'http://www.baidu.com'
        },
        computed: {
            site: {
                // getter
                get: function () {
                    return this.name + ' ' + this.url
                },
                // setter
                set: function (newValue) {
                    var names = newValue.split(' ')
                    this.name = names[0]
                    this.url = names[names.length - 1]
                }
            }
        }   
    })
    // 调用setter, vm.name 和 vm.url 也会被对应更新
    vm.site = '新浪新闻 http://www.sina.com';
    document.write('name: ' + vm.name);
    document.write('<br>');
    document.write('url: ' + vm.url);
</script>

2、监听属性

监听属性关键字:watch,可以通过 watch 来响应数据的变化

<div id="computed_props">
    分 : <input type="text" v-model="minutes"> 
    秒 : <input type="text" v-model="seconds">
</div>

<script type="text/javascript">
    var vm = new Vue({
        el: '#computed_props',
        data: {
            minutes: 0,
            seconds: 0
        },
        methods: {},
        computed: {},
        watch: {
            minutes: function(val) {
                this.minutes = val;
                this.seconds = val * 60;
            },
            seconds: function(val) {
                this.minutes = val / 60;
                this.seconds = val;
            }
        }
    });
</script>

Vue.js 样式绑定

class 与 style 是 HTML 元素的属性,用于设置元素的样式,我们可以用 v-bind 来设置样式属性。

Vue.js v-bind 在处理 class 和 style 时, 专门增强了它。表达式的结果类型除了字符串之外,还可以是对象或数组。

1、绑定内联样式style

  • 可以通过 v-bind:style 直接设置样式
<div id="app">
    <div v-bind:style='{ background: mycolor, fontSize: mysize + "px"}'>我是一个div</div>
</div>

<script type="text/javascript">
    new Vue({
        el: '#app',
        data: {
            mycolor: 'pink',
            mysize: 30              
        }
    })
</script>
  • 也可以直接绑定到一个样式对象,让模板更清晰
<div id="app">
    <div v-bind:style='mystyle'>我是一个div</div>
</div>

<script type="text/javascript">
    new Vue({
        el: '#app',
        data: {
            mystyle: {
                background: 'pink',
                fontSize: '30px'    
            }
        }
    })
</script>
  • 可以使用数组将多个样式对象应用到一个元素上
<div id="app">
    <div v-bind:style='[back, font]'>我是一个div</div>
</div>

<script type="text/javascript">
    new Vue({
        el: '#app',
        data: {
            back: {
                background: 'pink',
                color: 'blue'   
            },
            font: {
                fontSize: '30px',
                fontWeight: 'bold'  
            }
        }
    })
</script>

2、绑定属性class

  • 可以通过v-bind:class设置样式
<div id="app">
    <div v-bind:class="{classA: isA }"></div>
</div>
<script>
    new Vue({
      el: '#app',
      data: {
        isA: true
      }
    })
</script>
<style>
    .classA {
        width: 100px;
        height: 100px;
        background: green;
    }
</style>
  • 可以传入多个属性来改变样式
<div class="static"
     v-bind:class="{ classA: isA, classB: isB }">
</div>
<script>
    new Vue({
      el: '#app',
      data: {
        isA: true,
        isB: true
      }
    })
</script>
<style>
    .classA {
        width: 100px;
        height: 100px;
        background: green;
    }
    .classB {
        background: red;
    }
</style>
  • 可以直接绑定数据里的一个对象
<div class="static"
     v-bind:class="object">
</div>
<script>
    new Vue({
      el: '#app',
      data: {
          object: {
              classA: true,
              classB: true
          }
      }
    })
</script>
<style>
    .classA {
        width: 100px;
        height: 100px;
        background: green;
    }
    .classB {
        background: red;
    }
</style>
  • 可以使用数组绑定多个样式
<div id="app">
    <div v-bind:class="[classA, classB]"></div>
</div>
<script>
new Vue({
  el: '#app',
  data: {
    classA: 'A',
    classB: 'B'
  }
})
</script>
<style>
.A {
    width: 100px;
    height: 100px;
    background: green;
}
.B {
    background: red;
}
  • 可以使用三元表达式来切换列表中的 class
<div id="app">
    <div v-bind:class="[isA ? aClass : bClass]"></div>
</div>
<script>
    new Vue({
        el: '#app',
        data: {
            isA: true,
            aClass: 'A',
            bClass: 'B'
        }
    })
</script>
<style>
.A {
    width: 100px;
    height: 100px;
    background: red;
}
.B {
    width: 100px;
    height: 100px;
    background: green;
}
</style>

Vue.js 表单

可以使用 v-model 指令在表单控件元素上创建双向数据绑定。 v-model 会根据控件类型自动选取正确的方法来更新元素。

v-model.png
  • v-model会忽略所有表单元素的 value、checked、selected 特性的初始值而总是将 Vue 实例(new Vue({}))的数据(data)作为数据来源。你应该通过 JavaScript 在组件的 data选项中声明初始值。

  • 对于需要使用输入法 (如中文、日文、韩文等) 的语言,你会发现 v-model不会在输入法组合文字过程中得到更新。如果你也想处理这个过程,请使用 input 事件。

1、input

<input v-model="message" placeholder="edit me">
<p>Message is: {{ message }}</p>

2、textarea

在文本区域插值 (<textarea></textarea>) 并不会生效,应用 v-model 来代替。

<textarea v-model="message" placeholder="add multiple lines"></textarea><br>
<span>Multiline message is:</span>
<p>{{ message }}</p>

3、checkbox

  • 单个复选框,绑定到布尔值:
<input type="checkbox" id="checkbox" v-model="checked">
<label for="checkbox">{{ checked }}</label>
  • 多个复选框,绑定到同一个数组:
<div id='app'>
  <input type="checkbox" id="zhang3" value="张三" v-model="checkedNames">
  <label for="zhang3">张三</label>
  <input type="checkbox" id="li4" value="李四" v-model="checkedNames">
  <label for="li4">李四</label>
  <input type="checkbox" id="wang5" value="王五" v-model="checkedNames">
  <label for="wang5">王五</label>
  <br>
  <span>Checked names: {{ checkedNames }}</span>
</div>

<script>
    new Vue({
      el: '#app',
      data: {
        checkedNames: []
      }
    })
</script>

4、radio

<div id="app">
    <label> <input type='radio' name="single" value="H5" v-model='choice' /> H5 </label>
    <label> <input type='radio' name="single" value="嵌入式" v-model='choice' /> 嵌入式 </label>
    <label> <input type='radio' name="single" value="java" v-model='choice' /> java </label><br />
    <span>{{choice}}</span>
</div>
<script>
    new Vue({
        el: '#app',
        data: {
            choice: []
        }
    })
</script>

5、select

  • 单选时
<div id="app">
  <select v-model="selected">
    <option disabled value="">请选择</option>
    <option>A</option>
    <option>B</option>
    <option>C</option>
  </select>
  <span>Selected: {{ selected }}</span>
</div>
<script>
    new Vue({
      el: '#app',
      data: {
        selected: ''
      }
    })
</script>
  • 多选时(绑定到一个数组)
<div id="app">
  <select v-model="selected" multiple style="width: 50px;">
    <option>A</option>
    <option>B</option>
    <option>C</option>
  </select>
  <br>
  <span>Selected: {{ selected }}</span>
</div>
<script>
    new Vue({
      el: '#app',
      data: {
        selected: []
      }
    })
</script>
  • 用v-for渲染的动态选项
<div id='app'>
    <select v-model="selected">
        <option v-for="option in options" v-bind:value="option.value">
            {{ option.text }}
        </option>
    </select>
    <span>Selected: {{ selected }}</span>
</div>

<script>
     new Vue({
      el: '#app',
      data: {
        selected: 'A',
        options: [
          { text: 'One', value: 'A' },
          { text: 'Two', value: 'B' },
          { text: 'Three', value: 'C' }
        ]
      }
    })   
</script>

6、修饰符

(1).lazy:在默认情况下,v-model在每次 input事件触发后将输入框的值与数据进行同步 。你可以添加 lazy 修饰符,从而转变为使用 change事件进行同步:

<div id="app">
    <input type="text" v-model.lazy='msg'/><br />
    <p>{{msg}}</p>
</div>
<script type="text/javascript">
    new Vue({
        el: "#app",
        data: {
            msg: '你好'
        }
    })
</script>

(2).number:如果想自动将用户的输入值转为数值类型,可以给 v-model 添加 number修饰符 。这通常很有用,因为即使在 type="number" 时,HTML 输入元素的值也总会返回字符串。

<div id="app">
    <input type="text" v-model.number="message">
    <p>{{message}}</p>
    <input @click="assay" type="button" value="获取"> 
</div>
<script>
new Vue({
    el: '#app',
    data: {
        message: ""
    },
    methods: {
        assay () {
            console.log(typeof this.message);
        }
    }
})
</script>

需要注意的是:number修饰符并不是限制用户的输入,而是将用户输入的数据尝试绑定为 js 中的 number类型 。如果用户输入的是数字,那么会得到一个number类型的值,而如果用户输入的不是数字,这个指令并不会产生任何效果。

(3).trim:如果要自动过滤用户输入的首尾空格,可以添加 trim 修饰符到 v-model 上过滤输入

<div id="app">
    <input type="text" v-model.trim="message">
    <p>{{message}}</p>
    <input @click="assay" type="button" value="获取"> 
</div>
<script>
new Vue({
    el: '#app',
    data: {
        message: ""
    },
    methods: {
        assay () {
            console.log(this.message);
        }
    }
})
</script>

Vue.js 组件

组件(Component)是 Vue.js 最强大的功能之一。

组件可以扩展 HTML 元素,封装可重用的代码。

组件相当于新建一个属于自己的标签。但是这个标签的功能很强大,可以有很多特殊的功能。

组件系统让我们可以用独立可复用的小组件来构建大型应用,几乎任意类型的应用的界面都可以抽象为一个组件树:

components.png

1、全局组件

全局注册的组件可以用在任何新创建的 Vue 根实例 (new Vue) 的模板中 ,需要注意的是:全局组件必须写在Vue实例创建之前,才在该根元素下面生效

(1)注册全局组件语法格式 如下:定义在script中,new Vue({ })之前

<script>
    Vue.component(tagName, options)

    参数说明:
    tagName:组件名称
    options:配置选项
</script>

(2)调用组件

<tagName></tagName>

示例:

<div id="app">
    <!-- 3、使用组件 -->
    <my-component></my-component>
</div>
 
<script>
    // 2、注册全局组件
    Vue.component('my-component', {
      template: '<h1>自定义组件!</h1>'
    })
    // 1、创建根实例
    new Vue({
      el: '#app'
    })
</script>

2、局部组件

如果不需要全局注册,或者是让组件使用在其它组件内,可以用选项对象的components属性实现局部注册

<div id="app">
    <!-- 3、my-componen只能在#app下使用 -->
    <my-component></my-component>
</div>
 
<script>
    //1、创建局部组件
    var Child = {
      template: '<h1>自定义组件!</h1>'
    }

    // 创建根实例
    new Vue({   
      el: '#app',
      components: {
          //2、在根实例中注册局部组件
         'my-component': Child
      }
    })
</script>

3、组件中的属性

关于组件中的其他属性,可以和实例中的一样,但是data属性必须是一个函数。

(1)全局组件

<div id="app">
  <my-component></my-component>
</div>
<script>
    Vue.component("my-component",{
        template:"<button @click='add'>全局组件:{{m}}</button>",
        data:function(){
            return {
                m:10
            }
        },
        methods:{
            add:function(){
                this.m++
            }
        }
     });
     new Vue({
        el:"#app"
     })
</script>

(2)局部组件

<div id="app">
  <child-component></child-component>
</div>
<script>
  var child={
    template:"<button @click='add'>我是局部组件:{{m}}</button>",
    data:function(){
        return {
            m:1
        }
    },
    methods:{
      add:function(){
        this.m++
      }
    }
  };
  new Vue({
    el: "#app",
    components:{
      "child-component":child
    }
  })
</script>

4、prop

prop 是父组件用来传递数据的一个自定义属性。

父组件的数据需要通过 props 把数据传给子组件,子组件需要显式地用 props 选项声明 "prop"

<div id="app">
    <child message="hello!"></child>
</div>
 
<script>
    // 注册全局组件
    Vue.component('child', {
      // 声明 props
      props: ['message'],
      template: '<span>{{ message }}</span>'
    })
    // 创建根实例
    new Vue({
      el: '#app'
    })
</script>

Vue.js 路由

有时候,我们在用vue的时候会有这样的需求,比如一个管理系统,点了左边的菜单栏,右边跳转到一个新的页面中,而且刷新的时候还会停留在原来打开的页面。

又或者,一个页面中几个不同的画面来回点击切换,这两种情况都可以用vue router路由来解决

<!-- 导入js文件 -->
<script src="https://cdn.bootcss.com/vue-router/2.4.0/vue-router.js"></script>

<div id="app">
    <div>
    <!--
        使用router-link组件来导航,
        通过 to属性就是指向某个具体的链接,链接的内容会被渲染到router-view标签中
        router-link会被渲染成a标签,
        例如第一个会变成<a href="#/first">第一个页面</a>,前面加了个#
    -->
        <router-link to="/first">第1个页面</router-link>
        <router-link to="/second">第2个页面</router-link>
        <router-link to="/third">第3个页面</router-link>
    </div>
            
    <!-- 路由匹配到的组件将渲染在这里 -->
    <router-view></router-view>
</div>

<script type="text/javascript">
    //1、申明三个模板(定义路由组件)
    var first = { template: '<p>this is first page</p>' };
    var second = { template: '<p>this is second page</p>' };
    var third = { template: '<p>this is third page</p>' };
        
    //2、定义路由,每个路由应该映射一个组件
    //其中,component属性是通过 Vue.extend()创建的组件构造器,
    //或者,只是一个组件配置对象。
    var routes = [
        { path: '/first', component: first },
        { path: '/second', component: second },
        { path: '/third', component: third }
    ];
        
    //3、创建VueRouter实例
    var router = new VueRouter({
        routes  //(缩写)相当于routes: routes
    });
        
    /*4、创建和挂载根实例
     * 通过router配置参数注入路由,给vue对象绑定路由
     * .$mount("#app")手动挂载,用来延迟挂载,跟
     *  const app = new Vue({
     *   el:"#app"
     *   router
     *  });
     * 效果是一样的
     */
    const app = new Vue({
        router
    }).$mount("#app");
</script>

运行步骤:

  1. 当router-link对应的标签被点击时,比如此时点击第二个,to的值是/second,那么实际的地址就是当前页面地址+#/second。
  2. Vue会找到当前vue实例的路由里的routes里面path为/second的路由。
  3. 会将找到的这一行记录的模板component渲染到router-view里面。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,491评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,856评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,745评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,196评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,073评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,112评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,531评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,215评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,485评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,578评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,356评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,215评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,583评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,898评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,174评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,497评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,697评论 2 335

推荐阅读更多精彩内容

  • 1.安装 可以简单地在页面引入Vue.js作为独立版本,Vue即被注册为全局变量,可以在页面使用了。 如果希望搭建...
    Awey阅读 10,971评论 4 129
  • 这篇笔记主要包含 Vue 2 不同于 Vue 1 或者特有的内容,还有我对于 Vue 1.0 印象不深的内容。关于...
    云之外阅读 5,040评论 0 29
  • Vue 实例 属性和方法 每个 Vue 实例都会代理其 data 对象里所有的属性:var data = { a:...
    云之外阅读 2,182评论 0 6
  • 阿丁: 像猪一样地活着 就会像猪一样地死去 君子终日乾乾 要夕惕若历 其实 多数人像猪一样的活着 小心 ...
    王天神阅读 352评论 0 4
  • 10/31武丽娟感恩日志 感恩叶老师信任,我的坚持终于得到认可,谢谢自己的坚持! 感恩承诺老师精彩点评,虽然是点评...
    花布鱼阅读 143评论 0 0