Vue.js开发基础语法知识

  • 安装chrome devtoos

  1. 从网上搜索一个安装包
    下载了zip的扩展包之后,直接将zip文件拖拽到“chrome浏览器》更多工具》扩展程序”窗口中,就可以使用了。(Mac每次打开浏览器,都会需要重新拖拽一次)
  2. 还有一个在线下载地址
    https://chrome-extension-downloader.com/
    只需要把要下载的chrome store中的路径地址输入到下载框中就可以下载了(看你的网速快慢了,不用安全上网)。
  3. 下载devtoos app
    (只有一次下载成功了,网不好,很难下载下来)
  4. 从 Github 下载 devtools 的项目包到本地,install 之后,build 生产扩展文件包,vue-devtools/packages/shell-chrome/,从 chrome 浏览器的开发者模式中加载。
  • vue CLI

vue create hello-world

创建项目的时候,建议选择手动安装选项(Manually select features),这样可以选择配置上 vuex、vue-router 等依赖,项目会自动生成相应的配置文件。

还可以界面化安装 
vue ui
  • Vue.js

一、基础语法

1.组件data为函数(单页面应用中适用,html页面中为对象格式)

export default { data () { return { foo: 'bar' } } }
//data: function() { return { foo: 'bar' } } ES5写法

2.永远不要把 v-if 和 v-for 同时用在同一个元素上,可将 v-if 移动至容器元素上 。

把一个 <template> 元素当做不可见的包裹元素,并在上面使用 v-if。最终的渲染结果将不包含 <template> 元素。

<template v-if="ok">
  <h1>Title</h1>
  <p>Paragraph 1</p>
  <p>Paragraph 2</p>
</template>

可以利用带有 v-for 的 <template> 来循环渲染一段包含多个元素的内容。比如:

<ul>
  <template v-for="item in items">
    <li>{{ item.msg }}</li>
    <li class="divider" role="presentation"></li>
  </template>
</ul>

3.组件名为多个单词

Vue.component('todo-item', {
  // ...
})
export default {
  name: 'TodoItem',
  // ...
}

4.组件名大小写

<!-- 在单文件组件、字符串模板和 JSX 中 -->
<MyComponent/>
<!-- 在 DOM 模板中 -->
<my-component></my-component>

5. prop名大小写传参

props: {
  greetingText: String
}
<WelcomeMessage greeting-text="hi"/>

6.动态参数

<a v-bind:[attributeName]="url"> ... </a>
<a v-on:[eventName]="doSomething"> ... </a>

7. 计算属性 computed

计算属性是基于它们的响应式依赖进行缓存的只在相关响应式依赖发生改变时它们才会重新求值。

<div id="example">
  <p>Original message: "{{ message }}"</p>
  <p>Computed reversed message: "{{ reversedMessage }}"</p>
</div>
var vm = new Vue({
  el: '#example',
  data: {
    message: 'Hello'
  },
  computed: {
    // 计算属性的 getter
    reversedMessage: function () {
      // `this` 指向 vm 实例
      return this.message.split('').reverse().join('')
    }
  }
})

8.侦听器 watch

当需要在数据变化时执行异步或开销较大的操作时,这个方式是最有用的。

<div id="demo">{{ fullName }}</div>
var vm = new Vue({
  el: '#demo',
  data: {
    firstName: 'Foo',
    lastName: 'Bar',
    fullName: 'Foo Bar'
  },
  watch: {
    firstName: function (val) {
      this.fullName = val + ' ' + this.lastName
    },
    lastName: function (val) {
      this.fullName = this.firstName + ' ' + val
    }
  }
})

9. class 样式名

v-bind:class 指令也可以与普通的 class 属性共存。当有如下模板:

<div
  class="static"
  v-bind:class="{ active: isActive, 'text-danger': hasError }"
></div>

数组语法

<div v-bind:class="[activeClass, errorClass]"></div>

10. v-show 和 v-if

v-if 有更高的切换开销,而 v-show 有更高的初始渲染开销。

因此,如果需要非常频繁地切换,则使用 v-show 较好;如果在运行时条件很少改变,则使用 v-if 较好。

11. 数组变动

Vue 不能检测以下数组的变动

vm.items[indexOfItem] = newValue
vm.items.length = newLength

可以使用splice实现上面的变动

// Array.prototype.splice
vm.items.splice(indexOfItem, 1, newValue)
vm.items.splice(newLength)

也可以适用vue自带的

Vue.set(vm.items, indexOfItem, newValue)

你也可以使用 vm.$set 实例方法,该方法是全局方法 Vue.set 的一个别名:

vm.$set(vm.items, indexOfItem, newValue)

12. 为已有对象赋值新属性的方法

vm.userProfile = Object.assign({}, vm.userProfile, { age: 27 })
Vue.set(vm.userProfile, 'age', 27)
vm.$set(vm.userProfile, 'age', 27)

13. input

v-model绑定data
<input v-model="message">
<!-- 在“change”时而非“input”时更新 -->
<input v-model.lazy="msg" >
如果要自动过滤用户输入的首尾空白字符,可以给 v-model 添加 trim 修饰符: <input v-model.trim="msg">

14. 监听子组件事件

<blog-post
  ...
  v-on:enlarge-text="postFontSize += 0.1"
></blog-post>

同时子组件可以通过调用内建的 $emit 方法 并传入事件名称来触发一个事件:

<button v-on:click="$emit('enlarge-text')">
  Enlarge text
</button>

15. 插槽

<slot></slot>

它允许你像这样合成组件:

<navigation-link url="/profile">
  Your Profile
</navigation-link>

然后你在 <navigation-link> 的模板中可能会写为:

<a
  v-bind:href="url"
  class="nav-link"
>
  <slot></slot>
</a>

当组件渲染的时候,<slot></slot> 将会被替换为“Your Profile”。插槽内可以包含任何模板代码,包括 HTML,甚至其它的组件。

16. 异步更新队列 nextTick

Vue 在更新 DOM 时是异步执行的。只要侦听到数据变化,Vue 将开启一个队列,并缓冲在同一事件循环中发生的所有数据变更。

为了在数据变化之后等待 Vue 完成更新 DOM,可以在数据变化之后立即使用 Vue.nextTick(callback)。

17. Vue.observable 让一个对象可响应,在小项目中替换 Vuex 使用。

Vue 内部会用它来处理 data 函数返回的对象。

返回的对象可以直接用于渲染函数计算属性内,并且会在发生变更时触发相应的更新。也可以作为最小化的跨组件状态存储器,用于简单的场景:

const state = Vue.observable({ count: 0 })

const Demo = {
  render(h) {
    return h('button', {
      on: { click: () => { state.count++ }}
    }, `count is: ${state.count}`)
  }
}

18. 过滤器 filters

过滤器可以用在两个地方:双花括号插值和 v-bind 表达式 (后者从 2.1.0+ 开始支持)。过滤器应该被添加在 JavaScript 表达式的尾部,由“管道”符号指示:

<!-- 在双花括号中 -->
{{ message | capitalize }}

<!-- 在 `v-bind` 中 -->
<div v-bind:id="rawId | formatId"></div>

你可以在一个组件的选项中定义本地的过滤器:

filters: {
  capitalize: function (value) {
    if (!value) return ''
    value = value.toString()
    return value.charAt(0).toUpperCase() + value.slice(1)
  }
}

或者在创建 Vue 实例之前全局定义过滤器:

Vue.filter('capitalize', function (value) {
  if (!value) return ''
  value = value.toString()
  return value.charAt(0).toUpperCase() + value.slice(1)
})

new Vue({
  // ...
})
  • vue-router

<!-- 路由匹配到的组件将渲染在这里 -->
<router-view></router-view>
<!-- <router-link> 默认会被渲染成一个 `<a>` 标签 -->
<router-link to="/foo">Go to Foo</router-link>
或者js中跳转
this.$router.push('/foo')

页面加载不同模块的方法

<div class="user">
    <h2>User</h2>
    <router-view></router-view>
    <router-view name="a"></router-view>
</div>
routes: [
    {
      path: '/user', component: User,
      children: [
        // 当 /user 匹配成功,
        // UserHome 会被渲染在 User 的 <router-view> 中
        { path: '', 
          components: {
            default: UserHome,
            a: UserNext 
          },
        // ...其他子路由
      ]
    }
  ]

props 解藕传参

const User = {
  props: ['id'],
  template: '<div>User {{ id }}</div>'
}
const router = new VueRouter({
  routes: [
    { path: '/user/:id', component: User, props: true },
    // 对于包含命名视图的路由,你必须分别为每个命名视图添加 `props` 选项:
    {
      path: '/user/:id',
      components: { default: User, sidebar: Sidebar },
      props: { default: true, sidebar: false }
    }
  ]
})

this.$router

router 实例。

this.$route

当前激活的路由信息对象。这个属性是只读的,里面的属性是 immutable (不可变) 的,不过你可以 watch (监测变化) 它。

  • Vuex

// 如果在模块化构建系统中,请确保在开头调用了 Vue.use(Vuex)

const store = new Vuex.Store({
  state: {
    count: 0
  },
  mutations: {
    increment (state) {
      state.count++
    }
  }
})

现在,你可以通过 store.state 来获取状态对象,以及通过 store.commit 方法触发状态变更:

store.commit('increment')

console.log(store.state.count) // -> 1
  • axios

从服务器(后台)获取数据

axios.get('/user?ID=12345')
  .then(function (response) {
    // handle success
    console.log(response);
  })
  .catch(function (error) {
    // handle error
    console.log(error);
  })
  .finally(function () {
    // always executed
  });
axios.post('/user', {
    firstName: 'Fred',
    lastName: 'Flintstone'
  })
  .then(function (response) {
    console.log(response);
  })
  .catch(function (error) {
    console.log(error);
  });
axios.all([getUserAccount(), getUserPermissions()])
  .then(axios.spread(function (acct, perms) {
    // Both requests are now complete
  }));

Promise用法

function post(){
  return axios.post('urlPath', { firstName: 'Fred'})
}
new Promise(function(resolve, reject) {
  resolver(post())
}).then((response)=>{
}).catch(err=>{})