这是我参与「第四届青训营 」笔记创作活动的第5天
六、:class动态绑定元素的类名
1.字符串方式
<label class="custom" :class="item.isdeleted ? 'delete' : ''"> 动态绑定class </label>
2.数组方式
3.对象方式
下面代码实现点击按钮后,更换对应h3的样式
<h3 :class="classObj">动态绑定class组件</h3>
<button @click="classObj.italic = !classObj.italic">toggle italic</button>
<button @click="classObj.delete = !classObj.delete">toggle italic</button>
data() {
return {
classObj:{
italic:true,
delete:false,
}
}
}
4.:style以对象语法动态绑定内联的style
<div :style="{fontSize : fsize}">hello</div>
<button @click="fsize + 1">字号+1</button>
data() {
return {
fsize : 30,
}
}
七、emit自定义事件
自定义事件其实就实现了一个子组件向父组件传参的操作,是为了让父组件能得到子组件内部详细的数据变化
1.声明自定义事件
//Counter.vue
<script>
export default {
emits:['countChange'] //声明自定义事件
}
</script>
2.触发自定义事件
//Counter.vue
<button @click="add">+1</button>
<script>
export default {
methods:{
add() {
this.count++
this.$emit('countChange',this.count) //触发自定义事件,并且将count的值向父组件传递
}
}
</script>
3.监听自定义事件
//App.vue
<my-counter @countChange="getCount"><my-counter>
<script>
export default {
methods:{
getCount(val) {
console.log('触发自定义事件',val) //监听到触发自定义事件,并且将子组件传值置于val中
}
</script>
4.emit结合组件上的v-model指令,实现同时父子双向传输
- 用于 维护组件内外数据的同步,可以同时子传父、父传子
//Counter.vue
<p>子组件count值为: {{number}}</p>
<button @click="add">+1</button>
<script>
export default {
props:['number'], //从父组件中获取number
emits:['update:number'], //声明自定义事件为更新父组件的number
method: {
add() {
this.$emit('update:number',this.number + 1) //触发事件,并且向父组件传值
}
}
}
</script>
//App.vue
<p>父组件count值为: {{count}}</p>
<button @click="count + = 1">+1</button>
<my-counter v-model:number="count"><my-counter> //通过v-model绑定,父向子传值
<script>
export default {
data(){
return {
count:0,
}
}
</script>
八、采用vuex的store来构造全局变量(状态管理)
经过上面我们可以看到,传统的传值方式在多层嵌套的时候,会变得异常的复杂,这个时候就需要全局的变量来解决数据的传输问题。
对于简单的应用,使用reactive()建立简单store能更快速的达成建立全局共享状态的目标,但是对于复杂的应用,reactive就显得力不从心了,利用vuex store,能更好的帮我们达成目标。vuex由下面五大部分组成:
1.state全局变量
state为单一状态树,在state中需要定义我们所需要管理的数组、对象、字符串等等,全局只有唯一一个store储存这些信息。
//store/index.js 建立一个store
import Vue from 'vue';
import Vuex from 'vuex';
Vue.use(Vuex);
const store = new Vuex.Store({
state: {
count: 0 //store的数据都要存到state中
}
});
new Vue({
el: '#app',
});
创建一个能读取到store中count的counter组件
const Counter = {
template: `<div>{{ count }}</div>`,
computed: {
count () {
return this.$store.state.count //store已经被全局注入,前面加this即可引用
}
}
}
利用mapState进行快速映射
import { mapState } from 'vuex'
computed: mapState([
// 映射 this.count 为 store.state.count
'count'
])
2.getter计算属性
getter类似vue.js的计算属性,,getter会接收state作为第一个参数,而且getter的返回值会根据它的依赖被缓存起来,只有getter中的依赖值发生改变的时候才会被重新计算。
const store = createStore({
state: {
todos: [
{ id: 1, text: '...', done: true },
{ id: 2, text: '...', done: false }
]
},
getters: {
doneTodos (state) {
return state.todos.filter(todo => todo.done)
}
}
})
Getter 会暴露为 store.getters 对象,可以以属性的形式访问这些值:
store.getters.doneTodos // -> [{ id: 1, text: '...', done: true }]
Getter 也可以接受其他 getter 作为第二个参数:
getters: {
// ...
doneTodosCount (state, getters) {
return getters.doneTodos.length
}
}
你也可以通过让 getter 返回一个函数,来实现给 getter 传参。在你对 store 里的数组进行查询时非常有用。
getters: {
// ...
getTodoById: (state) => (id) => {
return state.todos.find(todo => todo.id === id)
}
}
store.getters.getTodoById(2) // -> { id: 2, text: '...', done: false }
mapGetters 辅助函数也可以将 store 中的 getter 映射到局部计算属性
computed: {
...mapGetters({
// 把 `this.doneCount` 映射为 `this.$store.getters.doneTodosCount`
doneCount: 'doneTodosCount'
})
3.mutation
更改store中state状态的唯一方法就是提交mutation。每个mutation都有一个字符串类型的事件类型和一个回调函数,我们需要改变state的值就要在回调函数中改变。我们要执行这个回调函数,那么我们需要执行一个相应的调用方法:store.commit。
const store = createStore({
state: {
count: 1
},
mutations: {
increment (state, n) { //n是payload,可以向注册的事件传递对应的参数
state.count += n
}
})
store.commit('increment', 10) //通过commit去使用注册的事件
4.action
action可以提交mutation,在action中可以执行store.commit。在页面中如果我们要使用这个action,则需要执行store.dispatch
5.module
,module可以将store分割成模块,每个模块中拥有自己的state、mutation、action和getter,解决数据过多的store臃肿问题