ThinkChat🤖让你学习和工作更高效,注册即送10W Token,即刻开启你的AI之旅 广告
可由jQuery平滑过渡到vue.js vue是一个兴起的前端js库,是一个精简的MVVM。从技术角度讲,Vue.js 专注于 MVVM 模型的 ViewModel 层。它通过双向数据绑定把 View 层和 Model 层连接了起来,通过对数据的操作就可以完成对页面视图的渲染。 jQuery是使用选择器($)选取DOM对象,对其进行赋值、取值、事件绑定等操作,其实和原生的HTML的区别只在于可以更方便的选取和操作DOM对象,而数据和界面是在一起的。比如需要获取label标签的内容:$("lable").val();,它还是依赖DOM元素的值。 Vue则是通过Vue对象将数据和View完全分离开来了。对数据进行操作不再需要引用相应的DOM对象,可以说数据和View是分离的,他们通过Vue对象这个vm实现相互的绑定。这就是传说中的MVVM。 使用jq需要拿到数据后操作dom元素来实现,vue直接用v-for来实现,不需要我们来操作dom元素。jquery就是类库,而vue是框架。 vue适用的场景:复杂数据操作的后台页面,表单填写页面。 jquery适用的场景:比如说一些html5的动画页面,一些需要js来操作页面样式的页面 然而二者也是可以结合起来一起使用的,vue侧重数据绑定,jquery侧重样式操作,动画效果等,则会更加高效率的完成业务需求 在使用vue的时候,ajax该如何选择: fetch.js fetch是基于Promise的,未来的趋势。 axios.js Vue 2.0 官方推荐。 [官方教程](https://vuejs.org/v2/guide) Vue (pronounced /vjuː/, like view) is a progressive framework for building user interfaces. 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.he official guide assumes intermediate level knowledge of HTML, CSS, and JavaScript. Vue does **not** support IE8 and below, because it uses ECMAScript 5 features that are un-shimmable in IE8. vue全家桶(`vue2.x` + `vue-router2.x` + `vuex`) [TOC] ## Important concept in Vue ### Declaratively render data/ Reactivity system /Data and Method At the core of Vue.js is a system that enables us to declaratively render data to the DOM using straightforward template syntax: ~~~html //html <div id="app"> {{ message }} </div> ~~~ ~~~javascript //js var app = new Vue({ el: '#app', data: { message: 'Hello Vue!' } }) ~~~ ### Directive (**`v-*`**) [[Vue Directive]](https://vuejs.org/v2/api/#Directives) Directives are prefixed with `v-` to indicate that they are special attributes provided by Vue, they apply special reactive behavior to the rendered DOM. eg: It is basically saying “keep this element’s title attribute up-to-date with the message property on the Vue instance.” ~~~html //html <div id="app-2"> <span v-bind:title="message"> Hover your mouse over me for a few seconds to see my dynamically bound title! </span> </div> ~~~ ~~~javascript //js var app2 = new Vue({ el: '#app-2', data: { message: 'You loaded this page on ' + new Date().toLocaleString() } }) ~~~ **`v-bind`**:, shorhand: `:` **`v-if`**: Conditionals **`v-for`**: Loops **`v-on`**: Handling User Input, shorhand: `@` **`v-model`**: two-way binding between form input and app state a breeze ### Component (**`Vue.component`**) #### reusable Since components are reusable Vue instances, they accept the same options as `new Vue`, such as `data`, `computed`, `watch`, `methods`, and lifecycle hooks. The only exceptions are a few root-specific options like `el`. ~~~ html <div id="components-demo"> <button-counter></button-counter> <button-counter></button-counter> <button-counter></button-counter> </div> ~~~ ~~~ javascript // Define a new component called button-counter Vue.component('button-counter', { data: function () { return { count: 0 } }, template: '<button v-on:click="count++">You clicked me {{ count }} times.</button>' }) //reused the 'button-counter' new Vue({ el: '#components-demo' }) ~~~ Notice that when clicking on the buttons, each one maintains its own, separate `count`. That’s because each time you use a component, a new instance of it is created. Vue defines the rule : a component’s `data` option must be a function, so that each instance can maintain an independent copy of the returned data object: ~~~ javasciprt data: function () { return { count: 0 } } ~~~ #### a tree of nested components ![](https://box.kancloud.cn/b5c08269dfc26ae6d7db3801e9efd296_1406x544.png) :-: a tree of nested components For example, you might have components for a header, sidebar, and content area, each typically containing other components for navigation links, blog posts, etc. There are two types of component registration: global and local. ~~~ javascript //global Vue.component('my-component-name', { // ... options ... }) ~~~ #### Passing Data to Child Components with `props` ~~~ javascript Vue.component('blog-post', { props: ['title'], template: '<h3>{{ title }}</h3>' }) ~~~ Once a prop is registered, you can pass data to it as a custom attribute, like this: ~~~html <blog-post title="My journey with Vue"></blog-post> <blog-post title="Blogging with Vue"></blog-post> <blog-post title="Why Vue is so fun"></blog-post> ~~~ In a typical app, however, you’ll likely have an array of posts in data: ~~~ javascript new Vue({ el: '#blog-post-demo', data: { posts: [ { id: 1, title: 'My journey with Vue' }, { id: 2, title: 'Blogging with Vue' }, { id: 3, title: 'Why Vue is so fun' } ] } }) ~~~ ~~~html <blog-post v-for="post in posts" v-bind:key="post.id" v-bind:title="post.title" ></blog-post> ~~~ refactor the <blog-post> component to accept a single post prop instead: ~~~ javascript Vue.component('blog-post', { props: ['post'], template: ` <div class="blog-post"> <h3>{{ post.title }}</h3> <div v-html="post.content"></div> </div> ` }) ~~~ ~~~html <blog-post v-for="post in posts" v-bind:key="post.id" v-bind:post="post" ></blog-post> ~~~ >[danger] The above example and some future ones use JavaScript’s template literal to make multi-line templates more readable. These are not supported by Internet Explorer (IE), so if you must support IE and are not transpiling (e.g. with Babel or TypeScript), use newline escapes instead. #### Sending Messages to Parents with `Events` Vue instances provide a custom events system to emit an event to the parent, we can call the built-in `$emit` method, passing the name of the event: `v-bind` ~~~html <div id="app"> <app-nav></app-nav> <app-view> <app-sidebar></app-sidebar> <app-content></app-content> </app-view> </div> <div id="app-7"> <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> ~~~ ~~~javascript Vue.component('todo-item', { // The todo-item component now accepts a // "prop", which is like a custom attribute. // This prop is called todo. props: ['todo'], template: '<li>{{ todo.text }}</li>' }) var app7 = new Vue({ el: '#app-7', data: { groceryList: [ { id: 0, text: 'Vegetables' }, { id: 1, text: 'Cheese' }, { id: 2, text: 'Whatever else humans are supposed to eat' } ] } }) ~~~ ### Vue Instance Every Vue application starts by creating a new Vue instance with the Vue function: ~~~javascript var vm = new Vue({ // options }) ~~~ For reference, you can also browse the full list of options in the [API reference](https://vuejs.org/v2/api/#Options-Data). All Vue components are also Vue instances, and so accept the same options object (except for a few root-specific options). ### Instance Lifecycle All lifecycle hooks are called with their this context pointing to the Vue instance invoking it. ![a diagram for the instance lifecycle](https://box.kancloud.cn/6f2c97f045ba988851b02056c01c8d62_1200x3039.png) :-: a diagram for the instance lifecycle >[danger] Don’t use arrow functions on an options property or callback, such as `created: () => console.log(this.a)` or `vm.$watch('a', newValue => this.myMethod())`. Since arrow functions are bound to the parent context, `this` will not be the Vue instance as you’d expect, often resulting in errors such as `Uncaught TypeError: Cannot read property of undefined` or `Uncaught TypeError: this.myMethod is not a function`. ### Template Syntax * Text ~~~html <span>Message: {{ msg }}</span> //perform one-time interpolations that do not update on data change by using the v-once directive, but keep in mind this will also affect any other bindings on the same node <span v-once>This will never change: {{ msg }}</span> ~~~ * Raw HTML `v-html` ~~~html <p>Using mustaches: {{ rawHtml }}</p> <p>Using v-html directive: <span v-html="rawHtml"></span></p> ~~~ >[danger] Dynamically rendering arbitrary HTML on your website can be very dangerous because it can easily lead to XSS vulnerabilities. Only use HTML interpolation on trusted content and never on user-provided content. * Attributes `v-bind` ~~~html <div v-bind:id="dynamicId"></div> <button v-bind:disabled="isButtonDisabled">Button</button> ~~~ If isButtonDisabled has the value of `null`, `undefined`, or `false`, the `disabled` attribute will not even be included in the rendered `<button>` element. * Using JavaScript Expressions ~~~html {{ number + 1 }} {{ ok ? 'YES' : 'NO' }} {{ message.split('').reverse().join('') }} <div v-bind:id="'list-' + id"></div> <!-- this is a statement, not an expression: --> {{ var a = 1 }} <!-- flow control won't work either, use ternary expressions --> {{ if (ok) { return message } }} ~~~ >[ danger] Template expressions are sandboxed and only have access to a whitelist of globals such as `Math` and `Date`. You should not attempt to access user defined globals in template expressions. * Arguments for `v-on` and `v-bind` Some directives can take an “argument”, denoted by a colon after the directive name. For example, the `v-bind` directive is used to reactively update an HTML attribute: ~~~html <a v-bind:href="url"> ... </a> <a v-on:click="doSomething"> ... </a> ~~~ The `v-on` directive listens to DOM events. * Modifiers for `v-on` and `v-model` Modifiers are special postfixes denoted by a dot, which indicate that a directive should be bound in some special way. For example, the `.prevent` modifier tells the `v-on` directive to call event.preventDefault() on the triggered event: ~~~html <form v-on:submit.prevent="onSubmit"> ... </form> ~~~ * Shorthand ~~~html <!-- full syntax --> <a v-bind:href="url"> ... </a> <!-- shorthand --> <a :href="url"> ... </a> <!-- full syntax --> <a v-on:click="doSomething"> ... </a> <!-- shorthand --> <a @click="doSomething"> ... </a> ~~~ The shorthand syntaxs `:` and `@` are totally optional, they are valid chars for attribute names and all Vue.js supported browsers can parse it correctly. ### Computed Caching vs Methods ~~~html <p>Reversed message: "{{ reverseMessage() }}"</p> ~~~ ~~~javascript var vm = new Vue({ el: '#example', data: { message: 'Hello' }, computed: { // a computed getter reversedMessage: function () { // `this` points to the vm instance return this.message.split('').reverse().join('') } } }) // in component methods: { reverseMessage: function () { return this.message.split('').reverse().join('') } } ~~~ Computed properties are cached based on their dependencies. A computed property will only re-evaluate when some of its dependencies have changed. In comparison, a method invocation will always run the function whenever a re-render happens. Why do we need caching? Imagine we have an expensive computed property A, which requires looping through a huge Array and doing a lot of computations. Then we may have other computed properties that in turn depend on A. Without caching, we would be executing A’s getter many more times than necessary! In cases where you do not want caching, use a method instead. ### Watchers ~~~html <div id="watch-example"> <p> Ask a yes/no question: <input v-model="question"> </p> <p>{{ answer }}</p> </div> <!-- Since there is already a rich ecosystem of ajax libraries --> <!-- and collections of general-purpose utility methods, Vue core --> <!-- is able to remain small by not reinventing them. This also --> <!-- gives you the freedom to use what you're familiar with. --> <script src="https://cdn.jsdelivr.net/npm/axios@0.12.0/dist/axios.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/lodash@4.13.1/lodash.min.js"></script> <script> var watchExampleVM = new Vue({ el: '#watch-example', data: { question: '', answer: 'I cannot give you an answer until you ask a question!' }, watch: { // whenever question changes, this function will run question: function (newQuestion, oldQuestion) { this.answer = 'Waiting for you to stop typing...' this.debouncedGetAnswer() } }, created: function () { // _.debounce is a function provided by lodash to limit how // often a particularly expensive operation can be run. // In this case, we want to limit how often we access // yesno.wtf/api, waiting until the user has completely // finished typing before making the ajax request. To learn // more about the _.debounce function (and its cousin // _.throttle), visit: https://lodash.com/docs#debounce this.debouncedGetAnswer = _.debounce(this.getAnswer, 500) }, methods: { getAnswer: function () { if (this.question.indexOf('?') === -1) { this.answer = 'Questions usually contain a question mark. ;-)' return } this.answer = 'Thinking...' var vm = this axios.get('https://yesno.wtf/api') .then(function (response) { vm.answer = _.capitalize(response.data.answer) }) .catch(function (error) { vm.answer = 'Error! Could not reach the API. ' + error }) } } }) </script> ~~~ In this case, using the `watch` option allows us to perform an asynchronous operation (accessing an API), limit how often we perform that operation, and set intermediary states until we get a final answer. None of that would be possible with a computed property. In addition to the `watch` option, you can also use the imperative [vm.$watch API](https://vuejs.org/v2/api/#vm-watch). ## Event Handling (**`v-on`**) `v-on`: directive to listen to DOM events and run some JavaScript when they’re triggered. 1. `$event`: the original DOM event. 2. event modifiers * <span style="color: #e96900;">`.stop`</span> * <span style="color:#e96900;">`.prevent `</span> * <span style="color:#e96900;">`.capture `</span> * <span style="color:#e96900;">`.self `</span> * <span style="color:#e96900;">`.once `</span> * <span style="color:#e96900;">`.passive`</span> In order to call <span style="color: #e96900;">`event.preventDefault()`</span> or <span style="color: #e96900;">` event.stopPropagation()`</span> , recall the above modifiers are directive postfixes denoted by a dot. ~~~ html <!-- the click event's propagation will be stopped --> <a v-on:click.stop="doThis"></a> <!-- the submit event will no longer reload the page --> <form v-on:submit.prevent="onSubmit"></form> <!-- modifiers can be chained --> <a v-on:click.stop.prevent="doThat"></a> <!-- just the modifier --> <form v-on:submit.prevent></form> <!-- use capture mode when adding the event listener --> <!-- i.e. an event targeting an inner element is handled here before being handled by that element --> <div v-on:click.capture="doThis">...</div> <!-- only trigger handler if event.target is the element itself --> <!-- i.e. not from a child element --> <div v-on:click.self="doThat">...</div> <!-- the click event will be triggered at most once --> <a v-on:click.once="doThis"></a> <!-- the scroll event's default behavior (scrolling) will happen --> <!-- immediately, instead of waiting for `onScroll` to complete --> <!-- in case it contains `event.preventDefault()` --> <div v-on:scroll.passive="onScroll">...</div> ~~~ >[danger] Don’t use `.passive` and `.prevent` together, because `.prevent` will be ignored and your browser will probably show you a warning. Remember, `.passive` communicates to the browser that you don’t want to prevent the event’s default behavior. 3. Key Modifiers Vue also allows adding key modifiers for v-on when listening for key events, full list of key modifier aliases: * <span style="color: #e96900;">`.enter `</span> * <span style="color: #e96900;">`.tab `</span> * <span style="color: #e96900;">`.delete`</span> (captures both “Delete” and “Backspace” keys) * <span style="color: #e96900;">`.esc `</span> * <span style="color: #e96900;">`.space `</span> * <span style="color: #e96900;">`.up `</span> * <span style="color: #e96900;">`.down `</span> * <span style="color: #e96900;">`.left `</span> * <span style="color: #e96900;">`.right`</span> eg: when 'enter' key is pressed, call function ‘submit’. ~~~html <!-- code 1--> <input v-on:keyup.enter="submit"> <!-- code 2--> <input v-on:keyup.13="submit"> <!--code 3, also works for shorthand --> <input @keyup.enter="submit"> ~~~ Automatic Key Modifiers ~~~html <input @keyup.page-down="onPageDown"> ~~~ In the above example, the handler will only be called if `$event.key === 'PageDown'`. Because any valid key names exposed via `KeyboardEvent.key` as modifiers by converting them to kebab-case. System Modifier Keys * <span style="color: #e96900;">`.ctr `</span> * <span style="color: #e96900;">`.alt `</span> * <span style="color: #e96900;">`.shift`</span> * <span style="color: #e96900;">`.meta`</span> ~~~html <!-- Alt + C --> <input @keyup.alt.67="clear"> <!-- Ctrl + Click --> <div @click.ctrl="doSomething">Do something</div> ~~~ >[danger] Note that modifier keys are different from regular keys and when used with `keyup` events, they have to be pressed when the event is emitted. In other words, `keyup.ctrl` will only trigger if you release a key while holding down `ctrl`. It won’t trigger if you release the `ctrl` key alone. If you do want such behaviour, use the `keyCode` for `ctrl` instead: `keyup.17`. >[] Note: On Macintosh keyboards, meta is the command key (⌘). On Windows keyboards, meta is the windows key (⊞). On Sun Microsystems keyboards, meta is marked as a solid diamond (◆). On certain keyboards, specifically MIT and Lisp machine keyboards and successors, such as the Knight keyboard, space-cadet keyboard, meta is labeled “META”. On Symbolics keyboards, meta is labeled “META” or “Meta”. `.exact` Modifier This modifier allows control of the exact combination of system modifiers needed to trigger an event. ~~~html <!-- this will fire even if Alt or Shift is also pressed --> <button @click.ctrl="onClick">A</button> <!-- this will only fire when Ctrl and no other keys are pressed --> <button @click.ctrl.exact="onCtrlClick">A</button> <!-- this will only fire when no system modifiers are pressed --> <button @click.exact="onClick">A</button> ~~~ Mouse Button Modifiers * <span style="color: #e96900;">`.middle `</span> * <span style="color: #e96900;">`.left `</span> * <span style="color: #e96900;">`.right`</span> These modifiers restrict the handler to events triggered by a specific mouse button. ## Form Input Bindings (**`v-model`**) `v-model` directive is used to create two-way data bindings on form input, textarea, and select elements. It automatically picks the correct way to update the element based on the input type. Although a bit magical, `v-model` is essentially syntax sugar for updating data on user input events, plus special care for some edge cases. >[danger] `v-model` will ignore the initial `value`, `checked` or `selected` attributes found on any form elements. It will always treat the Vue instance data as the source of truth. You should declare the initial value on the JavaScript side, inside the `data` option of your component. >[danger] For languages that require an IME (Chinese, Japanese, Korean etc.), you’ll notice that `v-model` doesn’t get updated during IME composition. If you want to cater for these updates as well, use `input` event instead. ### Basic Usage * Text ~~~ html <input v-model="message" placeholder="edit me"> <p>Message is: {{ message }}</p> ~~~ * Multiline text ~~~ html <span>Multiline message is:</span> <p style="white-space: pre-line;">{{ message }}</p> <br> <textarea v-model="message" placeholder="add multiple lines"></textarea> ~~~ * Checkbox ~~~ html <!-- Single checkbox, boolean value: --> <input type="checkbox" id="checkbox" v-model="checked"> <label for="checkbox">{{ checked }}</label> <!-- Multiple checkboxes, bound to the same Array: --> <div id='example-3'> <input type="checkbox" id="jack" value="Jack" v-model="checkedNames"> <label for="jack">Jack</label> <input type="checkbox" id="john" value="John" v-model="checkedNames"> <label for="john">John</label> <input type="checkbox" id="mike" value="Mike" v-model="checkedNames"> <label for="mike">Mike</label> <br> <span>Checked names: {{ checkedNames }}</span> </div> ~~~ ~~~ javascript new Vue({ el: '#example-3', data: { checkedNames: [] } }) ~~~ * Radio ~~~ html <input type="radio" id="one" value="One" v-model="picked"> <label for="one">One</label> <br> <input type="radio" id="two" value="Two" v-model="picked"> <label for="two">Two</label> <br> <span>Picked: {{ picked }}</span> ~~~ * Select Single select: ~~~ html <select v-model="selected"> <option disabled value="">Please select one</option> <option>A</option> <option>B</option> <option>C</option> </select> <span>Selected: {{ selected }}</span> ~~~ ~~~ javascript new Vue({ el: '...', data: { selected: '' } }) ~~~ Multiple select (bound to Array): ~~~ html <select v-model="selected" multiple> <option>A</option> <option>B</option> <option>C</option> </select> <br> <span>Selected: {{ selected }}</span> ~~~ Dynamic options rendered with `v-for`: ~~~ html <select v-model="selected"> <option v-for="option in options" v-bind:value="option.value"> {{ option.text }} </option> </select> <span>Selected: {{ selected }}</span> ~~~ ~~~ javascript new Vue({ el: '...', data: { selected: 'A', options: [ { text: 'One', value: 'A' }, { text: 'Two', value: 'B' }, { text: 'Three', value: 'C' } ] } }) ~~~ ### Value Bindings (`v-model` / `v-bind`) For radio, checkbox and select options, the `v-model` binding values are usually static strings (or booleans for checkbox): ~~~ html <!-- `picked` is a string "a" when checked --> <input type="radio" v-model="picked" value="a"> <!-- `toggle` is either true or false --> <input type="checkbox" v-model="toggle"> <!-- `selected` is a string "abc" when the first option is selected --> <select v-model="selected"> <option value="abc">ABC</option> </select> ~~~ using `v-bind` allows us to bind the input value to non-string values. * radio ~~~ html <input type="radio" v-model="pick" v-bind:value="a"> ~~~ ~~~ javascript // when checked: vm.pick === vm.a ~~~ * select ~~~ html <select v-model="selected"> <!-- inline object literal --> <option v-bind:value="{ number: 123 }">123</option> </select> ~~~ ~~~ javascript // when selected: typeof vm.selected // => 'object' vm.selected.number // => 123 ~~~ ### Modifiers (`.lazy`, `,number`, `.trim`) ~~~ html <!-- synced after "change" instead of "input" --> <input v-model.lazy="msg" > <!-- user input to be automatically typecast as a number --> <input v-model.number="age" type="number"> <!-- user input to be trimmed automatically--> <input v-model.trim="msg"> ~~~ By default, `v-model` syncs the input with the data after each `input` event (with the exception of IME composition as stated above). You can add the lazy modifier to instead sync after `change` events. ### `v-model` with Components Vue components allow you to build reusable inputs with completely customized behavior. These inputs even work with `v-model`! ## note ### 在Vue中使用jQuery ~~~ html <!DOCTYPE html> <html lang="en"> <head>     <meta charset="UTF-8">     <script type="text/javascript" src="../assets/js/vue.js"></script>     <script type="text/javascript" src="../assets/js/jquery-3.1.1.min.js"></script>     <title>Early Examples Demo</title> </head> <body>     <h1>Early Examples Demo</h1>     <hr>     <div id="app">         {{message}}     </div>       <script type="text/javascript">         var app=new Vue({             el:'#app',             data:{                 message:'hello Vue!'             },             //在Vue中使用jQuery             mounted:function(){                 $('#app').html('我是jQuery!');             }         })     </script> </body> </html> --------------------- 作者:xiaohanzhu000 来源:CSDN 原文:https://blog.csdn.net/xiaohanzhu000/article/details/80896710 版权声明:本文为博主原创文章,转载请附上博文链接! ~~~