Vue基础(Vue实例,data,父子组件传值,参数校验,非props特性,计算属性,ref,样式绑定)

688 阅读8分钟

Vue实例

new一个vue实例,一个程序进行加载的时候肯定有一个入口点,图上就都是从vm这个vue实例开始加载的,所以这个vmVue实例,被称为根实例

el:'#root'意思是,告诉vue,这个实例接管了id为root的div,在这个id下的div,遇到相关指令的时候就会按照vue的方法去执行或寻找,遇到v-on:click就会在实例中的methods里找对应的函数去执行,遇到双花括号(插值表达式)就会去data等地方去找对应的值

当没有给template属性的时候,vue会把整个div当做模板 相当于 vue中的每一个组件都是一个vue实例 凡是以$开头的,指的都是vue的实例属性或者实例方法

Vue中的根组件data和子组件data

data:根组件(即最外层vue实例)的data可以直接通过对象定义 image.png

子组件中定义data时,要求data必须是一个函数,同时这个函数要求返回一个对象,对象里要包含所对应的数据

image.png 为什么: 因为一个子组件不像根组件只会被调用一次,他可能在不同的地方会被调用很多次

比如在红框里就被调用了3次,子组件的每次调用,或者说每一个子组件,我不希望他的数据和其他的子组件产生冲突,或者说每一个子组件都应该有自己的数据,也就是说,第一个row对应的数据和第二个row对应的数据,应该是完整的两套数据,而不应该是共享的一套数据

子组件的data通过一个函数来返回一个对象的目的就是为了让每一个子组件都拥有一个独立的数据存储 这样就可以避免多个子组件之间的数据出现互相影响的情况

Vue父子组件间的数据传递(父向子,子向父,隐性规则)

父向子:通过绑定属性的方式进行传递

image.png image.png

子向父:子组件在内部通过事件触发的形式向父传递数据

eg:我们希望每次子组件被点击的时候,他可以向父组件去传递一些内容,比如自己当前的值 image.png counter组件被点击的时候触发子组件的原生事件handleClick,handleClick又通过this.$emit触发inc事件,同时向外传一个参数(即步长,为2) image.png 父组件监听子组件的事件inc,监听到该事件后执行handleIncrease函数 image.png 这时候就可以收到子组件传来的参数step,然后在handleIncrease函数中去使用

隐性规则:Vue中的单向数据流的概念:不要直接去修改父组件传递过来的数据

vue中有一个单项数据流的概念:父组件可以随意的向子组件去传递参数,但是!子组件不可以随意的修改父组件传递过来的参数

why这样?如果父组件传递过来的是一个对象类型的引用类型的数据时,子组件如果改变了传递过来的一些内容,有可能这个引用类型的数据同时在被其他的子组件所使用,这就可能会对其他的子组件造成影响

那现在我们如果确实需要去改变传来的数据怎么办?

现在这个例子就需要通过点击让传入的输出每次点击加一,很简单

我们把从父组件传来的参数保存一份在我们子组件自己的data里,当需要对参数进行操作时,我们改子组件自己保留下来的参数就可以了.如图所示: image.png

Vue组件参数校验与非 props 特性

组件参数校验(type /required /default /validator)

image.png 父组件向子组件传递参数,子组件接受参数,同时可以对传来的参数进行一定的约束,这里就要求传来的参数必须是string类型的    如果传递其他类型就会报错 image.png 也可以用数组的语法,表示,传来的值要么是数字要么是字符串 image.png 也可以这么写,require指的是是否必须传入这个属性,若为true,不传这个属性就会报错 image.png 若require属性设置为false,可以给一个default属性,作用是,当不传参数时,会给模板中所绑定的内容一个默认的内容,如图,content就会渲染为default value image.png 也可以给一个校验器,进行判断,图为:传入的长度大于5时,校验器返回true,若小于五则报错

非props特性

非props特性是与props特性相对应的,props特性就是,父组件向子组件传值,子组件声明了对父组件传递过来的值的接受(恰好在props里声明了这个content)所以父子组件有一个对应关系,这种形式的属性就叫props特性

第一个情况,父组件传值过来,子组件没有接受,使用这个值的时候就会报错 image.png 第二个情况,如果没有使用传过来的值,这个值实际会显示在dom的属性之中,而props特性不会把传来的值显示在dom的属性之中 image.png image.png

Vue中非父子组件间的传值

image.png 左侧的页面可以分成右侧的组件结构,第二第三条红线都是非父子组件关系,他们之间应该如何传值

一般有2种方式来解决vue中的非父子组件间的传值问题

1.借助Vue官方提供的数据层的框架——Vuex(项目中遇到较多,往后和项目一起写博客再讲)

2.使用发布订阅模式的Bus总线机制(这里我们讲这个方法

我们结合具体例子,比如:想实现点击上面dell时,下面的lee也变成dell,点击lee时,上面的dell也变成lee image.png image.png new一个vue的实例,把它赋值给Vue.prototype.bus

意思是,往vue的prototype上挂载一个bus的属性,这个属性指向new的Vue的实例,这样,以后我们new 的vue组件,它(vue组件)上都会有bus这个属性,因为每一个组件都是通过vue这个类来创建的,而vue这个类上挂载了bus这个属性,挂载在了vue类的prototype上,每一个通过这个类创建的实例上都会有bus这个属性,都指向同一个Vue的实例

接下来,如何把兄弟组件的值传给兄弟组件

意思是:这个实例有一个bus属性,这个bus属性又是一个vue实例,所以他有$emit的方法,他向外触发一个叫change的事件,同时传出去一个参数是当前子组件的content值,现在向外触发搞定了,那么其他组件就要去监听他触发的事件

每一个组件都有一个钩子,生命周期函数,mounted image.png 在要监听的函数,借助生命周期函数监听触发的事件,mounted,这段代码的意思: this.bus是挂载在vue原型属性上的所以在这个兄弟组件上有bus属性,又因为bus是一个vue实例,所以他有$on方法,用来监听函数,他监听一个叫change的函数,同时执行一个函数,图中为:将收到的参数alert出来(这样我们就取到了兄弟组件传来的参数)

代码完成如下 image.png image.png

Vue:计算属性vs方法vs侦听器

1.计算属性 computed

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

例子: image.png 首先,页面首次渲染时,fullName会计算一次,得出值,并将值存入缓存中,往后,只要它响应式依赖的值不发生改变,也就是firstName和lastName不发生改变,他就不会再计算,每次使用这个fullNaem时,都调用缓存中的fullName值直接使用。

2.方法 methods

image.png 方法也同样可以实现显示fullName的功能,首先在插值表达式里调用方法要加一对小括号表示调用,但是methods中没有缓存的机制,只要页面上的数据(也就是m层)发生改变,fullName都会重新执行一次,也就是说,哪怕我改变的是age的值,fullName也会重新执行一次,得出和上次一样的fullName(爱凑热闹的很)

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

我们为什么需要缓存?假设我们有一个性能开销比较大的计算属性 A,它需要遍历一个巨大的数组并做大量的计算。然后我们可能有其他的计算属性依赖于 A。如果没有缓存,我们将不可避免的多次执行 A 的 getter!如果你不希望有缓存,请用方法来替代。 所以当method和computed都可以实现某个功能时,选computed的性能更高

3.侦听器

image.png 侦听器和computed计算属性差不多,会有一个缓存,除了依赖的变量发生变化时,侦听器还是会使用之前缓存的值,而不会重新计算

但是watch侦听器的语法和computed计算属性的语法相比,就复杂了很多,代码也变多了

如果watch,computed,methods都可以实现一个功能,从性能和代码简洁的角度来讲,computed计算属性胜出!

Vue计算属性computed的get和set函数

image.png 代码解释:

计算属性的fullName有一个get函数:

意思是,使用fullName值时,通过这个get函数来得到fullName值,当然,响应式依赖没有改变时(即firstName和lastName没有发生改变时),还是使用缓存中的fullName值

计算属性的fullName有一个set函数:

意思是,当设置fullName值时,会将设置的值作为value,传入set函数,如图上的操作,当value值传入时,对value值以空格为标志来分成一个数组赋值给arr(如果把fullName赋值为‘gao jiahui’,那么他变成一个第一项为gao第二项为jiahui的数组),然后分别把第一项和第二项赋值给firstName和lastName,set的主要功能就是对传入的值(对计算属性的赋值)进行操作##

vue的ref(引用):可以通过ref来获取dom节点

image.png (refs是所有的引用,.hello是我们定义的其中的一个引用)

当ref写在一个div上时,通过this.$refs.refname获取到的是对应的这个dom元素

image.png image.png image.png 这个例子实现了一个点击计数的计数器功能

当ref写在一个组件上上时,通过this.$refs.refname获取到的是对这个组件的引用

在根组件中的方法里通过this.$refs.refname获取到的是对名为one和two两个子组件的引用,再通过.number,取到子组件里的数据,实现求和的功能

Vue中的样式绑定calss/style(分为通过对象的方式进行绑定,和通过数组的方式进行绑定)

实现点击变红再次点击变黑

绑定class(数组)数组里是一个个变量,变量是什么内容class就显示什么样式

image.png image.png image.png activatedOne就被显示在div上

绑定class(对象)

image.png image.png

绑定style(对象)

image.png

绑定style(数组):这个div显示的样式,由数组里的对象所决定

image.png image.png