v-if ensures that event listeners and child components inside the conditional block are properly destroyed and re-created during toggles. I
f the condition is false on initial render, it will not do anything - the conditional block won’t be rendered until the condition becomes true for the first time.
vs
v-show The usage is largely the same to v-if. The element is always rendered regardless of initial condition, with CSS-based toggling.(不論怎樣都會render, 他只是利用css使顯示不同)
Note that v-show doesn’t support the <template> element, nor does it work with v-else.
比較後的結論 v-if has higher toggle costs while v-show has higher initial render costs. So prefer v-show if you need to toggle something very often, and prefer v-if if the condition is unlikely to change at runtime.
※v-if 与 v-for 一起使用 is not recommended. 首先了解一下 filter vs map (他們大致相同,只在return內容為判別式時,會不同)
Filter receives the same arguments as map, and works very similarly. The only difference is that the callback needs to return either true or false. If it returns true then the array keeps that element and if it returns false the element is filtered out.
下面舉例:
再來進入正題, To filter items in a list (e.g. v-for="user in users" v-if="user.isActive"). In these cases, replace users with a new computed property that returns your filtered list (e.g. activeUsers). To avoid rendering a list if it should be hidden (e.g. v-for="user in users" v-if="shouldShowUsers"). In these cases, move the v-if to a container element (e.g. ul, ol).
var vm = new Vue({ data: { items: ['a', 'b', 'c'] }})vm.items[1] = 'x'// 不是响应性的vm.items.length = 2// 不是响应性的
再一次由於 JavaScript 的限制,Vue 不能检测屬性(property)的添加與刪除:
var vm = new Vue({ data: { a: 1 }})// `vm.a` is now reactivevm.b = 2// `vm.b` is NOT reactive
Vue does not allow dynamically adding new root-level reactive properties to an already created instance. However, it’s possible to add reactive properties to a nested object using the Vue.set(object, key, value) method.
如下例子
var vm = new Vue({ data: { userProfile: { name: 'Anika' } }})
You could add a new age property to the nested userProfile object with:
Sometimes you may want to assign a number of new properties to an existing object, for example using Object.assign() or _.extend(). In such cases, you should create a fresh object with properties from both objects. So instead of:
The result equals the input argument (no conversion).
Number
The result is false if the argument is +0, −0, or NaN;
otherwise the result is true.
String
The result is false if the argument is the empty String (its length is zero);
otherwise the result is true.
Object
true.
This is the formula JavaScript uses to classify values as truthy (true, "potato", 36, [1,2,4]and {a:16}) or falsey (false, 0, "", null and undefined).(我自己的想法是除了這幾個以外,都是true,這樣比較容易記)
<divid="example-2"><!-- `greet` is the name of a method defined below --><buttonv-on:click="greet">Greet</button></div>
var example2 = new Vue({ el: '#example-2', data: { name: 'Vue.js' },// define methods under the `methods` object methods: { greet: function (event) {// `this` inside methods points to the Vue instance alert('Hello ' + this.name + '!')// `event` is the native DOM eventif (event) { //Event Objects: When an event occur in HTML, the event belongs to a certain event object, like a mouse click event belongs to the MouseEvent object. alert(event.target.tagName) //BUTTON } } }})// you can invoke methods in JavaScript tooexample2.greet() // => 'Hello Vue.js!' ,不執行 if (event)的內容,因為該event 是指event object,在此處為[object MouseEvent]
Sometimes we also need to access the original DOM event in an inline statement handler. You can pass it into a method using the special $event variable:
<buttonv-on:click="warn('Form cannot be submitted yet.', $event)"> Submit</button>
// ...methods: { warn: function (message, event) {// now we have access to the native eventif (event) event.preventDefault() alert(message) }}
Unlike the other modifiers, which are exclusive to native DOM events, the .oncemodifier can also be used on component events. If you haven’t read about components yet, don’t worry about this for now.
Event Modifiers
.stop
.prevent
.capture
.self
.once
.passive
<!-- the click event's propagation will be stopped --><av-on:click.stop="doThis"></a><!-- the submit event will no longer reload the page --><formv-on:submit.prevent="onSubmit"></form><!-- modifiers can be chained --><av-on:click.stop.prevent="doThat"></a><!-- just the modifier --><formv-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 --><divv-on:click.capture="doThis">...</div><!-- only trigger handler if event.target is the element itself --><!-- i.e. not from a child element --><divv-on:click.self="doThat">...</div>
<!-- the click event will be triggered at most once --><av-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()` --><divv-on:scroll.passive="onScroll">...</div>
5.5 Key Modifiers → v-on:keyup.xxx When listening for keyboard events, we often need to check for common key codes.
<!-- only call `vm.submit()` when the `keyCode` is 13 --><inputv-on:keyup.13="submit">
Vue provides aliases for the most commonly used keys:
.enter
.tab
.delete (captures both “Delete” and “Backspace” keys)
.esc
.space
.up
.down
.left
.right
<!-- same as above --><inputv-on:keyup.enter="submit"><!-- also works for shorthand --><input @keyup.enter="submit">
let textarea = document.getElementById('test-target'),
consoleLog = document.getElementById('console-log'),
btnClearConsole = document.getElementById('btn-clear-console');functionlogMessage(message){let p = document.createElement('p');
p.appendChild(document.createTextNode(message));
consoleLog.appendChild(p);}
textarea.addEventListener('keydown',(e)=>{if(!e.repeat)logMessage(`first keydown event. key property value is "${e.key}"`);
else
logMessage(`keydown event repeats. key property value is "${e.key}"`);});
textarea.addEventListener('beforeinput',(e)=>{logMessage(`beforeinput event. you are about inputing "${e.data}"`);});
textarea.addEventListener('input',(e)=>{logMessage(`input event. you have just inputed "${e.data}"`);});
textarea.addEventListener('keyup',(e)=>{logMessage(`keyup event. key property value is "${e.key}"`);});
btnClearConsole.addEventListener('click',(e)=>{let child = consoleLog.firstChild;while(child){
consoleLog.removeChild(child);
child = consoleLog.firstChild;}});
System Modifier Keys
You can use the following modifiers to trigger mouse or keyboard event listeners only when the corresponding modifier key is pressed:
.ctrl
.alt
.shift
.meta
<!-- Alt + C --><input @keyup.alt.67="clear"><!-- Ctrl + Click --><div @click.ctrl="doSomething">Do something</div>
system modifier 可搭配.exact (modifier / 修飾符)
<!-- 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>
↑如果最初的selected內容不在任何可選的選項中,那就provide a disabled option with an empty value.
這樣設計的原因是→If the initial value of your v-model expression does not match any of the options, the <select> element will render in an “unselected” state. On iOS this will cause the user not being able to select the first item because iOS does not fire a change event in this case.
綜合應用如下
<selectv-model="selected"><optionv-for="option in options"v-bind:value="option.value"> {{ option.text }}</option></select><span>Selected: {{ selected }}</span>
<!-- `picked` is a string "a" when checked --><inputtype="radio"v-model="picked"value="a"><!-- `toggle` is either true or false --><inputtype="checkbox"v-model="toggle"> //在vue的設定中會傳true或false的值,但如果檢查該元素的value,那麼不論checked or not「都」會傳on的值。因為vue的v-modal雖似v-bind:value,但不是真的value,我想這樣的寫法在傳送表單時應該也有它自己的一套方式<!-- `selected` is a string "abc" when the first option is selected --><selectv-model="selected"><optionvalue="abc">ABC</option></select>
<divid="app"><h1>Bitcoin Price Index</h1><sectionv-if="errored"><p>We're sorry, we're not able to retrieve this information at the moment, please try back later</p></section><sectionv-else><divv-if="loading">Loading...</div><divv-elsev-for="currency in info"class="currency" > {{ currency.description }}:<spanclass="lighten"><spanv-html="currency.symbol"></span>{{ currency.rate_float | currencydecimal }}</span></div></section></div>
var vm = new Vue({ el: '#example', data: { message: 'Hello' }, computed: { reversedMessage: function () {returnthis.message.split('').reverse().join('') }
<!-- 单个元素 --><spanv-once>This will never change: {{msg}}</span><!-- 有子元素 --><divv-once><h1>comment</h1><p>{{msg}}</p></div><!-- 组件 --><my-componentv-once:comment="msg"></my-component><!-- `v-for` 指令--><ul><liv-for="i in list"v-once>{{i}}</li></ul>
<templatev-if="loginType === 'username'"><label>Username</label><inputplaceholder="Enter your username"key="username-input"></template><templatev-else><label>Email</label><inputplaceholder="Enter your email address"key="email-input"></template>
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.
a component’s data option must be a function, so that each instance can maintain an independent copy of the returned data object.
There are two types of component registration: global and local.
進一步,可以重複使用的component在重複利用時用props指定其中變數的值:
Vue.component('blog-post', { props: ['title'], template: '<h3>{{ title }}</h3>'})
<blog-posttitle="My journey with Vue"></blog-post><blog-posttitle="Blogging with Vue"></blog-post><blog-posttitle="Why Vue is so fun"></blog-post>
最後,可以把上面這個重複的blog-post tag改成array
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' } ] }})
//原本沒有data,data.posts的內容是json
<blog-postv-for="post in posts"v-bind:key="post.id"v-bind:title="post.title"></blog-post>
use v-bind to dynamically pass props.如此一來接API時posts就可以直接接json使用,如下: new Vue({ el: '#blog-post-demo', data: { posts: [] }, created: function () { // Alias the component instance as `vm`, so that we // can access it inside the promise function var vm = this // Fetch our array of posts from an API fetch('https://jsonplaceholder.typicode.com/posts') .then(function (response) { return response.json() }) .then(function (data) { vm.posts = data }) } })
先行補充:每個XML文檔都只有一個root element。它包含所有其他元素,因此是所有其他元素的唯一父元素。ROOT elements are also called document elements。在HTML中,根元素是<html>元素 component must have a single root element!
前面以props讓重複使用的component可以是不同的參數應用,並且在body連續的寫入,可改用array更簡潔,如:<blog-post v-for="post in posts" v-bind:key="post.id" v-bind:title="post.title" ></blog-post>,但是如果除了post.title之外,還有post.content, post.publishedAt, post.comments,...,則建議重建為:
<blog-post v-for="post in posts" v-bind:key="post.id" v-bind:post="post"></blog-post>配合下面
console.log('string text line 1\n' + 'string text line 2'); 和 console.log(`string text line 1 string text line 2`); 都出現下方結果 // "string text line 1 // string text line 2"
<!-- Component changes when currentTabComponent changes --><componentv-bind:is="currentTabComponent"></component>
In the example above, currentTabComponent can contain either:
the name of a registered component, or
a component’s options object
→Have you ever needed to switch between various arbitrary components at the same mount point in Vue.js ?
it’s quite simple to do in Vue by using the <component></component> tag.
It just takes a string (or component definition) :is prop. Vue then looks up the component referenced by that string and renders it in place of the <component> tag.
Custom events can also be used to create custom inputs that work with v-model. 3.<slot></slot>→
vue.component在HTML中再寫入任何any template code, including HTML,則需要在組成時的template中寫上 <slot></slot>,否則If <navigation-link> did not contain a <slot> element, any content passed to it would simply be discarded.
<base-layout><templateslot="header"><h1>Here might be a page title</h1></template><p>A paragraph for the main content.</p><p>And another one.</p><templateslot="footer"><p>Here's some contact info</p></template></base-layout>
另一種直接寫在元素上
<base-layout><h1slot="header">Here might be a page title</h1><p>A paragraph for the main content.</p><p>And another one.</p><pslot="footer">Here's some contact info</p></base-layout>
→為<slot></slot>提供默認內容:
<buttontype="submit"><slot>Submit</slot></button>
如果父組件為其提供了其他內容,則默認內容就會被替換掉。
→当你想在插槽内使用数据时,例如:
<navigation-linkurl="/profile"> Logged in as {{ user.name }}</navigation-link>
延伸: JSX (JavaScript eXtension) is an extension to the JavaScript language syntax. Similar in appearance to HTML. 我们推荐在 React 中使用 JSX 来描述用户界面。JSX 乍看起来可能比较像是模版语言,但事实上它完全是在 JavaScript 内部实现的。
它將HTML寫在JAX裡,避免了XXS(注入攻擊),又
1
2
3
var text = 'Hello React';
<h1>{text}</h1>
<h1>{'text'}</h1>
解析完後:
1
2
var text = 'Hello React';
React.createElement("h1", null, "Hello React!");
明顯JSX易讀
git clone https://github.com/vuejs/vue.git node_modules/vuecd node_modules/vuenpm installnpm run build