vue入门

时间:2024-03-27 12:41:52

vue功能

数据渲染/数据同步

组件化/模块化

其他:路由,ajax,数据流


js、css、html在同一个文件里 

还可以在组件里例如 <style lang=less>的方式用less来编译样式


vue实例对象

vue入门

el决定了把这个对象挂载到哪里  例如 el: 'body 放在body下

template 模板

data数据

components 可以把其他组件引用到根组件里 

new Vue({

components:{other-component}

})

通常在开头创建这个根组件


Vue组件

main.js入口文件 内容为

import Vue from ‘vue’  //es6的写法类似于require()

组件树

vue入门


*data最好不要直接赋值

最好这样做

vue入门

实例选项 option就是在创建实例时内部的template data等等


文本渲染

v-once 执行一次性地插值,当数据改变时,插值处的内容不会更新。


<span v-once>这个将不会改变: {{ msg }}</span>

*{{  }}在2.0中已经不能使用到属性里  例如 <div title={{xxx}}> 是被禁止的

{{}}中可以这么写{{num + 1}}  甚至三目运算符等一些简单表达式


<!-- 这是语句,不是表达式 -->
{{ var a = 1 }}
<!-- 流控制也不会生效,请使用三元表达式 -->
{{ if (ok) { return message } }}

v-html和v-text

vue入门

这两种写法的区别在于v-text会将内容转化为字符串  而v-html会自动将标签部分转为标签

结果如下

vue入门




列表渲染

v-for

vue入门

在需要循环的项添加v-for 而不是在父级添加

结果如下

vue入门

为奇数列表添加odd的class

vue入门


当然也可以在模板中使用对象的方式

vue入门

那么相应的html中内容

vue入门


将其他组件的内容渲染进app.vue

vue入门

将组件componentA引入 记得要在当前的组件中添加components: {componentA}



列表更新

支持的列表更新方法

vue入门

不支持的方法

filter、concat、slice

还有

vue入门

1.直接为列表某一项赋值  2.改变列表的长度

html写法

vue入门

组件

vue入门

点击一次就添加一个 pinaapple256

*如果想直接点击按钮时更新第二项列表呢?

vue入门



标签属性、条件渲染

v-bind绑定属性

vue入门

*可以缩写 直接写:href=“link”也是可以的


通过v-bind还可以绑定class  和普通的class不冲突

vue入门


通过控制组件中的classStr的布尔值来达到显示哪个class

例如

vue入门


vue入门

为true就显示出来  false不显示


*还可以数组和对象混合绑定

vue入门



条件渲染

v-if v-show

vue入门

配置isPartA为true

添加一个method

vue入门


点击按钮就可以实现partA和B的切换

注意v-if 和v-show的区别

v-if的内容所以<!---->的形式存放的

v-show是以display:none来控制隐藏与显示

v-if vs v-show

v-if 是“真正的”条件渲染,因为它会确保在切换过程中条件块内的事件监听器和子组件适当地被销毁和重建。

v-if 也是惰性的:如果在初始渲染时条件为假,则什么也不做——直到条件第一次变为真时,才会开始渲染条件块。

相比之下, v-show 就简单得多——不管初始条件是什么,元素总是会被渲染,并且只是简单地基于 CSS 进行切换。

一般来说, v-if 有更高的切换开销,而 v-show 有更高的初始渲染开销。因此,如果需要非常频繁地切换,则使用 v-show 较好;如果在运行时条件不太可能改变,则使用 v-if 较好。



v-else

vue入门

用于与v-if和v-show配合



事件绑定

v-on缩写  例如v-on:click=“xxxx”  缩写为@click=“xxx”


阻止冒泡的修改器写法

vue入门


另外一种常见的修改写法

vue入门

摁下13的时候触发

onkeydown方法

vue入门



自定义事件

vue入门

引入子组件 

自定义了一个事件 my-event

vue入门

如何触发这个事件呢?

转到子组件中

vue入门


回到父组件

点击按钮 结果如下

vue入门






表单事件绑定

v-model

vue入门


vue入门


结果

vue入门

实现了双向绑定


v-model的修饰符

v-model.lazy会在输入完成之后会修改右侧的内容或者是点enter或者失去焦点的时候更新

v-model.number会将myVal转为number类型  例如 修改 {{typeof myVal}}  输入数字 右侧显示number  输入字母 显示string(默认都是string)

v-model.trim会自动裁剪掉空格 在输入框中输入空格会被自动滤过




checkbox

vue入门

修改myVal:[ ]

结果如下

vue入门


type=radio同理  只不过myVal又改回了 “ ”;


select

vue入门

myVal改成0

选项也是列表 通常配合v-for来使用



vue入门


vue入门



自定义组件v-select

vue入门


vSelect.vue文件

vue入门

后面会有更细致的讲解


tips:

VUE 单页面中,如何使用JQUERY 插件,如:ckplayer.js 这些插件,用VUE单页会报错的,报的是插件内部的一些API 找不到了

建议先去github上找找有没有已经集成好的vue 类似或者相同的插件。如果实在没有,你可以把jquery和ckplayer.js放到static目录下,在index.html直接在头部用 <script> 引入进来。

这样引入的对象也可以在组件里用,因为通常对象都放在顶层window下。


计算属性

模板内的表达式是非常便利的,但是它们实际上只用于简单的运算。在模板中放入太多的逻辑会让模板过重且难以维护。例如:


<div id="example">
{{ message.split('').reverse().join('') }}
</div>

在这个地方,模板不再简单和清晰。你必须看一段时间才能意识到,这里是想要显示变量 message 的翻转字符串。当你想要在模板中多次引用此处的翻转字符串时,就会更加难以处理。

这就是对于任何复杂逻辑,你都应当使用计算属性的原因。

基础例子


<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: {
// a computed getter
reversedMessage: function () {
// `this` points to the vm instance
return this.message.split('').reverse().join('')
}
}
})

结果:

Original message: "Hello"

Computed reversed message: "olleH"

这里我们声明了一个计算属性 reversedMessage。我们提供的函数将用作属性 vm.reversedMessage 的 getter 函数:


console.log(vm.reversedMessage) // -> 'olleH'
vm.message = 'Goodbye'
console.log(vm.reversedMessage) // -> 'eybdooG'


你可以像绑定普通属性一样在模板中绑定计算属性。Vue 知道 vm.reversedMessage 依赖于 vm.message,因此当 vm.message 发生改变时,所有依赖于 vm.reversedMessage 的绑定也会更新。而且最妙的是我们已经以声明的方式创建了这种依赖关系:计算属性的 getter 函数是没有连带影响 (side effect),这使得它易于测试和推理。


计算属性和method方法

我们可以将同一函数定义为一个 method 而不是一个计算属性。对于最终的结果,两种方式确实是相同的。然而,不同的是计算属性是基于它们的依赖进行缓存的

计算属性只有在它的相关依赖发生改变时才会重新求值。这就意味着只要 message 还没有发生改变,多次访问 reversedMessage 计算属性会立即返回之前的计算结果,而不必再次执行函数。

这也同样意味着下面的计算属性将不再更新,因为 Date.now() 不是响应式依赖:


computed: {
now: function () {
return Date.now()
}
}

相比之下,每当触发重新渲染时,method 调用方式将总是再次执行函数。

我们为什么需要缓存?假设我们有一个性能开销比较大的的计算属性 A,它需要遍历一个极大的数组和做大量的计算。然后我们可能有其他的计算属性依赖于 A 。如果没有缓存,我们将不可避免的多次执行 A 的 getter!如果你不希望有缓存,请用 method 替代。



vue入门


如果改成return this.myValue + ‘end’

vue入门

再或者改成return this.myValue.replace(/\d/g, "")


vue入门

就会自动将数字替换掉



第二种实现方法

通过在methods中编写一个函数

vue入门


vue入门


*两者的区别 computed对myValue依赖大  myValue不更新那么computed就固定了

例如将return的语句都换成 Date.now() 那么computed的时间是最开始的时间 固定了  而methods的时间随着每次变化而变化



数据监听


<input type="text" v-model="myVal">

vue入门


打印结果为

vue入门


监听的使用小例子

假设有这么一组列表

vue入门


绑定几种事件 需要在每次改变列表的时候提醒一下 于是定义了一个methods tellUser

vue入门


这样每次写在其他函数后面很麻烦

于是通过watch

vue入门






组件之间的通信

vue入门




根组件main.js

通过实例化对象

vue入门


中间通过配置文件 app.vue


父组件和子组件

vue入门

需要注意的有三点:

1.把子组件import进来

2.components:{

a,

b,

...

}


3.使用子组件的标签 例如 ComAHasChild 最好是转为<com-a-has-child>的形式 在1.0版本支持这种写法 而2.0可以直接的<ComAHasChild>


第二种方式(好处在于可以动态引入模板组件)

vue入门

vue入门


用变量的形式 可以修改变量来达到修改模板的效果



父子组件之间传递信息


vue入门

假如父组件中有这么一个number

vue入门

要把这个number渲染到子组件中

子组件应该用props

vue入门

这样渲染后 number相当于子组件的data中的一个属性了(就像hello一样)

需要注意的是 驼峰和-之间的转换

vue入门



我们这里的number-to-do传递是静态值

那么如何传递动态值呢

vue入门

子组件中

vue入门

my-value接受number或者string类型


emit在前面自定义组件中使用过

如果父组件想把一个模板传给子组件呢

vue入门


在子组件中通过<slot>标签接受

vue入门


假如<com-a>

<p>xxxx</p>

<span>xxxx<span>

</com-a>

中让p成为插孔  那么例如这样

vue入门

子组件中如下

vue入门


结果如下

vue入门




动态组件


如果有两个子组件 com-a com-b 需要来回切换 我们可以使用keep-alive这个内置标签来缓存

vue入门




过渡效果

vue入门

可以实现在文字出现和隐藏的中间有一个过渡的动画效果

vue入门


不同的阶段有不同的类名

name是自己定义的  具体动画效果在style中写

vue入门



来定义另外一种效果

name=my-trans

vue入门



当然也可以对动态组件添加过渡

vue入门


添加一个toggle方法

vue入门


这样做有一个问题

在页面中显示的顺序是在另外一个切换进页面后之前一个才会消失 视觉效果不好

vue入门

默认的model是in-out 先进后出   修改一下就可以啦



*还有一个问题是遇到标签名相同时 动画不起作用了?

vue入门

记得要使用key来区分




使用js来实现过渡

vue入门

js通过绑定事件控制


例子


vue入门


.animate-p{

position:absolute;

left:0;

top:0;

}


vue入门






!!!如果需要使用vue的同时使用jquery怎么办 

建议放到index的head中引入jquery文件

jquery放在static目录下,在index.html里直接用script标签直接引入,这是我总结下来最简单的方法,当时通常来说,用了vuejs就不要再用jquery了,过渡效果vuejs都能用,如果仅为了过渡效果就引入jquery这么大一个库不太值得,可以去找一些专门过渡效果的库



自定义组件

第一种方法

局部自定义组件

vue入门


第二种方法 全局组件

在main.js中

vue入门

vue.director有inserted和bind   在内部console  先打印出bind 再打印insert

vue.director中的内容

接受v-css的value遍历后整合传入arr中 再设置为当前元素的css内容



*在main.js写全局指令Vue.directive报错了

Vue.directive不能写在new vue后面不然会报错的


插件

在pakeage.json中

可以看到项目所依赖的dependencies

它们都是独立于vue的

下载引入后

vue入门

需要vue.use才能生效

*Var vueRouter=require();和 Import vueRouter from vue-router;有什么区别吗

没区别,require是 AMD那套模块化规则, import是es6的语法,原来为什么会有require,是因为js本身没法实现模块化,现在es6(es2015)有了。

这两种在vue脚手架项目里都会被处理,import会被babel处理,然后被webpack处理,具体的没看,babel可能也是把import转成require。 require直接会被webpack的模块处理机制处理掉。

对开发者来说是一样的,没啥区别。


*<style scoped> scoped限制css只对这个组件生效




安装vue-cli

cnpm install vue-cli -g

vue --help 查看

vue -V显示版本号

vue list查看可以使用的模板

vue init webpack 使用webpack这个模板

初始完毕后

cd vuedemo3   (这里是自己的项目名称)

在vuedemo3(也就是有package.json的文件夹里)   cnpm install 会将项目的依赖安装到node_modules中

最后npm run dev 给出一个端口 打开

vue入门

npm run build 会生成一个dist文件


vue-router 路由 根据不同的url跳转到不同页面

单页面应用  不刷新页面实现跳转

安装路由 cnpm install vue-router --save

然后在main.js中

vue.use(router);



history模式直接访问页面就是不带#的。


app.vue

<template>
  <div id="app">
    <img src="./assets/logo.png">
    <router-view></router-view>

    <router-link :to="{path:'apple'}">to apple</router-link>
    <router-link :to="{path:'banana'}">to banana </router-link>

  </div>
</template>

<script>
  import HelloWorld from './components/HelloWorld.vue'//./必须要有
export default {
  name: 'App'
}
</script>

<style>
#app {
  font-family: 'Avenir', Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>



main.js

// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue'
import App from './App'
import router from './router'
import Apple from './components/apple'
import Banana from './components/banana'
Vue.config.productionTip = false
Vue.use(router);
let rout = new router({
  mode: 'history',
  routes: [
    {
      path: '/apple',
      component: Apple
    },
    {
      path: '/banana',
      components: Banana
    }
  ]
});
/* eslint-disable no-new */
new Vue({
  el: '#app',
  router : rout,
  components: { App },
  template: '<App/>'
})



设置路由参数

vue入门

*  :后面的是被注册到params中的参数  而后面如果不带:  需要严格按后面的来 例如  /apple/:color/detail  这个detail不能改动

然后在页面中设置 例如 red

vue入门

通过$route.params 在控制台中会打印出red

当然也可以<p>{{$route.params.color}} </p>显示在页面中

路由参数有什么具体的应用场景

页面跳转要传参,比如用户列表点到用户页面,可以把用户id放到路由参数里

VUE怎么引JQuery

最方便的方法是在index.html里引入 jquery用线上的或者放到static目录下


路由嵌套

vue入门


如果一个项目有个100个子组件 ,这些子组件都要在main.js import?

不用,在哪里用在哪里import, webpack会处理


路由视图 路由重定向

地址前面加/代表根目录

vue入门

这样可以直接在router-link里设置参数

vue入门

默认是a标签 如果想改成其他标签 可以使用tag


导航还可以使用编程式导航

在main.js中

通过router.push的方式

vue入门

beforeEach在每次路由跳转前生效


命名导航

通过name的方式

vue入门

以示区分

vue入门

重定向

vue入门

在访问根目录的时候重定向到apple

路由视图中<router-view></router-view>使用name的话在main.js中component要改成components


路由重定向和多个<router-view/>有什么用

路由重定向,比如首页叫做 index页面,访问是 localhost:8080/index,  就可以把根目录的访问重定向到index, 把 / 重定向到/index。  还有就是有些页面是不允许被访问的,或者两个地址关联到同一个页面,比如你可以设定 /dt 重定向到/detail 。

多个router-view可以多重控制路由组件,每块view展示不同的组件内容,还可以实现子路由


没理解命名视图,能讲个应用场景?

命名视图可以通过name来区分router-view,可以给一个路径设置不同的 视图组件,相当于吧页面的内容,边栏等部分拆分开,我想到的应用场景是,有个页面用sidebarA,有的用sidebarB,在路由配置的时候就可以简单得设置,不需要在页面组件层级来做,同时不同的sidebar还都是独立的非耦合组件。


过渡动画应用到路由中

vue入门


keep-alive实现缓存 避免浪费资源


vuex

假如有一个购物车  存在页面各处 在某一处改变购物车的存放商品  其他地方都会改变

示意图

vue入门


vue入门


安装vuex

cnpm install vuex --save


vue入门

全局使用

vue入门


vue入门

vue入门



?????

vue入门


vue入门

异步请求

vue入门


vue入门

vue入门

vue入门





actions 状态里的 函数内 参数 context是什么啊

context是一个内容对象,包含这个vuex整体的其他属性,state,mutation等等,你可以打印出来看看