Vue3手册译稿 - 基础 - 介绍

介绍

提示
已经了解Vue2且仅想知道Vue3有哪些新功能?请参阅迁移指南

Vue.js是什么?

Vue(读音/vjuː/,像view一样发音)是一套用于构建用户界面的先进框架,不像其他僵化的框架,Vue被设计为全面的渐进式可扩没用框架。该核心库只关注视图层,使用非常简单且易于与其他第三方类库或现有项目进行集成。另一方面当与现代化工具以及支持类库结合使用时,Vue也完全能够为复杂的单页面应用(SPA)提供完美支持。

开始使用

提示
官方手册认为HTML,Css,JavaScript你已达到中等水平。如果你是前端开发的新手,直接跳过基础学习Vue框架不是一个好主意,建议掌握基础知识以后再回来!了解其他框架对学习Vue有帮助,但也不是必须的。

最佳学习习Vue.js方法是验证使用Hello World示例。可以在新标签打开这个链接,跟着我们一起学习这些基础示例。

安装节已提供了多种安装Vue的方式。说明:不推荐初学者一开始就使用vue-cli,特别是你对基于Node.js构建工具不是非常熟悉的情况下。

声明式渲染

Vue.js的核心是让我们很简单的使用模板语法声明式渲染数据至DOM元素上。
完整代码如下:

<!DOCTYPE html>
<html lang="en-US">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <title>vue demo1</title>
	<script src="https://unpkg.com/vue@next"></script>
   </head>
   <body>
		<div id="counter">
			Counter:{{counter}} <br />
		</div>
   </body>
   <script type="text/javascript">
	const Counter = {
		data() {
			return {
				counter: 0
			}
		}
	}
	Vue.createApp(Counter).mount("#counter")
   </script>
</html>

运行结果如下:

我们已成功创建第一个Vue应用!这看起来跟渲染一个字符模板非常相似,但Vue在后台做了大量的工作。数据和DOM元素建立起了关联,并且所有都是响应式的。我们怎么知道是响应式的?看看下面这个例子,counter这个变量每秒增加,你将会看到界面上的DOM元素是如何变化的!

<!DOCTYPE html>
<html lang="en-US">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <title>vue demo1</title>
	<script src="https://unpkg.com/vue@next"></script>
   </head>
   <body>
		<div id="app">
			Counter:{{counter}} <br />
		</div>
   </body>
   <script type="text/javascript">
	const Counter = {
		data() {
			return {
				counter: 0
			}
		},
		mounted() {
			setInterval(() => {
			  this.counter++
			}, 1000)
	  }
	}
	Vue.createApp(Counter).mount("#app")
   </script>
</html>

除了文本插值,可以像这样绑定元素属性:

<!DOCTYPE html>
<html lang="en-US">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <title>vue demo1</title>
	<script src="https://unpkg.com/vue@next"></script>
   </head>
   <body>
		<div id="app">
			<span v-bind:title="message">
				鼠标放到我上面,将会看到动态绑定的title信息
			</span>
		</div>
   </body>
   <script type="text/javascript">
	const Counter = {
		data() {
			return {
				message: "页面载入时间为:"+ new Date().toLocaleString()
			}
		}
	}
	Vue.createApp(Counter).mount("#app")
   </script>
</html>

我们学习到了一些新的东西。你看到的v-bind属性我们称之为指令。指令是以v-打头表明是由Vue提供的特殊属性,你可能已经猜到了,他们可以响应式的渲染DOM。这里我们基本上可以说“这个实例是通过message这个变量动态的绑定到了html元素上”。

处理用户输入

为了让用户和界面进行交互,我们可以使用v-on指令绑定一个事件监听,调用在当前实例中定义的方法:

<!DOCTYPE html>
<html lang="en-US">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <title>vue demo1</title>
	<script src="https://unpkg.com/vue@next"></script>
   </head>
   <body>
		<div id="app">
			<span v-bind:title="message">
				{{message}}
				<br />
				<button v-on:click="reverseMessage">反转上文字</button>
			</span>
		</div>
   </body>
   <script type="text/javascript">
	const Counter = {
		data() {
			return {
				title: "页面载入时间为:"+ new Date().toLocaleString(),
				message: "鼠标放到我上面,将会看到动态绑定的title信息"
			}
		},
		methods: {
			reverseMessage() {
				this.message = this.message.split('').reverse().join('')
			}
		}
	}
	Vue.createApp(Counter).mount("#app")
   </script>
</html>

点击按钮后,message内容被反转为:

注意这个方法没有使用DOM就更新了界面上的内容 - 所有DOM都由Vue进行操作,而你的代码只要关注具体的业务逻辑即可。
同时Vue提供了v-model指令,可以轻而易举的实现表单文本框和界面元素(app state)的双向绑定:

<!DOCTYPE html>
<html lang="en-US">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <title>vue demo1</title>
	<script src="https://unpkg.com/vue@next"></script>
   </head>
   <body>
		<div id="app">
			<p>{{ message }} </p>
			<input v-model="message" />
		</div>
   </body>
   <script type="text/javascript">
	const Counter = {
		data() {
			return {
				message: "你好世界!"
			}
		},
	}
	Vue.createApp(Counter).mount("#app")
   </script>
</html>


(你可以想象一下,用jquery,你需要多少行代码来实现双向绑定?其实我不是黑jquery,当年jquery节省了我们大量时间调浏览器兼容性和可以调用一些强大的方法)

条件分支及循环

非常容易切换一个元素的显示状态:

<!DOCTYPE html>
<html lang="en-US">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <title>vue demo1</title>
	<script src="https://unpkg.com/vue@next"></script>
   </head>
   <body>
		<div id="app">
			<span v-if="seen">看的见我?看不见我?</span>
		</div>
   </body>
   <script type="text/javascript">
	const Counter = {
		data() {
			return {
				seen: true
			}
		},
	}
	Vue.createApp(Counter).mount("#app")
   </script>
</html>

(只需要控制seen变量为true或false就能显示/隐藏span标签)
这个示例演示了DOM元素不仅能绑定字符和属性,同时也可以绑定DOM结构(控制DOM的展示?),另外,Vue提供了强大的转场效果系统,当我们在界面上插入/更新/移除元素时会自动应用转场效果。

还有很多其他指令,每个都有自己独特的功能。例如v-for指令可以将一个数组的每个元素展示成一个列表:

<!DOCTYPE html>
<html lang="en-US">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <title>vue demo1</title>
	<script src="https://unpkg.com/vue@next"></script>
   </head>
   <body>
		<div id="app">
			<ul>
				<li v-for="(item,index) in todos">
					{{ item.week }} : {{ item.text }}
				</li>
			</ul>
		</div>
   </body>
   <script type="text/javascript">
	const app = {
		data() {
			return {
				todos: [
					{"week":"周一","text":"学习java"},
					{"week":"周二","text":"学习oracle"},
					{"week":"周三","text":"学习python"},
					{"week":"周四","text":"学习uni-app"},
					{"week":"周五","text":"看电影"},
					{"week":"周六","text":"休息"},
					{"week":"周日","text":"休息"}
				]
			}
		},
	}
	Vue.createApp(app).mount("#app")
   </script>
</html>

运行结果如下:

组件化

组件系统是Vue中另一个非常重要的概念,因为是一种抽像,允许我们使用小型 、自包含、可反复使用的组件构建大型应用。如果我们仔细想一想,几乎所有的用户界面都可以抽像成一个组件树。

Vue中,组件本质上是拥有预定义选项的实例。Vue中注册组件也很简单:像应创建应用对象一样创建组件,然后在父页面中components选项中进行定义 :

//js
// 创建Vue应用
const app = Vue.createApp(...)

// Define a new component called todo-item
app.component('todo-item', {
  template: `<li>This is a todo</li>`
})

// 挂载Vue应用
app.mount(...)

现在你就可以在其他页面的模板中调用这个组件了

<ol>
  <!-- 创建一个todo-item组件的实例 -->
  <todo-item></todo-item>
</ol>

但这样每个todo渲染的文字内容都是一样的,没有意思。我们可以从父页面传递数据到子组件。接下来让我们改造下组件定义来接收一个prop:

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

然后我们在使用组件的地方可以传递不同的todo参数:

<div id="todo-list-app">
  <ol>
    <!--
    现在我们提供含有todo-item的todo对象变量,
    这意味着组件内容是动态变化的。
    我们同时需要为每个组件指定一个“key”,后面再做解释。
    -->
    <todo-item
      v-for="item in groceryList"
      v-bind:todo="item"
      v-bind:key="item.id"
    ></todo-item>
  </ol>
</div>
const TodoList = {
  data() {
    return {
      groceryList: [
        { id: 0, text: '蔬菜' },
        { id: 1, text: '芝士' },
        { id: 2, text: '任何人类能吃的食品 }
      ]
    }
  }
}

const app = Vue.createApp(TodoList)

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

app.mount('#todo-list-app')

看一个完整的例子:

<html lang="en-US">
    <head>
      <meta charset="utf-8">
      <meta name="viewport" content="width=device-width,initial-scale=1">
      <title>vue demo1</title>
      <script src="https://unpkg.com/vue@next"></script>
     </head>
     <body>
          <div id="app">
              <ul>
                 <todo-item
                    v-for="(item,index) in todos"
                    v-bind:todo="item"
                    v-bind:key="index"
                 ></todo-item>
              </ul>
          </div>
     </body>
     <script type="text/javascript">
      const todoList = {
          data() {
              return {
                  todos: [
                      {"week":"周一","text":"学习java"},
                      {"week":"周二","text":"学习oracle"},
                      {"week":"周三","text":"学习python"},
                      {"week":"周四","text":"学习uni-app"},
                      {"week":"周五","text":"看电影"},
                      {"week":"周六","text":"休息"},
                      {"week":"周日","text":"休息"}
                  ]
              }
          }
      }
      const app = Vue.createApp(todoList)
      app.component('todo-item',{
          props: ['todo'],
          template: '<li>{{todo.week}}:{{todo.text}}</li>'
      })
      app.mount("#app")
     </script>
  </html>

这是一个非预想中的示例,但是我们已将应用分隔成两个单元,且父应用通过props接口合乎逻辑的分隔出了一个子组件,我们可以进一步的完善<todo-item>组件实现复杂的模板和逻辑而不影响父应用。
在大型应用中,有必要将整个应用分割成不同的组件使得开发更加便于管理。在后续章节中我们会更多的谈到组件,下面简单演示一个(想像)示例展示组件是如何在模板中使用的:

<div id="app">
  <app-nav></app-nav>
  <app-view>
    <app-sidebar></app-sidebar>
    <app-content></app-content>
  </app-view>
</div>

关于自定义标签

你可能已经注意到了,Vue组件和HTML的自定义标签非常像,属于Web 组件规则的一部分。这是因为Vue组件语法比Web组件规则更加宽松的模型。举个例子,Vue组件实现了插槽API和特殊属性。但是仍然有一些不同点:

  1. WEB组件已经被确定但不是所有浏览器能原生支持。Safari 10.1+,Chrome 54+ 和Firefox 63+ 原生已支持WEB组件。相对而言,Vue组件一如既往的在所有支持的浏览器中均能工作(兼容IE11及以上)。如果有必要,Vue组件还可以放置进一个原生的标签中。
  2. Vue组件提供了简单的定制标签提不具备的功能,突出的包括组件间数据流,标准事件通信以及构建工具集成。

即便Vue内部并不使用定制标签,但在使用和发布自定义标签时仍然具备很强的互操作性。Vue CLI同时也提供将Vue组件注册为原生自定义标签的支持。

准备好了吗?

我们已经对Vue.js核心功能做了简要的介绍 - 手册的剩余部分,我们将再次详细介绍并包含很多高级功能点和细节,所以,请务必通读该教程!

posted on 2021-02-26 12:07  zhouyu  阅读(281)  评论(0编辑  收藏  举报

导航