一: 监听数组变化,实时更新?
<script>
methods: {
changeArray() {
//arr=[1,2,3],这里我们将下标0的数据更新为10
this.arr.splice(0, 1, 10); //方法一 arr=[10,2,3]
this.$set(this.arr, 0, 10); //方法二
//整个数组更新:
this.arr= [...this.arr] //批量处理多个数据后将新的数组赋值给原数组
不常用的方法:
this.$forceUpdate //强制更新的意思 不管数据是否变化
}
}
//数组对象更新一个数据
//item是循环的一个对象,showSpecificBtn是键名,true为要修改的值
// this.$set(item, 'showSpecificBtn', true)
</script>
二: Vue是怎样触发组件更新,实现响应式更新?
Vue 在创建实例时,会对data内的数据进行一个getter,setter的转化,相当于一个中间代理,不管是设置数据还是取数据,都会经过代理层data,在组件进行数据渲染reader时,如果有使用data内的数据,就将此数据发送给监听者Watcher,没有使用到是不会进入到 Watcher内,所以当data数据更新setter时,Watcher内有记录的,就会通知组件,进行reader渲染,没有则不会进行reader渲染,即使数据已经发生改变.
三:计算属性computed和监听属性watcher?
计算属性 computed:
- 减少模板中的计算逻辑
- 数据缓存
- 依赖固定的数据类型(响应式数据 )
侦听器 watch:
- 更加灵活, 通用
- watch 中可以执行任何逻辑, 如: 函数节流, Ajax 异步获取数据, 甚至操作 DOM
- 当需要在数据变化时执行异步或开销较大的操作时使用
- 可以嵌套监听, 如: "a.b",deep:true可以使一个对象下所有属性都进行同时监听
computed vs watch:
- computed 能做的, watch 都能做, 反之则不行
- 优先使用 computed,因为watcher有时代码会很冗余
四: Vue指令
内部指令: v-text , v-html , v-bing(:) , v-on(@) , v-show , v-if ,v-else-if ,v-else , v-model, v-for, v-slot(#) , v-pre() , v-clock , v-once
自定义指令(生命周期钩子): bind , inserted , update , componentUpdated , unbind;
五: 通信
组件间通信:
- provide / inject
主要在开发高阶插件/组件库时使用,并不推荐用于普通应用程序代码中,业务开发可以优先考虑vuex提供全局唯一store, provide inject 会有一个类似冒泡的特性,数据源有可能在中间被”“打断”,甚至是有可能被组件库中的组件打断,或者打断组件库中的provide,不利于维护. - Vuex
六: template 与 jsx区别.
template:(模板语法)是HTML的扩展,数据绑定使用Mustache语法即{{}};学习成本低,大量内置指令简化开发,组件作用域css(局部样式),但灵活性低
jsx: 是javaScript语法的扩展,数据绑定使用 {} 号,灵活性高
总结: 组件可以分为两类,一类偏视图表现,建议使用template语法,一类偏逻辑表现,业务复杂时可以使用jsx或渲染函数; 使用jsx需安装插件,二者可混合使用;
七: Vuex
1.Vuex 也是一个单向的一个数据流:Vuex 提供数据 State
来驱动我们的视图(VueComponents
)的渲染(Render
),
- 然后再通过视图派发(
Dispatch
)我们的Action
- 我们在
Action
中可以进一步的进行一些异步的操作,譬如我们通过Ajax
去后端去获取一些我们想要的一些后端的一些数据。 - 然后我们通过
commit
的形式将Action
提交给我们的Mutations
,最后由Mutations
处理完毕后,再来最终更改我们的State
中的数据,如此循环。
//1. 安装下载Vuex :npm install vuex --save
//放状态的文件夹.js
import Vuex from 'vuex'
Vue.use(Vuex) //显式安装Vuex,可以在Vuex中访问到Vue
Vue.config.productionTip = false
const store = new Vuex.Store({
state: {
count: 1
},
mutations: { //要改变store内的状态只能通过mutation显式进行改变,必须是同步函数,可以直接通过
increment(state) {
state.count += 1
}
},
actions:{ //向后台发起异步请求,这里用setTimeout模拟异步
increment({state}){
setTimeout(()=>{
state.count+=2
},2000)
}
}
})
new Vue({
store, //通过在根实例中注册 store 选项,该store 实例会
//注入到根组件下的所有子组件中且子组件能通过 this.$store 访问到。
render: h => h(App),
}).$mount('#app')
//子组件
<template>
<div id="app">
{{count}}
<button @click="increment">count+=1</button>
<button @click="incrementTwo">count++</button>
</div>
</template>
export default {
name: 'App',
computed:{
count(){
//通过 this.$store获取数据
return this.$store.state.count
}
},
methods: {
increment(){
//通过 this.$store.commit()修改数据
this.$store.commit('increment' )
},
incrementTwo(){
//通过this.$store.dispatch()进行请求
this.$store.dispatch('increment')
}
},
}
八: vue-router
hash: 路由拼接在#号后,比较丑,无法使用锚点定位
history: 需要前后端配合,IE9不兼容(可使用强制刷新处理)
vue中new VueRouter时把mode设置为history就行啦,默认是hash,这样url带#号,不美观.
const router = new VueRouter({
mode:'history',
routes
})
九: 请求后端数据跨域,配置proxy
//vue.config.js 文件
module.exports = {
devServer:{
proxy: {
'/api': { //代理标识
// 标识替换
// 原请求地址为 /api/getData 将'/api'替换''后, 代理后的请求地址为: http://xxx.xxx.xxx/getData
// 若替换为'/other',则代理后的请求地址为 http://xxx.xxx.xxx/other/getData
target: 'http://xxx.xxx.xx.xx/',//指向的实际地址
changeOrigin: true, // 允许跨域
pathRewrite: {
'^/api': ''
}
}
},
}
}
//请求的接口的文件内
// 请确认原请求中是否包含代理标识符
// 请确认接口 http://xxx.xxx.xx.xx/getData直接访问是否正常
this.$axios.get('/api/getData').then((r)=>{
console.log(r)
})
//配置好重新运行一次项目就可以啦: npm run serve