Vue:渲染、指令、事件、组件、Props

如果要我用一句话描述使用 Vue 的经历,我可能会说“它如此合乎常理”或者“它提供给我需要的工具,而且没有妨碍我的工作”。每当学习 Vue 的时候,我都很高兴,因为很有意义,而且很优雅。

以上是我对 Vue 的介绍。在我第一次学习 Vue 的时候,我就想要这样的文章

我喜欢 Vue 的一点是它吸取了其它框架的优秀之处,并有条不紊的将它们组合在一起。

  • 具有响应式组件化的虚拟 DOM 只提供视图层, props 和 类 Redux 状态管理与 React 类似。

  • 条件渲染和服务与 Angular 类似。

  • 受到 Polymer 简洁及性能方面的启发,Vue 提供了类似的模式,比如 HTML, 样式以及 JavaScript 组合在一起。

Vue 相比其它框架的优势有: 简洁,提供更多语义化的 API , 比 React 的表现稍好,不像 Polymer 那样使用 polyfill,相比 Angular 有独立的视图。

我还能举一些例子,但是你最好读一下这篇综合的、社区推动的文章对比其它框架 。这篇文章值得一读,但是如果你想先看代码,你也可以先跳过,以后再读。

开始吧!

还是从 "Hello, world!" 的例子开始。运行如下示例:

HTML:

<div id="app">
  {{ text }} Nice to meet Vue.
</div>

CSS:

body {
  font-family: 'Bitter', serif;
}

#app {
  text-align: center;
  padding: 70px;
  font-size: 22px;
  max-width: 360px;
  margin: 0 auto;
  display: table;
}

Vue.js

new Vue({
  el: '#app',
  data: {
    text: 'Hello World!'
  }
})

如果你熟悉 React,你会发现两者有很多相同之处。通过 mustache 模板以及使用一个变量,可以避免在内容中使用 JavaScript,但是不同的一点是我们直接书写 HTML 而不是 JSX 。虽然 JSX 易于使用,但是我无需再花时间把 class 改成 className,等等。这样启动及运行会更轻量。

现在尝试一下我喜欢的 Vue 的特性: 循环以及条件渲染。

条件渲染

假如有一组元素,类似导航条,我打算重复利用。合理的做法是放在数组中动态的更新。使用普通的 JS (需要 Babel) ,我们会这样做: 创建一个数组,然后创建一个空字符串,用来存放使用 <li> 包裹的元素,再用 <ul> 包裹所有内容,使用 innerHTML 方法添加到 DOM 中:

HTML:

<div id="app">
    <ul>
        <li v-for="item in items">
            {{item}}
        </li>
    </ul>
</div>

Vue.js:

new Vue({
   el:"#app",
   data:{
       items:[
           'thingie',
           'another things',
           'lots of stuff',
           'yadda yadda'
       ]
   }
})

非常简洁。如果你熟悉 Angular,你对此应该不陌生。我发现这种条件渲染的方式简单明了。如果你需要更新内容,修改起来也很简单。

另外一种好的方式是使用 v-model 进行动态绑定。试试下面的例子:

HTML:

<div id="app">
    <h3>Type here:</h3>
    <textarea v-model="message" class="message" rows="5" maxlength="72"></textarea>
    <p class="booktext">{{message}}</p>
</div>

Vue.js

new Vue({
    el:"#app",
    data:{
        message:"this is a good place top type"
    }
})

在这个 Demo 中你会注意到两点。首先,可以直接向书中打字并且动态更新文本。Vue 通过 v-model 非常方便的实现了 <textarea><p> 的数据绑定。

并不是只有简单的输入绑定,甚至 v-if 可以用 v-show 替换,有 v-show 的元素不是销毁或重建组件,而是始终保持在 DOM 中,切换可见性。

Vue 提供了 很多指令 , 下面是我经常使用的一些指令。很多指令都有缩写,所以我会一起列出来。在之后的教程中,我们主要使用指令缩写,所以最好先熟悉一下下面的表格。

也有非常好的事件修饰符和其他 API

加快开发的方法:

  • @mousemove.stope.stopPropogation() 相同
  • @mousemove.prevent 类似于 e.preventDefault()
  • @submit.prevent 提交时不再重新加载页面
  • @click.once 不要和 v-once 混淆,这个 click 事件只触发一次
  • v-model.lazy 不会自动填充内容,它将在事件发生时绑定

事件处理

数据绑定虽然很好,但是没有事件处理也无法发挥更大的用途,因此接下来就试一试! 这是我喜欢的一部分。我们将使用上面的绑定和监听器来监听 DOM 事件。

在应用程序中有几种不同的方法来创建可用的方法。比如在普通的 JS 中,你可以选择函数名,但是实例方法直观地称为 methods

<div id="app">
   <p><button @click="increment">+</button><br>{{counter}}</p>
</div>
new Vue({
    el:"#app",
    data:{
        counter:0
    },
    methods:{
        increment:function(){
            this.counter++
        }
    }
})

我们创建了一个名为 increment 的方法并且你会注意到函数自动绑定了 this ,会指向实例及组件中的 data 。我喜欢这种自动绑定,不需要通过 console.log 查看 this 的指向。 我们使用缩写 @click 绑定 click 事件。Methods 并不是创建自定义函数的唯一方式。你也可以使用 watch 。两者的区别是 methods 适合小的、同步的计算,而 watch 对于多任务、异步或者响应数据变化时的开销大的操作是有利的。我经常在动画中使用 watch

让我们看看如何传递事件并且进行动态地样式绑定。如果你记得上面的表格,你可以使用 : 来代替 v-bind ,因此我们可以很简单地通过 :style 以及 传递状态,或者 :class 绑定样式 (以及其他属性)。这种绑定确实有很多用途。

<div id="app">
   <p>
       <button @click="increment">+</button>
       <br>
       {{counter}}
       <br>
       <button @click="decrement">-</button>
   </p>
</div>
    new Vue({
        el:"#app",
        data:{
            counter:0,
        },
        methods:{
            increment:function(){
                this.counter++
            },
            decrement:function(){
                this.counter--
            }
        }
    })

 

你应该看到我们甚至不需要传递 @click 事件,Vue 将它作为方法的参数(这里显示为 e )自动传递。

此外,原生方法也可以使用,比如 event.clientX,并且很容易关联 this 实例。在元素的样式绑定中,CSS 属性需要使用驼峰命名。在这个例子中,你可以看到 Vue 的简单明了。

组件和传递数据

如果你熟悉 React 或者 Angular2,组件思想和传递状态对你并不陌生。如果不是, 让我们先了解一些主要概念。

大小网站通常由不同的部分组成,并且抽象成更小的部分更容易布局、重用、并使得我们的代码更清晰。为了避免在冗长的多层次的页面中搜寻标签,我们可以这样构建组件:

<header></header>
<aside>
    <sidebar-item v-for="item in items"></sidebar-item>
</aside>
<main>
    <blogpost v-for="post in posts"></blogpost>
</main>
<footer></footer>

这是一个简单的例子,但是你可以看到这种组合方式在开始构建网站结构时的用途。如果你要维护这些代码,你可以很容易的了解程序的结构并且找到每一部分。著作权归作者所有。

Vue 有多种创建组件的方式。让我们从易到难,而复杂的例子就是一个普通的 Vue 程序。

下面是我能做的最简单的例子,所以非常容易理解。

记住 HTML 中的 :text 是 Vue 绑定的缩写。我们在指令部分的最后提到过。绑定可以用于所有方面,但是在这个实例中,这样做的好处是不需要把状态放在 mustache 模板中, 比如 {{ message }}

在下面的代码中,Vue.component 是组件, new Vue 称为实例。一个程序中可以有多个实例。通常情况下,我们会有一个实例和多个组件,因为实例是主要应用程序。

<div id="app">
    <child :text="message"></child>
</div>
    Vue.component('child', {
        props: ['text'],
        template: '<div>{{ text }}</div>'
    });

    new Vue({
        el: '#app',
        data: {
            message: 'Hello Mr. Magoo'
         }
    })

现在我们可以在程序中随意使用这个组件:

HTML:

<div id="app">
    <h3>
        <button @click="increment">+</button>
        Adjust the data
        <button @click="decrement">-</button>
    </h3>
    <h2>This is the app data: <span class="num">{{ count }}</span></h2>
    <h4>
        <child :count="count"></child>
    </h4>
    <p>This is a child counter that is using a static integer as props</p>
    <h4>
        <child :count="count"></child>
    </h4>
    <p>This is the same child counter and it is using the vue instance data as props</p>
</div>

Vue.js

    Vue.component('child', {
        props: ['count'],
        template: '<div class="num">{{ count }}</div>'
    });

    new Vue({
        el: '#app',
        data: {
            count: 0
        },
        methods: {
            increment:function(){
                this.count++
            },
            decrement:function(){
                this.count--
            }
        }
    })

区别在于你是否传递了一个属性并绑定它:

  • 没有使用状态<child count="1"></child>
  • 使用状态<child :count="count"></child>
再看一个案例:
HTML:
<div id="app">
    <img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/28963/vue-post-photo.jpg" alt="" class="main-photo" />
    <img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/28963/vue-main-profile.jpg" alt="" class="main-profile" />
    <div class="main-info">
        <span class="name">Julianne Delfina</span>
        <h3>"It's lovely after it rains"</h3>
    </div>
    <ul>
        <li
                is="individual-comment"
                v-for="comment in comments"
                v-bind:commentpost="comment"
                ></li>
    </ul>
    <input
            v-model="newComment"
            v-on:keyup.enter="addComment"
            placeholder="Add a comment" />
</div>

Vue.js

Vue.component('individual-comment', {
        template: '<li>{{ commentpost }}</li>',
        props: ['commentpost']
    });

    new Vue({
        el: '#app',
        data: {
            newComment: '',
            comments: [
                'Looks great Julianne!',
                'I love the sea',
                'Where are you at?'
            ]
        },
        methods: {
            addComment: function () {
                this.comments.push(this.newComment);
                this.newComment = ''
            }
        }
    })

<---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------->

Vue系列教程

入门vue----(vue的安装)

入门vue----(介绍)

Vue.js 基本语法

Vue深度学习(1)

Vue深度学习(2)

Vue深度学习(3)

Vue深度学习(4)-方法与事件处理器

Vue深度学习(5)-过渡效果

Vue深度学习(6)- 组件

vue-购物车

posted @ 2018-03-25 21:54  BluesQian  阅读(603)  评论(0编辑  收藏  举报