Vue快速上手的第一个项目—— todo-list

前言

在上大学那阵子,jQuery正流行,于是凭借着“一边百度一边敲代码的本领”,怎能把自己想要的效果显示出来,但是jQuery背后疯狂操纵dom的事实,和日后难维护的问题,当时并没有顾及太多(但是当时我就发现了,想要变换个什么功能,在代码里面找起来,是真的费劲)。
等开始实习的时候,实习单位使用的是Angular(刚入职的时候使用的AngularJs 后来使用了Angular4 这两个的关系就像是猫和熊猫的关系,根本不是一回事。)他们把Js代码军团组织的更加完整了,分离出来了MVC(Model,View,Controller)。使用起来给我们提供了很多的方便。但是总感觉他们并不是我的菜,怎么也提不起来对他们的兴趣。
直到后来我接触了Vue,简直就是前端各种框架的一股清流,引入了MVVM(Model,View,View-Model)。全文上下,变量,方法,组件,包裹在实例中,被安排的明明白白。由原来的事件作为驱动力,改为了数据作为驱动力,View的数据变动,通过View-Model修改了Model,同样的,Model的变化,通过View-Model修改了View的显示。View-Model像是一个桥梁一样连接着View和Model。
这是我学Vue的第一个小练习—— todo-list。

正文

学习一门技术,官网永远是最好的老师。
这里是官网教程入口
这里是讲解MVVM结构的入口,廖雪峰老师官方网站

简单例子引入

我们首先由一个简单的例子引入,在这里不使用Vue-Cli,只是通过CDN的方式引入。
先创建一个空的html文件,在其中输入以下代码:


<html>
    <head>
        <!--通过CDN引入vue.js源代码-->
        <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    </head>
    <body>
        <h3>element:root</h3>
        <div id="root">
            <div>
                {{msg}}
            </div>
            <!-- v-html 可以把data中的数据以html形式显示出来-->
            <div v-html="htmlInput">

            </div>
            <!-- v-text直接显示数据, 并不是在意以什么形式显示出来-->
            <div v-text="textInput">

            </div>
            <!-- v-on: (事件绑定),也可以写为@click="clickFunction"可以简写为"@"符号,-->
            <div v-on:click="clickFunction">
                {{clickText}}
            </div>
        </div>
        <hr>
        <h3>element:app-2</h3>
        <div id="app-2">
            <!-- v-bind(属性绑定) 直接可以简写为":"-->
            <span v-bind:title="message">
                鼠标悬停几秒钟查看此处动态绑定的提示信息!
            </span>
            <br>
            <!-- v-bind 用于单向绑定,数据驱动页面的变化,但是页面变化不会同时对应到后台上-->
            <input :value="content">
            <!-- v-model 用于双向绑定-->
            <input v-model="content">
            <div>{{content}}</div>
        </div>
        <hr>
        <h3>element:app-3</h3>
        <div id="app-3">
            first name:<input v-model='firstname'/>
            last name:<input v-model='lastname'/>
            <br>
            full name:<div >{{fullname}}</div>
        </div>
        <script type="text/javascript">
            //创建一个vue实例,这是整个vue的灵魂,这就是传说中的mvvm中的vm——viewmodel
            var root = new Vue({
                el:"#root",
                data:{
                    msg: "harry is worderful",
                    htmlInput: "<b>this is a test text</b>",
                    textInput: "<b>this is a test text</b>",
                    clickText: "you can click it"
                },
                methods:{
                    clickFunction:function(){
                        root.clickText = "congretulation";
                    }
                }
            });

            var app2 = new Vue({
              el: '#app-2',
              data: {
                message: '页面加载于 ' + new Date().toLocaleString(),
                content: "this is a content"
              }
            });

            new Vue({
                el: "#app-3",
                data: {
                    firstname: '',
                    lastname: ''
                },
                computed: {
                    fullname: function(){
                        return this.firstname + ' ' + this.lastname;
                    }
                }
            });
        </script>
    </body>

</html>

这段代码大家可以直接创建一个.html文件然后粘在里面查看一下效果,我也有写上注释。大概的思路是这样的,首先new 一个Vue实例,然后在实例中配置,首先设置“el”属性用来绑定dom的id,然后把需要定义的变量放在“data”属性中,把方法房子“methods”属性中,需要计算的变量,放在“computed”属性中。

初识todo-list

下面使用CDN创建一个todo-list简单的例子。todo-list实现的效果是,在一个文本框中输入数据,点击一个按钮,然后数据会显示在下方的一个list中。

<html>
    <head>
        <!--通过CDN引入vue.js源代码-->
        <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    </head>
    <body>
        <div id="root">
            <input type="text" v-model='variable'/>
            <br>
            <button @click='clickEvent'>click</button>
            <ul>
                <li v-for='(item, index) of list'>{{item}}</li>
            </ul>
            <hr>
            <h4>使用组件形式</h4>
            <ul>
                <todo-list v-for="(item, index) of list" :key="index" :content="item" :index="index" @delete="handleDelete"></todo-list>
            </ul>

        </div>

        <script type="text/javascript">

            //这是全局的组建可以被用于这个项目中的任何地方。
            Vue.component('todo-list',{
                props: ['content','index'],
                template: '<li @click="handleClick">{{content}} {{index}}</li>',
                methods:{
                    handleClick: function(){
                        this.$emit('delete',this.index);
                    }
                }
            });


             new Vue({
                el: "#root",
                data:{
                    variable: '',
                    list: []
                },
                methods:{
                    clickEvent: function(){
                        this.list.push(this.variable);
                        this.variable= '';
                    },
                    handleDelete: function(index){
                        this.list.splice(index,1);
                    }
                }
                
             });
        </script>
    </body>

</html>

大家可以先放到自己的文件中,查看一下效果。
我们可以很容易的观察到,这个例子,和刚刚哪个简单例子的区别。
在这个例子中为了说明组件的概念,将ul中的li单独抽了出来作为了一个组件。
主要的还是多了以下这段代码:

//html代码
<ul>
   <todo-list v-for="(item, index) of list" :key="index" :content="item" :index="index" @delete="handleDelete"></todo-list>
</ul>
//js代码
Vue.component('todo-list',{
                props: ['content','index'],
                template: '<li @click="handleClick">{{content}} {{index}}</li>',
                methods:{
                    handleClick: function(){
                        this.$emit('delete',this.index);
                    }
                }
            });

刚开始看到这块的代码,我整个人也是挺蒙的,下面我们来分析分析。
Vue.component(),这个方法用来创建一个组件,这是创建了一个全局的组件,就是在整个应用中的所有地方都可以使用这个组件,还有一种方法就是使用局部组件,大概的使用方法是这样的:
首先定义一个Json,里面还是放我刚刚说过的那些实例中的属性。

var todoList = {
    template: '<li>item</li>';
};

然后我们在外层实例中,使用"component"属性。
里面写入:

component: {
    'todo-list':todoList
}

todo-list为dom标签的名字,而他的value就是咱们刚刚定义的那个属性值。
回到刚刚说的定义的全局组件,component方法的第一个参数是使用这个组件的名称,第二个参数就像是我们Vue实例一样,里面有相应的参数设置。

  • props: 如果在子组件中,我们需要父组件传递进来的参数,首先需要在html的标签上绑定需要传进去的参数,在这里一个是content,一个是index,然后需要在这个属性注册以下。
  • template: 定义的自组件的模版。
  • methods: 自组件需要用到的方法。
    刚刚说到了父传子,那子传父我们应该怎么办呢?
    当一个事件在自组件被触发的时候,我们需要在这个事件中加入
this.$emit('delete',this.index);

向外部发送一个名字叫做delete的事件(这个事件名称可以自己随意起),然后在后面的参数中加上想要传递的参数,最后在外部组件的当前元素中监听刚刚发送的那个事件

@delete="handleDelete

再使用handleDelete方法进行具体处理就行。

Vue-cli 创建todo-list

下面咱们使用Vue-cli,进行一次todo-list的练习。
首先要确保自己的电脑上有node.js
没有的话可以自行下载一下,node js 官网
安装好了之后,通过 node -v查看一下是否安装成功了。
接下来我们就可以安装vue-cli了
1.npm install --global vue-cli
2.vue init webpack projectName
在这步过程中cli会对这个项目的一些设置进行询问,根据自己的需要填写就行了。

image.png

3.npm run dev,启动后输入localhost:8080就有以下效果。
image.png

我是使用atom作为编辑器,打开工程后,进入src文件夹将main.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 ToDoList from './ToDoList'

Vue.config.productionTip = false

/* eslint-disable no-new */
new Vue({
  el: '#app',
  components: { ToDoList },
  template: '<ToDoList/>'
})

然后添加一个ToDoList.vue文件

<template>
  <div>
    <input v-model="inputValue"/>
    <button @click="clickEvent">提交</button>
    <ul>
      <listitem v-for="(item,index) of list" :content="item" :index="index" @delete="deleteEvent"></listitem>
    </ul>
  </div>
</template>

<script>
import listitem from './components/listitem'

export default {
  name: 'ToDoList',
  components: {
    listitem
  },
  data () {
    return {
      inputValue : '',
      list:[]
    }
  },
  methods:{
    clickEvent:function(){
      this.list.push(this.inputValue);
      this.inputValue = '';
    },
    deleteEvent:function(index){
      this.list.splice(this.index,1);
    }
  }
}
</script>

<style>

</style>

再添加一个listitem.vue文件

<template>
    <li @click="clickEvent">{{content}}</li>
</template>

<script>
export default {
  name: 'listitem',
  props:['content','index'],
  methods:{
    clickEvent () {
        this.$emit('delete',this.index);
    }
  }
}
</script>

<style >

</style>

可以看到为了彻底的接触耦合,vue文件把代码分为了三块分别为 template(html代码) ,script(js代码),style(以及css代码的形式)
还是启动刚刚的localhost:8080,就可以看到效果了。
Tips:值得注意的是,我们现在要想使用data这个属性,就不能使用key-value的形式了,而是需要写成函数的形式,然后把数据作为返回值return出去:

data () {
    return {
      inputValue : '',
      list:[]
    }
  }

后记

这是我vue的第一步,在这里做一个总结,之后的不断学习,我也会不断发文章进行更新的。

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

推荐阅读更多精彩内容

  • 前言 您将在本文当中了解到,往网页中添加数据,从传统的dom操作过渡到数据层操作,实现同一个目标,两种不同的方式....
    itclanCoder阅读 25,701评论 1 12
  • 工作表的基础知识和基本操作知识点(1) . 工作表中公式的输入和复制(2) . 单元格绝对地址和相对地址的...
    拾起_518阅读 401评论 0 0
  • 男孩最后一字最好用二声或四声女孩最后一字最好用一声或三声
    查苏的吉古勒阅读 124评论 0 1