阅读 167

[翻译] vue3指南—02介绍

What is Vue.js? Vue.js是什么?

Vue (pronounced /vjuː/, like view) is a progressive framework for building user interfaces. Unlike other monolithic frameworks, Vue is designed from the ground up to be incrementally adoptable. The core library is focused on the view layer only, and is easy to pick up and integrate with other libraries or existing projects. On the other hand, Vue is also perfectly capable of powering sophisticated Single-Page Applications when used in combination with modern tooling and supporting libraries.

Vue(读/vjuː/,像view~) 是一个 构建界面的 渐进式框架(framework). 一方面,和其他 (monolithic framework)单片层框架不一样的是, Vue完完全全(from the ground up)是能够增量使用的.核心库(core library)只聚焦视图层, 很容易学而且很容易和其他库/已有项目结合使用. 另一方面, 当与一些现代工具链和相关支持类库合作开发时,Vue完全有能力处理(powering)大型复杂单页应用.

If you’d like to learn more about Vue before diving in, we created a video walking through the core principles and a sample project.

在深入学习Vue前,你还想了解更多的话,我们有一个视频——大致展示了核心原理并给了个小demo项目.

If you are an experienced frontend developer and want to know how Vue compares to other libraries/frameworks, check out the Comparison with Other Frameworks.

如果你是一个有经验的前端,想知道Vue和其他框架/库有什么不一样的.请看与其他框架比较

开始

TIP 提示

The official guide assumes intermediate level knowledge of HTML, CSS, and JavaScript. If you are totally new to frontend development, it might not be the best idea to jump right into a framework as your first step - grasp the basics then come back! Prior experience with other frameworks helps, but is not required. 这官方指南是当你对HTML,CSS,JS相关知识有相当水平的. 如果你完全不懂前端开发,直接接触这种前端框架是不合适的.去学一些基本知识然后再来看这个.对其他框架有经验是好事,但也没必要.

The easiest way to try out Vue.js is using the Hello World example. Feel free to open it in another tab and follow along as we go through some basic examples

最简单的尝试Vue的方法——HelloWorld例子——这里. 👈新标签打开这个连接,然后跟着这个指南一起撸下去.

The Installation page provides more options of installing Vue. Note: We do not recommend that beginners start with vue-cli, especially if you are not yet familiar with Node.js-based build tools.

上一个安装页面提供了很多安装vue的方式. 注意,不建议初学者直接从vue-cli开始.特别是你还不熟悉那些基于node.js的打包工具链.

Declarative Rendering 声明式渲染~ 😵

At the core of Vue.js is a system that enables us to declaratively render data to the DOM using straightforward template syntax:

Vue的最核心是一个这样的系统👉. 让我们使用明确的/直白的/简单明了的template语法,声明式地在Dom上渲染Data/数据.

<div id="counter">
  Counter: {{ counter }}
</div>
复制代码
// 
const Counter = {
  data() {
    return {
      counter: 0
    }
  }
}

Vue.createApp(Counter).mount('#counter')
复制代码

We have already created our very first Vue app! This looks pretty similar to rendering a string template, but Vue has done a lot of work under the hood. The data and the DOM are now linked, and everything is now reactive. How do we know? Take a look at the example below where counter property increments every second and you will see how rendered DOM changes:

好的~已经成功创建第一个vue应用了!这跟渲染一个简单字符串模版很像,但Vue在底层做了很多事情的. 现在Dom 和 data是 连接起来的了,并且所有内容都是响应式的. 来试试看?看下接下来这个 counter属性按秒自增的例子,并看看Dom怎么变化的:

const CounterApp = {
  data() {
    return {
      counter: 0
    }
  },
  mounted() {
    setInterval(() => {
      this.counter++
    }, 1000)
  }
}
复制代码

In addition to text interpolation, we can also bind element attributes like this:

除了文本插入,还可以绑定元素属性:

<div id="bind-attribute">
  <span v-bind:title="message">
    Hover your mouse over me for a few seconds to see my dynamically bound
    title!
  </span>
</div>
复制代码
const AttributeBinding = {
  data() {
    return {
      message: 'You loaded this page on ' + new Date().toLocaleString()
    }
  }
}

Vue.createApp(AttributeBinding).mount('#bind-attribute')
复制代码

Here we're encountering something new. The v-bind attribute you're seeing is called a directive. Directives are prefixed with v- to indicate that they are special attributes provided by Vue, and as you may have guessed, they apply special reactive behavior to the rendered DOM. Here we are basically saying "keep this element's title attribute up-to-date with the message property on the current active instance."

这里,我们遇到了些新知识. 你看到的这个 v-bind属性 可以叫做一个 指令(directive). 他们(指令们)的v-前缀 说明 他们是Vue特有的属性. 你就开始猜了,他们(指令)把特殊地响应式行为用于渲染dom. 这里可以这么理解, 保持元素上的title属性(attribute)和当前实例上的message属性(property)保持同步. (你或许会问,attribute/property的问题....Object's property has some attributes...我也不知道怎么翻译比较合适,见困惑[3])

Handling User Input

To let users interact with your app, we can use the v-on directive to attach event listeners that invoke methods on our instances:

为了人机交互,可以来用v-on指令绑定event listeners——就能调用(invoke)我们实例上的方法们了~.(纠结了一下是再说 实例上的方法 还是 把listeners绑定到实例上 呢...)

<div id="event-handling">
  <p>{{ message }}</p>
  <button v-on:click="reverseMessage">Reverse Message</button>
</div>
复制代码
const EventHandling = {
  data() {
    return {
      message: 'Hello Vue.js!'
    }
  },
  methods: {
    reverseMessage() {
      this.message = this.message
        .split('')
        .reverse()
        .join('')
    }
  }
}

Vue.createApp(EventHandling).mount('#event-handling')
复制代码

Note that in this method we update the state of our app without touching the DOM - all DOM manipulations are handled by Vue, and the code you write is focused on the underlying logic.

注意了⚠️. 在方法(reverseMessage())里面,我们更新了应用(vue.createApp)的状态(state of app就理解成页面变啦~),但我们并没有去操作dom,甚至都没管过dom. 所有的dom操作都交给Vue.你的代码只管处理背后逻辑(让vue来去操心dom渲染更新的事儿.)

Vue also provides the v-model directive that makes two-way binding between form input and app state a breeze:

Vue也提供了一个v-model指令.实现双向绑定.用户输入应用的状态间的绑定.轻松愉快~(make binding a breeze...🤧)

<div id="two-way-binding">
  <p>{{ message }}</p>
  <input v-model="message" />
</div>
复制代码
const TwoWayBinding = {
  data() {
    return {
      message: 'Hello Vue!'
    }
  }
}

Vue.createApp(TwoWayBinding).mount('#two-way-binding')
复制代码

Conditionals and Loops 条件和循环

It's easy to toggle the presence of an element, too

切换元素是否显示,很简单:

<div id="conditional-rendering">
  <span v-if="seen">Now you see me</span>
</div>
复制代码
const ConditionalRendering = {
  data() {
    return {
      seen: true
    }
  }
}

Vue.createApp(ConditionalRendering).mount('#conditional-rendering')
复制代码

This example demonstrates that we can bind data to not only text and attributes, but also the structure of the DOM. Moreover, Vue also provides a powerful transition effect system that can automatically apply transition effects when elements are inserted/updated/removed by Vue.

这里例子表明.Vue不仅绑定 文本和属性(attributes)(理解成标签里面的那些东西),而且绑定dom结构本身. 再而且,Vue还提供了强劲的transition效果系统(....)——当你操作这些dom结构元素,让dom插入,更新,删除(curd...)的时候,你就可以用这些效果来玩儿了. (至于怎么玩..🔗four-oh-four..对不起🧎‍♀️)

There are quite a few other directives, each with its own special functionality. For example, the v-for directive can be used to display a list of items using the data from an Array:

下面有些其他的指令,各有各的功能.比如v-for用来展示数组数据:

<div id="list-rendering">
  <ol>
    <li v-for="todo in todos">
      {{ todo.text }}
    </li>
  </ol>
</div>
复制代码
const ListRendering = {
  data() {
    return {
      todos: [
        { text: 'Learn JavaScript' },
        { text: 'Learn Vue' },
        { text: 'Build something awesome' }
      ]
    }
  }
}

Vue.createApp(ListRendering).mount('#list-rendering')
复制代码

Composing with Components 拿组件们来编曲了~

The component system is another important concept in Vue, because it's an abstraction that allows us to build large-scale applications composed of small, self-contained, and often reusable components. If we think about it, almost any type of application interface can be abstracted into a tree of components:

组件系统是另外一个重要概念.可以让我们像拼积木一样,用一个个小的,独立的,往往可复用的组件 构建出大型应用.既然说像拼积木,那么它就是一个抽象概念了👌.想想看,几乎所有应用界面可以抽象成一颗组件树𐂷.

In Vue, a component is essentially an instance with pre-defined options. Registering a component in Vue is straightforward: we create a component object as we did with App objects and we define it in parent's components option:

Vue里, 一个组件其实就是一个实例(当然这个实例有一些提前定义好的options). 注册一个组件很简单/直接/明了: 创建一个组件对象,像之前创建app对象那样;然后把这个组件对象放到你想放到的组件option里去.然你放进去的这个组件就成了儿子,被塞的那个组件就成了爸爸.

// Create Vue application
const app = Vue.createApp(...)

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

// Mount Vue application
app.mount(...)
复制代码

Now you can compose it in another component's template:

在其他模版里使用它~

<ol>
  <!-- Create an instance of the todo-item component -->
  <todo-item></todo-item>
</ol>
复制代码

But this would render the same text for every todo, which is not super interesting. We should be able to pass data from the parent scope into child components. Let's modify the component definition to make it accept a prop: 有个问题,这样只能渲染出相同文本内容的todo组件,就很蠢. 我们应该可以从爸爸那里传值到儿子那里. 让我们改改,让这个组件能接受一个prop(你看这里用的是property,就没有用attribute).

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

Now we can pass the todo into each repeated component using v-bind: 此时,我们用v-bindtodo传给每个重复的组件.(回顾一下👸,上一个我们用v-bind是在哪里...是改title的时候,那个span的attribute..)

<div id="todo-list-app">
  <ol>
    <!--
      Now we provide each todo-item with the todo object
      it's representing, so that its content can be dynamic.
      We also need to provide each component with a "key",
      which will be explained later.
    -->
    <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: 'Vegetables' },
        { id: 1, text: 'Cheese' },
        { id: 2, text: 'Whatever else humans are supposed to eat' }
      ]
    }
  }
}

const app = Vue.createApp(TodoList)

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

app.mount('#todo-list-app')
复制代码

This is a contrived example, but we have managed to separate our app into two smaller units, and the child is reasonably well-decoupled from the parent via the props interface. We can now further improve our component with more complex template and logic without affecting the parent app. 这是一个刻意搞出来的例子,但是说明了一些问题——确实能把应用拆分成更小的模块,而且每个小模块也能通过props接口和爸爸模块很好的解耦. 现在可以进一步开发<todo-item>组件,并且还不会影响它的父组件.

In a large application, it is necessary to divide the whole app into components to make development manageable. We will talk a lot more about components later in the guide, but here's an (imaginary) example of what an app's template might look like with components:

在大型应用里,这种拆分整个应用为组件们懂的行为是很有必要的,可以是的开发流程可控/易控. 接下来回聊更多关于组件的事儿.但现在先给你们看看一个由组件组成的应用大概长什么样子. 一个很(想)好(象)的例子:

<div id="app">
  <app-nav></app-nav>
  <app-view>
    <app-sidebar></app-sidebar>
    <app-content></app-content>
  </app-view>
</div>
复制代码

Relation to Custom Elements 和自定义元素的关系

You may have noticed that Vue components are very similar to Custom Elements, which are part of the Web Components Spec. That's because Vue's component syntax is loosely modeled after the spec. For example, Vue components implement the Slot API and the is special attribute. However, there are a few key differences:

你可能已经注意到了,Vue组件和自定义元素很像. 因为Vue组件语法是按照这个(Web Components Spec)规范松散建模的.比如, 实现了Slot API和特殊属性(attribute)is的同时,又有一些区别:

1.The Web Components Spec has been finalized but is not natively implemented in every browser. Safari 10.1+, Chrome 54+ and Firefox 63+ natively support web components. In comparison, Vue components work consistently in all supported browsers (IE11 with compatibility build and above). When needed, Vue components can also be wrapped inside a native custom element

1.The Web Components Spec这规范已经最终敲定了.但是每个浏览器原生实现的程度不一样.Safari 10.1+, Chrome 54+ ,Firefox 63+他们原生支持这些组件. 相比而言,Vue组件在所有支持的浏览器中都可以一致的工作(IE11 with compatibility build and above).

2.Vue components provide important features that are not available in plain custom elements, most notably cross-component data flow, custom event communication and build tool integrations.

2.Vue有一些了不起的features——是那些自定义元素没有的.其中最牛批的是 cross-component data flowcustom event communicationbuild tool integrations.

Ready for More? 再来点?

We've briefly introduced the most basic features of Vue.js core - the rest of this guide will cover them and other advanced features with much finer details, so make sure to read through it all!!

好了,已经大概介绍了Vue核心中最基础的特征了.剩下部分会更详细介绍这些和其他高级内容.答应我,读完它,好吗?好的!!

困惑点

  1. monolithic frameworks
  2. declarative programming
  3. Attribute VS Property