[Vue.js 1] 入门基础知识与开发

最近接触的几个项目框架全部用到了Vue.js技术,没办法只能对vuejs进行深入学习,不过可喜的是Vue.js学习路线非常快,上手也是非常快的,所以对于前端开发也是主流的开发框架了。不过其中的js部分我还得抽时间去专门地学习,否则自己的前端知识非常不扎实。

下面预计还有几篇关于Vue,大多是页面渲染,部署运维等其他知识了,当然了,有时间还是以项目为主(Vue.js项目大多以微信小程序为主,到时候可以直接上手一波了)

概述

随着网络的流行,很多的Wap(H5)应用也随之出现了,如微店、微站各个App中包含的H5页面。然而传统的技术特点:单击某个按钮或者提交表单Webpack会整体刷新,同时js/css请求往往很多(经常过百)。
所以越来越多的App采用SPA架构,如果项目要用在H5上面,那么一定要使用单页应用框架,例如Angular,React,Vue.js都是很好的框架。
主要的Web应用分为两类:传统的Web页面和单页应用(Single Page App)
传统的Web页面每次单击一个链接都会引起页面的整个刷新
以CSDN为例:每次页面打开,页面中的.js,.css,图片文件等资源会加载一遍,可以看到左下角一共加载了237个请求,耗时0.545s.
在这里插入图片描述
一般的Web页面的例子,从第一行到最后一行,都要加载my.js,my.css外部资源。

<head>
	<script src = "my.js" ></script>
	<style src = "my.css" ></style>
<head>

单页应用精髓就是点击任何链接不会引起页面的整体刷新,只会通过Js替换页面的局部内容。
说到这里就不得不谈 Ajax(js的异步处理),由js发起一个Http异步处理,用户可以一边上下滚动页面一边等待这个请求来返回数据。

Vue.js 是一个MVVM(Model - View - ModelView) 的SPA框架。
官方文档地址: Vue官方文档
简单来说,学会了Vue.js 就学会了微信小程序和阿里巴巴的Weex。

用到Vue.js的项目:
滴滴出行,饿了么,Gitlab,新浪微博等

原生的Vue.js

所谓原生,就是独立的Vue.js ,不与Webpack等框架结合使用。

极速入门

本人使用Webstorm进行开发:
Vue.js安装非常简单,只要引入一个第三方的JS包即可。

 <script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>

下面来看一个简单的例子:
在头部引入Vue.js包。在body引入了一个div,可以认为所有的页面展示都是在div下面的,当我们做任何点击的时候整个页面不会刷新。
var 就是创建一个Vue对象

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
    <title>测试Vue</title>
</head>
<body>
    <div id='app'>
        {{ show_my_text }}
    </div>
    <script>
        var app = new Vue({
        //指定所有的代码操作,对于div id= ‘app’来操作的
            e1 : 'app',
         // data表示Vue.js管理的变量赋值
            data : {
                show_my_text : 'Vuejs is the best one!'
            }
        })
    </script>
</body>
</html>

TODO-list项目

这个例子就是SPA的应用:
需求:1.可以列出待办事项,2.新建待办事项 3.可以把待办变成已办完。
这里的技术细节比较复杂,涉及到了组件,监听器,过滤器等。

<!DOCTYPE html>
<html>
<head>
  <title>TodoMVC</title>
<!--  引入vuejs库-->
  <script src="https://unpkg.com/vue@2"></script>
  <link
          rel="stylesheet"
          type="text/css"
          href="https://unpkg.com/todomvc-app-css@2.2.0/index.css"
  />
  <style>
    [v-cloak] {
      display: none;
    }
  </style>
</head>
<body>
<section class="todoapp">
<!--  定义了header,包括文字的提示和输入框-->
  <header class="header">
    <h1>todos</h1>
    <input
            class="new-todo"
            autofocus
            autocomplete="off"
            placeholder="What needs to be done?"
            v-model="newTodo"
            @keyup.enter="addTodo"
    />
  </header>

<!--  这里的代码把用户已经输入的待办事项做循环展示-->
  <section class="main" v-show="todos.length" v-cloak>
<!--    全选框-->
    <input
            id="toggle-all"
            class="toggle-all"
            type="checkbox"
            v-model="allDone"
    />
    <label for="toggle-all"></label>
<!--    v-for 用来循环-->
    <ul class="todo-list">
      <li
              v-for="todo in filteredTodos"
              class="todo"
              :key="todo.id"
              :class="{ completed: todo.completed, editing: todo == editedTodo }"
      >
        <div class="view">
          <input class="toggle" type="checkbox" v-model="todo.completed" />
          <label @dblclick="editTodo(todo)">{{ todo.title }}</label>
          <button class="destroy" @click="removeTodo(todo)"></button>
        </div>
        <input
                class="edit"
                type="text"
                v-model="todo.title"
                v-todo-focus="todo == editedTodo"
                @blur="doneEdit(todo)"
                @keyup.enter="doneEdit(todo)"
                @keyup.esc="cancelEdit(todo)"
        />
      </li>
    </ul>
  </section>
<!--  底部的状态,点击后可以进行过滤-->
  <footer class="footer" v-show="todos.length" v-cloak>
        <span class="todo-count">
          <strong>{{ remaining }}</strong> {{ remaining | pluralize }} left
        </span>
    <ul class="filters">
      <li>
        <a href="#/all" :class="{ selected: visibility == 'all' }">All</a>
      </li>
      <li>
        <a href="#/active" :class="{ selected: visibility == 'active' }"
        >Active</a
        >
      </li>
      <li>
        <a
                href="#/completed"
                :class="{ selected: visibility == 'completed' }"
        >Completed</a
        >
      </li>
    </ul>
    <button
            class="clear-completed"
            @click="removeCompleted"
            v-show="todos.length > remaining"
    >
      Clear completed
    </button>
  </footer>
</section>
<footer class="info">
  <p>Double-click to edit a todo</p>
  <p>Written by <a href="http://evanyou.me">Evan You</a></p>
  <p>Part of <a href="http://todomvc.com">TodoMVC</a></p>
</footer>


<!--js代码部分-->
<script>
  // Full spec-compliant TodoMVC with localStorage persistence
  // and hash-based routing in ~120 effective lines of JavaScript.

  // localStorage persistence
  // 下面的代码使用了浏览器的localStorage进行存储,同时定义了fetch()和save()用来方便操作
  var STORAGE_KEY = "todos-vuejs-2.0";
  var todoStorage = {
    fetch: function() {
      var todos = JSON.parse(localStorage.getItem(STORAGE_KEY) || "[]");
      todos.forEach(function(todo, index) {
        todo.id = index;
      });
      todoStorage.uid = todos.length;
      return todos;
    },
    save: function(todos) {
      localStorage.setItem(STORAGE_KEY, JSON.stringify(todos));
    }
  };

  //定义过滤器,分别对ative,completed和all进行过滤
  // visibility filters
  var filters = {
    all: function(todos) {
      return todos;
    },
    active: function(todos) {
      return todos.filter(function(todo) {
        return !todo.completed;
      });
    },
    completed: function(todos) {
      return todos.filter(function(todo) {
        return todo.completed;
      });
    }
  };

  //定义的Vue的实例
  // app Vue instance
  var app = new Vue({
    // app initial state
    data: {
      todos: todoStorage.fetch(),
      newTodo: "",
      editedTodo: null,
      visibility: "all"
    },

    // watch todos change for localStorage persistence
    watch: {
      todos: {
        handler: function(todos) {
          todoStorage.save(todos);
        },
        deep: true
      }
    },

    // computed properties
    // http://v2.vuejs.org/guide/computed.html
    computed: {
      filteredTodos: function() {
        return filters[this.visibility](this.todos);
      },
      remaining: function() {
        return filters.active(this.todos).length;
      },
      allDone: {
        get: function() {
          return this.remaining === 0;
        },
        set: function(value) {
          this.todos.forEach(function(todo) {
            todo.completed = value;
          });
        }
      }
    },

    filters: {
      pluralize: function(n) {
        return n === 1 ? "item" : "items";
      }
    },

    //核心方法,用来实现对待办事项的增加、删除和修改
    // methods that implement data logic.
    // note there's no DOM manipulation here at all.
    methods: {
      addTodo: function() {
        var value = this.newTodo && this.newTodo.trim();
        if (!value) {
          return;
        }
        this.todos.push({
          id: todoStorage.uid++,
          title: value,
          completed: false
        });
        this.newTodo = "";
      },

      removeTodo: function(todo) {
        this.todos.splice(this.todos.indexOf(todo), 1);
      },

      editTodo: function(todo) {
        this.beforeEditCache = todo.title;
        this.editedTodo = todo;
      },

      doneEdit: function(todo) {
        if (!this.editedTodo) {
          return;
        }
        this.editedTodo = null;
        todo.title = todo.title.trim();
        if (!todo.title) {
          this.removeTodo(todo);
        }
      },

      cancelEdit: function(todo) {
        this.editedTodo = null;
        todo.title = this.beforeEditCache;
      },

      removeCompleted: function() {
        this.todos = filters.active(this.todos);
      }
    },

    // a custom directive to wait for the DOM to be updated
    // before focusing on the input field.
    // http://v2.vuejs.org/guide/custom-directive.html
    directives: {
      "todo-focus": function(el, binding) {
        if (binding.value) {
          el.focus();
        }
      }
    }
  });

  // handle routing
  function onHashChange() {
    var visibility = window.location.hash.replace(/#\/?/, "");
    if (filters[visibility]) {
      app.visibility = visibility;
    } else {
      window.location.hash = "";
      app.visibility = "all";
    }
  }

  window.addEventListener("hashchange", onHashChange);
  onHashChange();

  // mount
  app.$mount(".todoapp");
</script>
</body>
</html>

样式图:
在这里插入图片描述

Webpack+Vue.js开发

NVM,NPM,Node

nvm(node version是非常好用的Node版本管理器,如果node版本不对,运行起来会有各种问题。
下载地址:NVM-windows
设置环境变量:

NVM_HOME: D:\nvm
NVM_SYMLINK : C:Program Files\nodejs

windows查看列出的的安装node版本:
在这里插入图片描述
列出本地安装的版本
在这里插入图片描述
安装的时候只要选择一个版本就可以,例如:

nvm install 17.5.0

加快nvm和npm的下载速度,修改成国内的镜像服务器:
对于nvm来说

NVM_NODEJS_ORG_MIRROR = https://npm.taobao.org/dist nvm install

对于npm,使用cnpm来代替npm

npm install - g cnpm --registry=https://registry.npm.taobao.org

然后通过国内的淘宝服务器安装node包:

Webpack

随着SPA单页应用的发展,使用js/css/png等文件特别多,比较难管理,文件夹结构也容易混乱,希望项目可以具有压缩的功能。
Webpack是一个打包工具,可以把js,css,node module,coffeescrip,scss等打包在一起,简直是SPA的福音。这样做可以做到路由的分离以及快速打包、部署以及项目上线。
安装Webpack:

npm install --save-dev webpack

因为Webpack自身支持Vue.js,所以Webpack与Vue.js很难分清谁是谁了。

开发环境的搭建

同时安装vue和vue-cli 这两个node package,-g表示可以被全局使用。

npm install vue vue-cli -g

可能会遇到这样的错误:npm WARN deprecated har-validator@5.1.5: this library is no longer supported
在这里插入图片描述

原因是资源的问题,要配置淘宝镜像
npm config set registry https://registry.npm.taobao.org
 
配置完成后检验是否成功
npm config get registry

如果下载后还是报错,那就是包问题,解决方法是删除文件的package-lock文件,重新npm install就可以了。

创建一个项目

vue init webpack my-project

会发现’vue’ 不是内部或外部命令,也不是可运行的程序或批处理文件。

首先进入npm查看全局安装路径:
在这里插入图片描述
进入到页面后,确实发现有vue了。
在这里插入图片描述
进入到环境变量:
在这里插入图片描述
在这里插入图片描述
重新打开cmd,此时安装完成了。
在这里插入图片描述
下面就进入到刚才的vue install一步:

vue init webpack my-project

安装依赖:

cd my-project
npm install

在本地以默认端口运行:

npm run dev

打开localhost:8080就可以看到创建的欢迎页了。
在这里插入图片描述

Webpack下的Vue.js项目结构

会生成一个崭新的项目,
在这里插入图片描述
在build文件中保留了各种打包脚本,不可随意更改。
config文件是与部署和配置相关的,在index.js定义了开发的端口,图片文件夹和代理服务器等
dist文件夹:对应的css,js,map都在这里。有了map文件夹浏览器可以下载整个.js文件。

在node_modules文件中,第三方包特别多,所有在package.json中定义的第三方包都会被自动下载。
src文件,是核心源代码所在目录。assets是放的图片,components用到的视图和组件(核心),router/index.js是路由文件,对应了各个页面的对应的Url.
在这里插入图片描述

Webpack+Vue.js入门

在这里插入图片描述
注意这里的位置是用小写,如果用大写将不能运行。
在这里插入图片描述

当然了你可以直接打开刚才创建的文件就可以,在readme直接运行npm run dev就可以了。

创建一个页面

默认的路由文件是src/router/index.js:
下面建一个sayhi,注意@表示当前目录

import Vue from 'vue'
import Router from 'vue-router'
// import HelloWorld from '@/components/HelloWorld'

//引入SayHi 这个component
import SayHi from '@/components/SayHi'

Vue.use(Router)

export default new Router({
  routes: [
  // 定义了/#/say_hi这个url
    {
      path: '/say_hi',
      name: 'SayHi', // Vue.js内部使用的名字
      component: SayHi //对应的.vue页面的名字
    }
  ]
})

创建一个新的Componet:
src/components/SayHi.vue

<template>
<div>
  Hi Vue
</div>
</template>

<script>
export default {
  data () {
    return { }
  }
}
</script>

<style scoped>

</style>

总是报 Expected indentation of 2 spaces but found 4错误,深入发现是缩进的原因,这个问题的原因在于eslint的风格样式缩进检测,eslint给出的规则是2个缩进,但我们通常是4个缩进。
在上面的代码中,template表示的是html模板,是最普通的HTML,script是js代码,所有的js代码都放在这里,这里使用的是EMScript,style表示所有的css文件都可以放在这里。
运行就可以了。

当然了可以增加样式
SayHi.vue

<div class ="hi">
<style scoped>
.hi {
  color: red;
  font-size: 20px;
}
</style>

定义并显示变量:
可以在data中定义:

export default {
  data () {
    return {
      message: '你好Vue'
    }
  }
}

当然了需要引用哦,这样就可以显示了:

<div class="hi">
  Hi Vue
  {{ message }}
</div>

Vue.js的ECMScript

我们使用的不是原生的js,而是新语言ECMScript(关于js我将会单独做几篇博客)
常量与变量:
声明本地变量:
var : 有可能引起变量提升,或者块级作用域问题
let : 为了解决以上两个问题。
多用let ,少用var

常量:
const title = “123”

全局变量:
window.title = “123”;

导入代码: import,用于导入外部代码:

import Vue from 'vue'
import Rounter from 'vue-router'

在每个vue文件的script中,都存在exprt default{…} 代码,作用是方便其他代码对这个代码进行引用。

其实在之前的代码我们发现:

export default {
//等同于 data ()
  data: function() {
	return {}
  }
}

分号可以省略。

以上。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值