vue.js 官方文档(基础)

什么dom

(Document Object Model)
Dom分为3个类型

  • 核心 DOM - 针对任何结构化文档的标准模型
  • XML DOM - 针对 XML 文档的标准模型
  • HTML DOM - 针对 HTML 文档的标准模型
HTML DOM

HTML DOM 定义了所有 HTML 元素的对象和属性,以及访问它们的方法。

什么是vue.js的双向绑定

image.png
View是HTML显示界面
ViewModel是业务逻辑层

(一切js可视化业务逻辑,比如表单按钮提交,自定义事件的注册和处理逻辑都在viewmodel里面负责监控两边的数据)

Model数据层对数据的处理(比如增删改查)

MVVM是MODEL-VIEW-VIEWMODEL模型的缩写。MVVM是一种很设计模式。MODEL层代表数据模型,也可以在model中定义
数据修改和操作的业务逻辑;VIEW代表的是UI组件,它负责将数据模型转化为ui组件展示出来,VIEWModel是一个同步viewmodel的对象
在MVVM架构上,view和model并没有直接联系,而是通过viewmodel进行交互,model和viewmodel之间的交互是双向的,因此view的数据变化会同步到MODEL中,而MODEL数据的变化也会立即反应到view上
viewmodel通过双向数据绑定把view和model层连接起来,而view和model之间的同步工作完全是自动的,无需人为干涉。因此开发者只需要关注业务逻辑,不需要手动操作DOM,不需要关注数据状态的同步问题,复杂的数据维护完全由MVVM来统一管理

条件与循环
<div id="app">
        <p>{{message}}</p>
    </div>
 var app = new Vue({
        el: '#app',
        data: {
            todos: [
                { text: '学习java'},
                { text: '学习Vue'},
                { text: '整个牛项目'}
            ]
        }
    })

处理用户信息

v-on

<div id="app">
        <p>{{message}}</p>
        <button v-on:click="reverseMessage"></button>
 </div>
var app = new Vue({
        el: '#app',
        data: {
            message: 'Hello Vue.js!'
        },
        methods: {
            reverseMessage: function() {
                this.message = this.message.split('').reverse().join("")
            }
        }
    })
v-model
<div id="app">
        <p>{{message}}</p>
        <input v-model="message">

    </div>
var app = new Vue({
        el: '#app',
        data: {
            message: 'Hello Vue.js!'
        }
    })
组件化应用实例
<div id="app">
        <ol>
            <!-- 创建一个 todo-item 组件的实例 -->
            <todo-item></todo-item>
          </ol>
    </div>
 Vue.component('todo-item', {
     template: '<li>这是个待办项</li>'
    })

    var app = new Vue({
     el: '#app'
    })
v-bind
<div id="app">
        <todo-item
         v-for="item in groceryList"
         v-bind:todo ='item'
         v-bind:key = 'item.id'
        >
        </todo-item>
    </div>
 Vue.component("todo-item",{
        props:["todo"],
        template: "<li>{{todo.text}}</li>"

    })
    var app = new Vue({
        el: "#app",
        data: {
            groceryList: [
                {id: 1, text: '蔬菜'},
                {id: 2, text: '猪肉'},
                {id: 3, text: '牛肉'}
            ]
        }
    })

实例生命周期钩子

created

用来在一个实例被创建之后执行代码:

new Vue({
  data: {
    a: 1
  },
  created: function () {
    // `this` 指向 vm 实例
    console.log('a is: ' + this.a)
  }
})
// => "a is: 1"

生命周期图示

image.png

模板语法

原始Html文件
<div id="app">
        <p>Using mustaches: {{ rawHtml }}</p>
        <p>Using mustaches directive: <span v-html="rawHtml"></span></p>

    </div>
 var app = new Vue({
        el: "#app",
        data : {
            rawHtml: '<span style="color: red">this is should be red</span>'
        }
    })
v-bind
<div id="app">
        <div v-bind:class='color'>test</div>
    </div>
var app = new Vue({
        el: "#app",
        data : {
            color: 'red'
        }
    })
支持javascript表达式
{{ number + 1 }}

{{ ok ? 'YES' : 'NO' }}

{{ message.split('').reverse().join('') }}

<div v-bind:id="'list-' + id"></div>

只支持单个表达式 不支持下面的表达式

<!-- 这是语句,不是表达式 -->
{{ var a = 1 }}

<!-- 流控制也不会生效,请使用三元表达式 -->
{{ if (ok) { return message } }}

指令

指令 attribute 的值预期是单个 JavaScript 表达式

参数

<a v-bind:href="url">...</a>

又如

<a v-on:click="doSomething">...</a>
动态参数
<a v-bind:[attributeName]="url"> ... </a>

如果你的 Vue 实例有一个 data 属性 attributeName,其值为 "href",那么这个绑定将等价于 v-bind:href。

修饰符

修饰符 (modifier) 是以半角句号 . 指明的特殊后缀,用于指出一个指令应该以特殊方式绑定。

<form v-on:submit.prevent="onSubmit">...</form>
缩写
<!-- 完整语法 -->
<a v-bind:href="url">...</a>

<!-- 缩写 -->
<a :href="url">...</a>
<!-- 完整语法 -->
<a v-on:click="doSomething">...</a>

<!-- 缩写 -->
<a @click="doSomething">...</a>

计算属性和侦听器

计算属性

基本用法
<div id="app">
        <p>Original message: "{{message}}"</p>
        <p>Computed Original message : "{{ reversedMessage}}"</p>
    </div>
var app = new Vue({
        el: "#app",
        data: {
            message: 'Hello'
        },
        computed:{
            reversedMessage: function(){
                return this.message.split('').reverse().join('')
            }
        }
    })
计算属性vs方法
// 在组件中
methods: {
  reversedMessage: function () {
    return this.message.split('').reverse().join('')
  }
}

我们可以将同一函数定义为一个方法而不是一个计算属性。两种方式的最终结果确实是完全相同的。
然而,不同的是计算属性是基于它们的响应式依赖进行缓存的。只在相关响应式依赖发生改变时它们才会重新求值。这就意味着只要 message 还没有发生改变,多次访问 reversedMessage 计算属性会立即返回之前的计算结果,而不必再次执行函数。
相比之下,每当触发重新渲染时,调用方法将总会再次执行函数。

侦听器

当采用异步操作或者开销更大的时候采用侦听器可以方便我的使用

Class和style绑定

绑定class

对象语法
 <div
            class="static"
            v-bind:class="{ 'active': isActive, 'text-danger': hasError }"
        ></div>
var app = new Vue({
        el: "#app",
        data: {
        isActive: true,
        hasError: true
        }
    })

也可以这样绑定class样式

<div v-bind:class="classObject"></div>
var app = new Vue({
        el: "#app",
        data: {
        classObject: {
            'active': true,
            'text-danger': false
        }
        }
    })
通过数组语法进行命名
<div v-bind:class='[activeClass, errorClass]'></div>
var app = new Vue({
        el: "#app",
        data: {
        activeClass: 'active',
        errorClass: 'isLoading',
        }
    })
也可以应用在组件上
<my-component v-bind:class={active:isActive}></my-component>
Vue.component('my-component',{
        template: '<p class="foo bar">Hi</p>'
    })
    var app = new Vue({
        el: "#app",
        data: {
        isActive:true
        }
    })

绑定内联样式

对象语法
<div v-bind:style="{ color: activeColor, fontSize: fontSize + 'px' }"></div>
var app = new Vue({
        el: "#app",
        data: {
        activeColor: 'red',
        fontSize: 50
        }
    })

也可以这样写

<div v-bind:style= 'styleObject'>Hi</div>
var app = new Vue({
        el: "#app",
        data: {
            styleObject: {
                'color': 'red',
                'font-size': '50px'
            }
        }
    })
多重值
<div :style="{ display: ['-webkit-box', '-ms-flexbox', 'flex'] }"></div>

它会根据浏览器中渲染的最后一个数组来实现内容

条件渲染

v-if v-else

<div v-if="Math.random() > 0.5">
  Now you see me
</div>
<div v-else>
  Now you don't
</div>

v-else-if
<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>

利用key管理可重复使用的元素

<template v-if="loginType === 'username'">
  <label>Username</label>
  <input placeholder="Enter your username">
</template>
<template v-else>
  <label>Email</label>
  <input placeholder="Enter your email address">
</template>

那么在上面的代码中切换 loginType 将不会清除用户已经输入的内容。因为两个模板使用了相同的元素,<input> 不会被替换掉——仅仅是替换了它的 placeholder

<template v-if="loginType === 'username'">
  <label>Username</label>
  <input placeholder="Enter your username" key="username-input">
</template>
<template v-else>
  <label>Email</label>
  <input placeholder="Enter your email address" key="email-input">
</template>

所以 Vue 为你提供了一种方式来表达“这两个元素是完全独立的,不要复用它们”。只需添加一个具有唯一值的 key 属性即可:

v-if和v-show的区别

v­if:
实时渲染:页面显示就渲染,不显示。我就给你移除
v­show:
v­show的元素永远存在也页面中,只是改变了css的display的属性

列表渲染

用v-for把一个数组对应一个元素

我们可以用 v-for 指令基于一个数组来渲染一个列表。v-for 指令需要使用 item in items 形式的特殊语法,其中 items 是源数据数组,而 item 则是被迭代的数组元素的别名。

<div id="app">
        <li v-for="item in items" >
            {{ item.message}}
        </li>
    </div>
var app = new Vue({
        el: "#app",
        data: {
           items: [
               {message: 'Foo'},
               {message: 'Bar'}
           ]
        }
    })

也可以这样写

<div id="app">
        <li v-for="(item,index) in items" >
           {{parentMessage}}-{{index}}-{{ item.message}}
        </li>
    </div>
 var app = new Vue({
        el: "#app",
        data: {
        parentMessage: 'Parent',
           items: [
               {message: 'Foo'},
               {message: 'Bar'}
           ]
        }
    })
在v-for里面使用对象
<div id="app">
        <li v-for="value in Object" >
           {{value}}
        </li>
    </div>
var app = new Vue({
        el: "#app",
        data: {
           Object:{
               title: 'Foo',
               message: 'Bar'
            }
        }
    })
也可以提供第二个参数键名还有第三个参数索引名字
<div id="app">
        <li v-for="(value,name,index) in Object" >
           {{index}}:{{name}}:{{value}}
        </li>
    </div>
 var app = new Vue({
        el: "#app",
        data: {
           Object:{
               title: 'Foo',
               message: 'Bar'
            }
        }
    })

方法和事件

<div id="app">
        点击次数: {{count}}
        <button @click='handle()'>点我每次加一</button>
        <button @click='handle(8)'>点我每次加8</button>

    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
    <script>
        var app = new Vue({
            el: '#app',
            data: {
                count: 0
            },
            methods: {
                handle: function (count) {
                    // console.log(count)
                    count = count || 1;
                    this.count += count;
                }
            }
        })
    </script>
image.png

如果方法中带有参数,但是你没有加括号,默认传原生事件对象event

vue.js 的修饰符号

在vue中传入event对象用 $event
向上冒泡
stop:阻止单击事件向上冒泡
prevent::提交事件并且不重载页面
self:只是作用在元素本身而非子元素的时候调用
once: 只执行一次的方法

可以监听键盘事件:
<input @keyup.13 ="submitMe"> ——­指定的keyCode
vueJS为我们提供了:
.enter
.tab
.delete

<div id="app">
        <!-- 向上冒泡 -->
        stop用法: <br>
        <div @click.self='divclick' style="height: 100px;width: 100px;background-color: red;">
            <button @click='btnclick'>点击</button>
        </div>
        <hr>
        prevent的用法:
        每次提交表单都会重载页面
        <form action="" @submit.prevent='hangle'>
            <button type='submit'>提交表单</button>
        </form>
        <hr>
        once: <br>
        <button @click='onceMethod'>执行无限次</button>
        <button @click.once='onceMethod'>只执行一次</button>
        <hr>
        监听键盘事件:
        <br>
        <input @keyup.13='submitMe'> ---keyCode
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
    <script>
        var app = new Vue({
            el: '#app',
            data: {
                count: 0
            },
            methods: {
                divclick: function () {
                    alert('div被点击了')
                },
                btnclick: function () {
                    alert('button被点击了')

                },
                hangle: function () {
                    alert('我不重载,页面也不刷新了')
                },
                onceMethod: function () {
                    alert('执行一次method')
                },
                submitMe: function () {
                    alert('您按下了enter键')
                }
            }
        })
    </script>

表单输入绑定

文本input

 <input v-model="message" placeholder="edit me">
 <p>Message is: {{ message }}</p>
new Vue({
  el: '#app',
  data: {
      message: ''
  }
})

多行文本textarea同理

复选框

单个复选框

单个复选框绑定布尔值

<input type="checkbox" v-model="checked">
<label for="checkbox">{{ checked }}</label>
new Vue({
  el: '#app',
  data: {
      checked: ''
  }
})
单选框同理
<input type="radio" v-model="checked" value="John">
        <label for="John">John</label>
        <input type="radio" v-model="checked" value="Jack">
        <label for="Jack">Jack</label>
        <label for="checkbox">{{ checked }}</label>
new Vue({
  el: '#app',
  data: {
      checked: []
  }
})

选择框

<div id="app">
        <select v-model="selected" >
            <option >A</option>
            <option >B</option>
            <option >C</option>

        </select>
        <span>Selected: {{ selected }}</span>
      </div>
new Vue({
  el: '#app',
  data: {
      selected: ''
  }
})
值绑定
复选框
<input
            type="checkbox"
            v-model="toggle"
            true-value="yes"
            false-value="no"
            >
        <span>Selected: {{ toggle }}</span>
new Vue({
  el: '#app',
  data: {
      toggle: ''
  }
})
单选按钮
<div id="app">
        <input type="radio" v-model="pick" v-bind:value="a">
        {{pick}}
      </div>
new Vue({
  el: '#app',
  data: {
      pick: '',
      a: 'a'
  }
})

修饰符

.lazy

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

<input v-model.lazy="msg">
{{msg}}
.number
<input v-model.number="msg" type="number">
        {{msg}}
new Vue({
  el: '#app',
  data: {
      msg: ''
  }
})
.trim
<input v-model.trim="msg">
        {{msg}}
new Vue({
  el: '#app',
  data: {
      msg: ''
  }
})

显示过滤,排序后的结果

computed过滤器

<div id="app">
        <li v-for="n in evenNumbers" >
            {{n}}
        </li>
    </div>
data: {
            Object: [ 1,2,3,4,5,]
        },
        computed: {
            evenNumbers: function(){
                return this.Object.filter(function(number){
                    return number % 2 === 0
                })
            }
        }

事件处理

监听事件
<div id="app">
        <button v-on:click="counter += 1">Add 1</button>
        <p>The button above has benn clicked {{counter }} times</p>
      </div>
new Vue({
  el: '#app',
  data: {
      counter: 0
  }
})
也可以定义为一个事件来进行处理
<div id="app">
        <button v-on:click="add">Add 1</button>
        <p>The button above has benn clicked {{counter }} times</p>
      </div>

new Vue({
  el: '#app',
  data: {
      counter: 0
  },
  methods: {
      add: function(){
          this.counter += 1
      }
  }
})
内联处理器的方法
<button v-on:click="say('hi')"> Say hi</button>
        <button v-on:click="say('fuck')"> Say fuck</button>
new Vue({
  el: '#app',
  methods: {
      say: function(message){
          alert(message)
      }
  }
})
事件修饰符
<!-- 阻止单击事件继续传播 -->
<a v-on:click.stop="doThis"></a>

<!-- 提交事件不再重载页面 -->
<form v-on:submit.prevent="onSubmit"></form>

<!-- 修饰符可以串联 -->
<a v-on:click.stop.prevent="doThat"></a>

<!-- 只有修饰符 -->
<form v-on:submit.prevent></form>

<!-- 添加事件监听器时使用事件捕获模式 -->
<!-- 即内部元素触发的事件先在此处理,然后才交由内部元素进行处理 -->
<div v-on:click.capture="doThis">...</div>

<!-- 只当在 event.target 是当前元素自身时触发处理函数 -->
<!-- 即事件不是从内部元素触发的 -->
<div v-on:click.self="doThat">...</div>
按键修饰符
<input v-on:keyup.enter="submit">

组件基础

data必须是一个函数

data: funciton(){
  return{
      count:0
  }
}

通过props向子组件传递数据

Prop 是你可以在组件上注册的一些自定义 attribute。当一个值传递给一个 prop attribute 的时候,它就变成了那个组件实例的一个属性。为了给博文组件传递一个标题,我们可以用一个 props 选项将其包含在该组件可接受的 prop 列表中:

Vue.component('blog-post', {
  props: ['title'],
  template: '<h3>{{ title }}</h3>'
})
<blog-post title="My journey with Vue"></blog-post>
<blog-post title="Blogging with Vue"></blog-post>
<blog-post title="Why Vue is so fun"></blog-post>
利用v-bind来动态传递prop
new Vue({
  el: '#blog-post-demo',
  data: {
    posts: [
      { id: 1, title: 'My journey with Vue' },
      { id: 2, title: 'Blogging with Vue' },
      { id: 3, title: 'Why Vue is so fun' }
    ]
  }
})
<blog-post
  v-for="post in posts"
  v-bind:key="post.id"
  v-bind:title="post.title"
></blog-post>

单个根元素

<h3>{{ title }}</h3>
<div v-html="content"></div>

Vue 会显示一个错误,并解释道 every component must have a single root element (每个组件必须只有一个根元素)。需要这样修改根元素

<div class="blog-post">
  <h3>{{ title }}</h3>
  <div v-html="content"></div>
</div>

当需要的post越来越多的时候,这时候就需要重构组件了

<blog-post
  v-for="post in posts"
  v-bind:key="post.id"
  v-bind:title="post.title"
  v-bind:content="post.content"
  v-bind:publishedAt="post.publishedAt"
  v-bind:comments="post.comments"
></blog-post>

例如这样进行重构

<div id="app">
        <blog-post
            v-for="post in posts"
            v-bind:key="post.id"
            :post="post"
            ></blog-post>
 </div>
Vue.component('blog-post',{
    props: ['post'],
    template: `
    <div>
    <h3>{{post.id}}</h3>
    <h3>{{post.title}}</h3>
    </div>
    `
})
new Vue({
  el: '#app',
  data: {
    posts: [
      { id: 1, title: 'My journey with Vue' },
      { id: 2, title: 'Blogging with Vue' },
      { id: 3, title: 'Why Vue is so fun' }
    ]
  }
})

父子组件通过props通信

事前准备

<div id="app"></div>
var Child = {
          template:`
                <div>我是子组件</div>
            `
     }  
     var Parent = {
         components:{
            Child
         },
         template:`
                <div>
                <div>我是父组件</div>
                <child></child>
                </div>
            `
     }   
     new Vue({
         el:'#app',
         components:{
             Parent
         },
         template:`
                <div>
                <div>我是主页</div>
                <parent></parent>
                </div>
            `
     })
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,230评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,261评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,089评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,542评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,542评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,544评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,922评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,578评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,816评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,576评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,658评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,359评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,937评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,920评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,156评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,859评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,381评论 2 342

推荐阅读更多精彩内容

  • Vue 实例 属性和方法 每个 Vue 实例都会代理其 data 对象里所有的属性:var data = { a:...
    云之外阅读 2,198评论 0 6
  • 1. Vue 实例 1.1 创建一个Vue实例 一个 Vue 应用由一个通过 new Vue 创建的根 Vue 实...
    王童孟阅读 1,013评论 0 2
  • Vue是一个前端js框架,由尤雨溪开发,是个人项目 Vue近几年来特别的受关注,三年前的时候angularJS霸占...
    6e5e50574d74阅读 550评论 0 0
  • 一、了解Vue.js 1.1.1 Vue.js是什么? 简单小巧、渐进式、功能强大的技术栈 1.1.2 为什么学习...
    蔡华鹏阅读 3,311评论 0 3
  • 在这次猫叔分享的《牛人求学课》基础版重点提到了六点。并点明学到就是赚到。不仅是赚回进牛人营的学费,若真的学以致用那...
    剽悍的今天阅读 956评论 0 2