Vue入门实战教程(一)—— Vue介绍

此学习教程是对官方教程的解析,官方教程地址:介绍 —— Vue.js

一  Vue介绍

1.VUE核心: 声明式渲染

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

理解:

Vue.js 的核心是一个系统, 什么样的系统呢?

(1)它有简洁的模板语法:{{ }}的形式

(2)它是声明式的:也就是告诉VUE我要将某个数据和DOM的某个文本/attribute/结构进行绑定,至于怎么将数据渲染进 DOM VUE会替我搞定(渲染是响应式的,数据变化会自动反映在DOM中; 响应式也是VUE的重要特性)。而命令式渲染,指的是你需要自己写程序来将数据渲染到DOM。这很累,对吧?

(3) 如何声明?将数据绑定到DOM。 以下是三种绑定方式:

1.1 文本插值:将数据绑定到DOM文本

在D:\workspace_vue\vue_demo目录创建vue_introduce.html, 输入以下内容:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<!-- 尝试 Vue.js 最简单的方法是使用 JSFiddle 上的 Hello World 例子。你可以在浏览器新标签页中打开它,跟着例子学习一些基础用法。或者你也可以创建一个 .html 文件,然后通过如下方式引入 Vue:-->
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>

<body>
<!-- Vue.js 的核心是一个允许采用简洁的模板语法来声明式地将数据渲染进 DOM 的系统: -->
<div id="app">
  {{ message }}
</div>

<script>
var app = new Vue({
  el: '#app',<!-- 此实例作用于id为app的div -->
  data: {
    message: 'Hello Vue!'
  }
})
</script>
</body>
</html>
<!--
我们已经成功创建了第一个 Vue 应用!看起来这跟渲染一个字符串模板非常类似,但是 Vue 在背后做了大量工作。现在数据和 DOM 已经被建立了关联,所有东西都是响应式的。我们要怎么确认呢?打开你的浏览器的 JavaScript 控制台 (就在这个页面打开),并修改 app.message 的值,你将看到上例相应地更新。
-->

运行结果

控制台修改app.message的值后:

1.2 控制元素attribute:将数据绑定到DOM元素attribute(使用指令)

指令:带有前缀 v-,以表示它们是 Vue 提供的特殊属性,它们会在渲染的 DOM 上应用特殊的响应式行为。

v-bind:  将元素节点的某个属性和 Vue 实例的某个属性绑定起来,从而保持一致。例如下例v-bind:style="style"的作用是,将<span>元素的style属性和app2的vue实例的style属性(app2的data里面)绑定。

示例(官网的鼠标悬停例子不好截图,所以换成颜色变换的效果):

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>

<body>
<!-- 除了文本插值,我们还可以像这样来绑定元素 attribute: -->
<!--
这里我们遇到了一点新东西。你看到的 v-bind attribute 被称为指令。指令带有前缀 v-,以表示它们是 Vue 提供的特殊 attribute。可能你已经猜到了,它们会在渲染的 DOM 上应用特殊的响应式行为。在这里,该指令的意思是:“将这个元素节点的 style attribute 和 Vue 实例的 style 属性保持一致”。
-->
<div id="app-2">
  <span v-bind:style="style">
    改变我的颜色!
  </span>
</div>

<script>
var app2 = new Vue({
  el: '#app-2',<!-- 此实例作用于id为app-2的div -->
  data: {
    style: 'color:dark'
  }
})
</script>
</body>
</html>

运行结果

控制台修改app2.style的值后:

1.3 条件与循环:将数据绑定到DOM结构(使用指令)

1.3.1 条件

v-if:  将元素节点的是否显示和 Vue 实例的某个布尔属性绑定起来,从而通过控制这个布尔属性来控制元素节点的切换

控制切换元素示例:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>

<body>
<!-- 控制切换一个元素是否显示也相当简单 -->
<!--
这个例子演示了我们不仅可以把数据绑定到 DOM 文本或 attribute,还可以绑定到 DOM 结构。此外,Vue 也提供一个强大的过渡效果系统,可以在 Vue 插入/更新/移除元素时自动应用过渡效果。
-->
<div id="app-3">
  <p v-if="seen">现在你看到我了</p>
</div>

<script>
var app3 = new Vue({
  el: '#app-3',
  data: {
    seen: true
  }
})
</script>
</body>
</html>

运行结果:

控制台修改app3.seen的值后:

1.3.2 循环

v-for:  绑定数组的数据来渲染一个项目列表

示例:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>

<body>
<!-- v-for 指令可以绑定数组的数据来渲染一个项目列表 -->
<div id="app-4">
  <ol>
    <li v-for="todo in todos">
      {{ todo.text }}
    </li>
  </ol>
</div>

<script>
var app4 = new Vue({
  el: '#app-4',
  data: {
    todos: [
      { text: '学习 JavaScript' },
      { text: '学习 Vue' },
      { text: '整个牛项目' }
    ]
  }
})
</script>
</body>
</html>

运行结果:

控制台修改app4.todos的值后:

2.处理用户输入

通过将数据绑定到DOM文本/attribute/结构的方式,VUE替我们完成了将数据渲染到DOM文本/attribute/结构的内部实现。然后我们通过控制台修改数据,DOM文本/attribute/结构就自动发生了相应的变化。 这很神奇。但用户可不会使用控制台。他们只能通过表单组件输入/修改数据。如何实现表单组件和数据的绑定呢?

2.1 按钮输入

v-on:添加一个事件监听器,通过它调用在 Vue 实例中定义的方法

示例:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>

<body>
<!-- 为了让用户和你的应用进行交互,我们可以用 v-on 指令添加一个事件监听器,通过它调用在 Vue 实例中定义的方法: -->
<div id="app-5">
  <p>{{ message }}</p>
  <button v-on:click="reverseMessage">反转消息</button>
</div>

<script>
var app5 = new Vue({
  el: '#app-5',
  data: {
    message: 'Hello Vue.js!'
  },
  methods: {
    //注意在 reverseMessage 方法中,我们更新了应用的状态,但没有触碰 DOM——所有的 DOM 操作都由 Vue 来处理,你编写的代码只需要关注逻辑层面即可。
    reverseMessage: function () {
      this.message = this.message.split('').reverse().join('')
    }
  }
})
</script>
</body>
</html>

运行效果:

按钮点击前

按钮点击后

2.2 表单输入

v-model:轻松实现表单输入和应用状态之间的双向绑定

示例:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>

<body>
<!-- Vue 还提供了 v-model 指令,它能轻松实现表单输入和应用状态之间的双向绑定 -->
<div id="app-6">
  <p>{{ message }}</p>
  <input v-model="message">
</div>

<script>
var app6 = new Vue({
  el: '#app-6',
  data: {
    message: 'Hello Vue!'
  }
})
</script>
</body>
</html>

运行效果:

文本框内容修改前:

文本框内容修改后:

回到最根本的问题,VUE为什么要实现声明式渲染,并且是它的核心呢?个人认为声明式渲染带来了以下好处:

(1)易入门:相对于命令式,声明式隐藏了实现细节,显得简单、易懂、直观,特别对于初学者友好,易于入门。

(2)便于维护:声明式渲染将数据及实现逻辑和视图进行了解耦, 开发人员可以专注于业务逻辑实现还无须操心DOM的变化。

(3)打下组件化基础:数据及逻辑和视图的解耦为组件化打下了基础。一个组件的内部,就包括了数据、逻辑和视图(组件模板),没有解耦,  组件就难以维护。

3.组件基础

为什么需要组件化:当一个应用很复杂时, 组件化将大大降低开发的难度,提高应用的稳定性和可维护性, 且容易复用。形象地说,打造一个复杂的应用就像搭积木一样。

组件系统:Vue 的另一个重要概念,因为它是一种抽象,允许我们使用小型、独立和通常可复用的组件构建大型应用。

组件:  拥有预定义选项的Vue 实例

组件注册:Vue.component(组件名, 预定义选项)

3.1 无属性的组件

组件最简单的例子:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>

<body>
<ol id="app-7">
    <todo-item></todo-item>
    <todo-item></todo-item>
    <todo-item></todo-item>
</ol>
<script>
// 一个组件本质上是一个拥有预定义选项的一个 Vue 实例。在 Vue 中注册组件很简单
// 定义名为 todo-item 的新组件
Vue.component('todo-item', {
  template: '<li>这是个待办项</li>' //组件模板
})
var app7 = new Vue({
  el: '#app-7'
})
</script>
</body>
</html>

运行结果:

3.2 带自定义属性的组件

上面的例子,组件模板的html内容都是固定的,这并不灵活。 能给组件传递数据吗? 可以,通过组件的自定义属性。

组件的自定义属性:由组件自定义选项props设置。

3.2.1 非对象属性:

给todo-item组件设置一个非对象属性todo:

Vue.component('todo-item', {
  props: ['todo'],
  template: '<li>{{todo}}</li>'
})

例子:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>

<body>
<div id="app-7">
  <ol>
    <!--
      为 todo-item 组件提供 todo 属性。
      注意有无v-bind的区别
    -->
    <todo-item todo="grocery"></todo-item>
    <todo-item v-bind:todo="grocery"></todo-item>
  </ol>
</div>
<script>
// 定义名为 todo-item 的新组件
Vue.component('todo-item', {
  // todo-item 组件现在接受一个
  // "prop",类似于一个自定义 attribute。
  // 这个 prop 名为 todo。
  props: ['todo'],
  template: '<li>{{todo}}</li>'
})

var app7 = new Vue({
  el: '#app-7',
  data: {
	grocery:'蔬菜'
  }
})
</script>
</body>
</html>

运行结果:

3.2.2 对象属性:

给todo-item组件设置一个对象属性todo:

Vue.component('todo-item', {
  props: ['todo'],
  template: '<li>{{todo.text}}</li>'
})

例子:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>

<body>
<div id="app-7">
  <ol>
    <!--
      这次todo-item的todo属性是一个对象。
      以下方式不起作用, 因为"grocery"是字符串不是对象,没有text属性
    -->
    <todo-item todo="grocery"></todo-item>
    
    <!-- 使用v-bind绑定对象数据 -->
    <todo-item v-bind:todo="grocery"></todo-item>
    <todo-item v-bind:todo="grocery_json"></todo-item>
  </ol>
</div>
<script>
// 定义名为 todo-item 的新组件
Vue.component('todo-item', {
  // todo-item 组件现在接受一个
  // "prop",类似于一个自定义 attribute。
  // 这个 prop 名为 todo。
  props: ['todo'],
  template: '<li>{{todo.text}}</li>' //模板里使用了对象的属性
})

var grocery=new Object();
grocery.id="0";
grocery.text="蔬菜";

var app7 = new Vue({
  el: '#app-7',
  data: {
	grocery: grocery, //这是一个javascript对象
	grocery_json: { id: 0, text: '蔬菜' }//这是一个JSON对象,更为简洁
  }
})
</script>
</body>
</html>

运行结果:

带循环的更复杂的例子:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>

<body>
<div id="app-7">
  <ol>
    <!--
      现在我们为每个 todo-item 提供 todo 对象
      todo 对象是变量,即其内容可以是动态的。
      我们也需要为每个组件提供一个“key”,稍后再
      作详细解释。
    -->
    <todo-item
      v-for="item in groceryList"
      v-bind:todo="item"
      v-bind:key="item.id"
    ></todo-item>
  </ol>
</div>
<script>
// 定义名为 todo-item 的新组件
Vue.component('todo-item', {
  // todo-item 组件现在接受一个
  // "prop",类似于一个自定义 attribute。
  // 这个 prop 名为 todo。
  props: ['todo'],
  template: '<li>{{ todo.text }}</li>'
})

var app7 = new Vue({
  el: '#app-7',
  data: {
    groceryList: [
      { id: 0, text: '蔬菜' },
      { id: 1, text: '奶酪' },
      { id: 2, text: '随便其它什么人吃的东西' }
    ]
  }
})
</script>
</body>
</html>
<!--
尽管这只是一个刻意设计的例子,但是我们已经设法将应用分割成了两个更小的单元。子单元通过 prop 接口与父单元进行了良好的解耦。我们现在可以进一步改进 <todo-item> 组件,提供更为复杂的模板和逻辑,而不会影响到父单元。
-->

运行结果:

>> 实践一下

以下例子运行下,看会发生什么(请注意生成的HTML的变化):

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>

<body>
<div id="app-7">
  <ol>
    <!--
      style="color:red" 
    -->
    <todo-item v-bind:todo="grocery" style="color:red"></todo-item>
  </ol>
</div>
<script>
// 定义名为 todo-item 的新组件
Vue.component('todo-item', {
  // todo-item 组件现在接受一个
  // "prop",类似于一个自定义 attribute。
  // 这个 prop 名为 todo。
  props: ['todo'],
  template: '<li><span>{{todo.text}}</span></li>' 
})


var app7 = new Vue({
  el: '#app-7',
  data: {
	grocery: { id: 0, text: '蔬菜' }
  }
})
</script>
</body>
</html>

3.3 嵌套的组件

这里有一个 (假想的) 例子,以展示使用了组件的应用模板是什么样的:

<div id="app">
  <app-nav></app-nav><!-- 应用导航组件,显示导航区-->
  <app-view><!-- 应用视图组件,显示视图区-->
    <app-sidebar></app-sidebar><-- 应用侧边栏组件,应用视图组件的子组件,显示侧边栏 -->
    <app-content></app-content><-- 应用内容组件,应用视图组件的子组件,显示内容 -->
  </app-view>
</div>

有四个自定义组件, 显示了一个清晰的组件树:

app-nav:应用导航组件,显示导航区

app-view:应用视图组件,显示视图区

  |-  app-sidebar:应用侧边栏组件,应用视图组件的子组件,显示侧边栏

  |-  app-content:应用内容组件,应用视图组件的子组件,显示内容

VUE 介绍部分学习教程结束!

全部教程地址:Vue入门实战教程 | 寒于水学习网

下一章:Vue入门实战教程(三)—— 视图层:模板及指令

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值