Vue框架

Vue框架

一、v-model双向绑定

// 引入 vue.js 库
<script src="./vue.min.js"></script>
<div id="node">
    <h1>
    	欢迎{{ secondName + '' + firstName}}来到Vue学习阶段!
	</h1>
 	<!-- v-model.trim 去掉输入内容两边的空格 -->
 	<!-- v-model.lazy 懒监听-->
	<input type="text" v-model="firstName" />
	<input type="text" v-model="secondName" />
</div>

<script>
	new Vue({
        // 指定当前 Vue 的作用标签。
        el:"#node"// 为了避免数据全局污染,这里使用 return 产生一个闭包
        data() {
        	return {
                firstName:"",
                secondName:""
            }
    	}
    })
</script>

双向绑定实现原理

<h1 id="node"> </h1>
<input type="text" oninput="inputEvt()" />
let data = { result:'' };
// Vue使用 Object.defineProperty 方法进行数据劫持。
// Vue只能兼容到 IE9,Vue3使用 Object.proxy 代发方法来实现。
Object.defineProperty(data,'result',{
    // 给 data 对象的 result 属性添加 setter 和 getter 方法。
    set(val) {
        render(val)
    },
    get() {
        return document.getElementById('node').innerText
    }
})
function inputEvt() {
    let val = event.target.value
    // 给 setter 方法赋值就会调用 setter 方法。
    data.result = val
}
function render(val) {
    document.getElementById('node').innerText = val
}

二、常用修饰器

<div id="node">
	<!-- for(let item in list) 遍历数据,for...in机制 -->
	<tr v-for="item in list">
		<td>{{item.name}}</td>
		<td>{{item.time}}</td>
        <!-- 条件渲染指令,不符合条件的节点将不会渲染到dom树上 -->
        <td v-if="item.temp <= 40">{{item.temp}}</td>
        <td v-else-if="item.temp <= 70">{{item.temp}}</td>
        <td v-else>{{item.temp}}</td>
        <!-- 显示渲染指令,控制display属性 -->
        <td v-show="item.temp <= 40">{{item.temp}}</td>
        <td v-show="item.temp <= 70 && item.temp > 40">{{item.temp}}</td>
        <td v-if="item.temp > 70">{{item.temp}}</td>
	</tr> 
</div>
new Vue({
    data() {
        // 因为要给Vue实例进行数据双向绑定,因此需要返回。
        return {
            list:Array(10).fill('').map((it,i) => {
                return {
                    name:'admin' + i,
                    time:'12:3' + i,
                    temp:Math.ceil(Math.random()*100)
                }
            })
        }
    }
// 挂载方法,在vue中直接调用vue实例的方法需要使用一个"$"来说明是vue方法。    
}).$mount('#node')

v-if 和 v-show 的区别

相同点:都可以动态控制着dom元素的显示隐藏。

不同点:v-if 的显示隐藏是将DOM元素整个添加或删除,v-show 的显示隐藏是为DOM元素添加css的样式display,设置none或者是block,DOM元素是还存在的。

三、vue事件绑定

<div id="node">
    <!-- 使用v-on:来指定当前绑定的是什么事件 -->
    <button v-on:click="vueEvt()">按钮</button>
    <!-- v-on:click 缩写 @click -->
    <button @click="vueEvt()">按钮</button>
</div>
new Vue({
    // vue的methods属性用作定义方法的容器
	methods:{
        vueEvt() {
            console.log('这是一个vue事件')
        }
    }	
}).$mount('#node')

四、vue属性绑定

<div id="node">
    <!-- v-bind:用来绑定数据 -->
    <span v-bind:class="temp" v-bind:style="{color:num>70?'red':'blue'}"></span>
    <!-- v-bind:简写 : -->
    <span :class="temp" :style="{color:num>70?'red':'blue'}"></span>
</div>

五、虚拟节点

// 固定的一个项目入口文件
// 需要引入的 Vue 对象
import Vue from 'vue'
// 实例化vue
new Vue({
    // render(createElement:CreateElement):VNode
    // vue中有一个render函数,这个函数接收一个CreateElement,要求方法返回一个VNode -> virtual node 虚拟节点
    render(createElement) {
     	// createElement(VNodeTag:String , VNodeTata:Object , VNodeChildren:Array):VNode
    	// createElement方法接收三个参数,并且会返回一个VNode
    	let em = crateElement(
    		'em',
    		{},
        	['我是h1的子节点']
    	)
		let VNode = createElement(
    		'h1',
        	{
            	"class":'my-cls',
            	style:{
                	color:'#f00',
                	font-size:'20px'
            	}
        	},
        	[
            	'我是第一个子节点',
            	em
        	]
    	)
        return VNode
    }
    // 挂载后会自动注入public包下的index.html文件id="app"节点
}).$mount('#app')

虚拟DOM的优点

真实DOM更新节点,需要查找节点,更新内容,再渲染。

虚拟DOM是批量更新数据,然后更新虚拟DOM对象,最后挂载到DOM树上,只需要一次查询(对根节点进行查询),全部一次挂载。

六、Vue脚手架

针对 Vue 框架进行工程化后的一个封装,提供开发、打包、测试功能;通过前端构建框架(webpack)来构建一个 Vue 的开发环境和打包工具。

全局安装

$ npm i -g @vue/cli

初始化项目

// 创建新项目
$ vue create 项目名
// 选择手动配置选项
$ * Manually select features
// 选择 Vue 版本
$ * Choose Vue version 2.x
// 选择 ESLint 检查标准版本
$ * ESLint + Standard config
// eslint 检查时机
$ * Lint on sava -- 保存时进行检查,可以预先指定代码错误,由webpack中eslint-loader插件支持
// 项目的全局配置
$ * In dedicated config files

vue.config.js文件

module.exports = {
    // 关闭eslint-loader代码检查报错
    lintOnSave: false,
    // 配置多页应用
    pages: {
        // 每一个页面需要有一个名字,还应该有很多属性
        index: {
            // 指定当前应用的模板
            template: 'public/index.html',
            // 指定当前应用的入口文件
            entry: 'src/main.js'
        },
        // 配置home页面
        home:{
            template:'public/home.html',
            entry:'src/home.js'
        }
    },
    // 开发服务设置
    devServer:{
        // 设置一个启动端口
        port:16888,
        // 用浏览器打开并运行项目
        open:true,
        // 代理属性
        proxy:{
            // 定义一个代理字段,请求地址中,包含了"/apis"这个字段,就会执行这个代理配置
            '/apis': {
                // 目标服务器
                target:"http://www.shuiyue.info:14600",
                // 去掉请求地址中的"/apis",替换为""。
                pathRewrite:{'/apis':''}
            }
        } 
    }
}

七、组件

// src包下创建views组件包,并创建indx.vue文件
// .vue文件会被vue-loader加载器进行编译和加载
// 模板标签,会被vue-loader编译器编译为一个render方法
<template>
<!-- 顶层元素只能由一个,不能放多个兄弟节点 -->
	<div class="box">
        <h1>我是一个组件标题内容</h1>
        <h2>我是一个组件的副标题</h2>
    </div>
</template>

<script>
    // 不需要使用new关键字,只需导出一个对象即可,会被vue-loader自动编译
	export default {
        // 如果存在template,此方法会被覆盖 -- 方法重载
        render(createElement) {
            return createElement(
        		'div',
        		{},
        		['我是一个节点']
        	)
        }
    }
</script>
// 使用style来编写样式
// scoped属性 -- 声明当前样式仅限于此页面使用
<style scoped>
    .box{
        margin:auto;
        border:solid 1px;
    }
</style>

引入组件

<template>
	<div>
        <!-- 把注册的组件当作一个标签使用 -->
        <child/>
    </div>
</template>
<script>
    // 组件引入,可以不写.vue后缀
	import ChildNode from './child'
    export default {
        // 使用vue中的components方法进行组件注册
        components:{
            child:ChildNode
        }
    }
</script>

全局组件

// main.js 项目入口文件
import Vue from 'vue'
// 引入index组件,ES6木块话的寻址功能,引入一个包,自动查找包中的index.xx文件
// 这个App是一个组件,也是一个Vue实例对象
import App from './views'
exprot dafault {
    install(Vue) {
        // 注册全局组件
        Vue.component('组件名',path)
        // 使用VueConstructor的filter方法进行过滤器全局注册
        Vue.filter('自定义过滤器名字',function(value,type) {
            console.log(arguments)
        })
        // 使用VueConstructor的directive方法进行指令全局注册
        Vue.directive('自定义指令名字',function(el,bindData,newVNode,oldVNode) {
            console.log(arguments)
        })
        
    }
}

vue.use 和 vue.component

// 定义插件
install(Vue){ }
// 注册插件
Vue.use(插件名)

// 注册组件
Vue.component('组件名',path)

八、组件的生命周期

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CTqU5RPR-1631554755419)(E:\井振昊\笔记\三阶段\生命周期.png)]

九、组件通信

父组件传值给子组件

<!-- 在父组件种的子组件标签上使用绑定语法给子组件绑定一个属性 -->
<child-node :rate="myRate"/>
// 子组件
<script>
	export default {
        // 父组件通过属性传递下来的数据,使用props属性来接收
        props:{
            rate:{
                // 指定必传参数
                required:true,
                // 指定接收的数据类型
                type:Number,
                // 指定默认值
                default:0
            }
        }
    }
</script>

子组件给父组件传值

<template>
	<button @click="editEvent()">传值</button>
</template>
<script>
	export default{
        methods:{
            editEvent() {
                // emit是vue自带的方法,通过this.$emit调用
                // $emit(event:string,args:...any[])
                // event -> 自定义一个回调事件名字
                // args:...any[] -> 触发事件时候传递的参数
                this.$emit('dataEvt','传给父组件的值')
            }
        }
    }
</script>
<template>
	<my-child @dataEvt="myEvent" />
</template>
<script>
	exprot default{
    	methods:{
            myEvent() {
                console.log('接收到的参数',arguments)
            }
        }
    }
</script>

十、动态组件

<template>
	<!-- component是vue中定制的一个全局组件,用于动态渲染组件 -->
	<!-- 需要有一个 is 绑定属性,属性值为组件的名字 -->
	<component :is="注册组件名" />
</template>

十一、全局组件

// main.js文件中注册全局组件
// 先引入组件
import ModalNode from './compinents/Modal.vue'
// 单个注册
Vue.component('ModalNode',ModalNode)

// main.js文件中自定义vue插件
// 如果自定义插件是一个函数
function plugin(MyVue) {
	MyVue.component('ModalNode',ModalNode)
}

// 如果自定义插件是一个对象
const plugin = {
    install:function(MyVue) {
        MyVue.component('ModalNode',ModalNode)
    }
}

// compinents组件包中创建index.js文件
// 引入组件
import ModalNode from './Modal.vue'
// 自定义插件
const plugin = {
    install(Vue) {
        Vue.component('ModalNode',ModalNode)
        // 过滤器注册
        Vue.filter('format',function(value) {
            return newValue
        })
        // 自定义指令注册
        Vue.directive('format',function(el,baindData) {
            console.log(arguments)
        })
    }
}
// 导出插件
export default plugin
// main.js中直接注册
import plugin from './components'
Vue.use(plugin)

十二、事件广播

// main.js文件
new Vue({
    // 定义一个全局变量
    data() {
        return {
            // 定义一个new Vue()实例对象
            eventBus:new Vue()
        }
    },
    render:h => h(App)
}).$mount('#app')
// 触发自定义事件
this.$root.eventBus.$emit('全局回调事件')
// 监听
this.$root.eventBus.$on('监听事件名',function() {
    console.log(arguments)
})

十三、继承和混合

<script>
    引入数据对象
	import Paging from './common/Paging.vue'
    import Header from './common/Header.js'
    export default {
        // vue实例继承,只能实现单继承,包括原型链继承
        extends:Paging,
        // 仅将引入实例对象的属性值和当前的属性值进行混合,不能继承原型链
        mixins:[Paging,Header]
    }
</script>

十四、组件插槽

// 子组件
<template>
	<!-- 具名插槽 -->
	<slot name="title"/>
	<!-- 默认插槽 -->
	<slot/>
</template>

// 父组件
<template>
	<child-node>
        <!-- 具名插槽 -->
        <sapn slot="title">title插槽</sapn>
        <!-- v-slot传参必须用在template上,或者组件上 -->
        <template v-slot:header="scope">
			<p>我是scope插槽</p>
	   </template>
		<!-- 默认插槽 -->
		<!-- slot-scope用来传参,scope接收到一个对象 -->
    	<h1 slot="title" slot-scope="scope">我是插槽</h1>
    </child-node>
</template>

十五、监听和计算属性

<script>
	export default {
        // 监听属性,用于监听一个数据对象的变化
        watch: {
            // 监听属性的入参为:改变后的值,改变前的值
            dept(newValue,oldValue) {
                console.log(newValue,oldValue)
            },
            dept:{
                // 立即监听
                immediate:true,
                // 深监听,监听对象内部属性的变化
                deep:true
                // 处理函数
                handler:function(newValue,oldValue) {
                    console.log(newValue,oldValue)
                }
            }
        },
        // 计算属性
        computed:{
            // methods,computed方法名不能重名,重名字后,只会调用methods的方法
            myDutie:function() {
                return Date.now()
            }
        }
    }
</script>

十六、路由

// 安装路由插件
$ npm i -S vue-router

// main.js入口文件
// 引入路由插件
import Router from 'vue-router'
// 注册路由插件
Vue.use(Router)
// 引入页面组件
import LoginPage from './views/login'
// 对Router进行实例化
const router = new Router({
    // H5的history模式
    mode:"history",
    // routes 用于路由配置,接收一个路由配置对象的数组
    // path 属性用于自定义访问页面组件的路由
    // component 属性用于指定当前这个路由配置对象对应的页面组件是谁
    // 将path重新定向到一个路由
    routes:[{path:'/',redirect:'/login'},
            {path:'/login',component:LoginPage},
            {
                path:'/order',
                component:'./order',
                // children属性实现子路由,path属性前面不要带/
                children:[
                    {path:'edit',component:'./order/edit'},
                    {path:'list',component:'./order/list'}
                ]
            }
           ]
})
new Vue({
    // 把router实例对象注入到当前Vue实例对象中
    // Vue实例对象给出了一个router属性用于router实例注册
    // router:router,
    router,
    render:ce => ce(App)
}).$mount('#app')
<template>
	<!-- 路由缓存 -->
	<keep-alive>
     	<!-- 路由中配置的组件应该放置在这个地方 -->
    	<router-view></router-view>
    </keep-alive>
</template>

动态路由

// 定义一个动态路由
{path:'/user/:id',component:user}

// 在组件内部获取路径中定义的动态部分id
this.$route.params

路由query传参

// 路由
let router = new VueRouter({
      routes: [
        { path: '/login', component: login },
        { name:'register',path: '/register', component: register } 
      ]
})
// 导航
<router-link to="/login?id=10&name=jj">登录</router-link>
<router-link :to="{path:'/register',query:{id:5,name:'lili'}}">注册</router-link>
<router-link :to="{name:'register',query:{id:5,name:'lili'}}">注册</router-link>

// 等同于
this.$router.push('/login?id=10&name=jj')
this.$router.push({path:'/register',query:{id:5,name:'lili'}})
this.$router.push({name:'register',query:{id:5,name:'lili'}})

jquery可以通过name或path来引入路由

// 获取参数
this.$router.query

路由params传参

// 路由
let router = new VueRouter({
      routes: [
        { path: '/login/:id/:name', component: login },
        { name:'register',path: '/register/:id/:name', component: register } 
      ]
})
// 导航
<router-link to="/login/10/jj">登录</router-link>
<router-link :to="{name:'register',params:{id:5,name:'lili'}">注册</router-link>

// 等同于
this.$router.push('/login/10/jj')
this.$router.push({name:'register',params:{id:5,name:'lili'}})
// 获取参数
this.$router.params

路由拦截

/**
 * NavigationGuard导航卫士
 * @param to Route:即将要进入的目标,路由对象
 * @param form Route:当前导航正要离开的路由
 * @param next Function:路由跳转
 */
// 配置路由时,添加requireAuth属性用来判断该路由的访问是否需要登录
{path:'/manage',name:'manage',component:'manage',meta:{requireAuth:true}}
router.beforeEach((to,from,next) => {
    if(to.meta.requireAuth) {   // 判断该路由是否需要登录权限
        if(to.path === '/login') {    // 判断是否登录保存token
        	next()
    	} else {
        	let token = sessionStorange.getItem('token')
        	if(!token) {
            	next('/login')
        	} else {
            	next()
        	}
    	}
    } else {
        next()
    }
    
})

十七、状态管理器

状态管理器是什么

  • 状态管理器实际上就是全局对象,用于存储状态数据。
  • 全局数据不能对全局造成污染 – 闭包,所以这个库必须提供两个方法:获取方法(getter)、设置方法(setter)

插件引入

// 安装插件
$ npm i -S vuex
// 引入vuex插件
import Vuex from 'vuex'
// 把插件注册到Vue构造函数上
Vue.use(Vuex)
// 状态管理器实例化
const store = new Vuex.Store({
    // 使用modules属性来实现,使用模块化进行状态数据管理
    modules:{
        // 定义命名空间(作用域)名字
        common:{
            // 开启命名空间
            namespaced: true,
            // 在state属性上定义需要存储的状态数据
            state:{
                token:'init value',
                userInfo:{id:'admin',name:'超级管理员'}
            },
            // 获取数据的getter方法
            getters:{
                // 定义一个获取token的getter方法
                // 这个getter方法入参一个state对象进来
                getToken(state) {
                    return state.token
                }
            },
            // 改变一个状态数据的值的时候,需要使用mutations扭转属性,它相当于一个setter方法
            mutations:{
                // 扭转token,除了入参state对象,还会有用户传递进来的一个数据对象
                mutationToken(state,token) {
                    state.token = token
                }
            },
            // 定义一个执行异步动作的方法
            actions:{
                tokenAction(myStore,token) {
                    setTimeout(() => {
                        myStore.commit('mutationToken','AYSYNC' + token)
                    },1000)
                }
            }
        }
    }
})

new Vue({
    // store实例注入
    store,
    render:ce => ce(App)
}).$mount('#app')

组件中使用vuex

// 获取命名空间中的状态数据
// this.$store.getters['命名空间/getter方法名']
this.$store.getters['common/getToken']

// 调用mutations中的扭转方法
// this.$store.commit('命名空间/扭转方法名',传递的数据)
this.$store.commit('common/mutationToken',token)

// 调用异步来更i性能token数据
// this.$store.dispatch('异步方法名',传递的数据)
this.$store.dispatch('tokenAction',token)

vue-persistedstate第三方持久化状态管理库插件

// 安装第三方持久化状态管理库插件
$ npm i -S vuex-persistedstate@3

// 引入插件
import persistedState from 'vue-persistedstate'
// 注入插件
const store = new Vuex.Store({
    plugins:[
        persistedState({
            // 指定数据缓存到哪个webStorage中
            storage:window.sessionStorage
        })
    ],
    modules:{
        common
    }
})
// 导出
export default store

十八、axios第三方库

// 安装第三方库
$ npm i -S axios
// 引入axios第三方库
import axios from 'axios'
// 使用axios的创建方法,可以达到配置通用数据的功能
const NewAxios = axios.create({
    baseURL:'/apis',
    // 设置请求接口的请求时间
    timeout:5000
})
// 封装ajax
function Ajax(req) {
    // 设置url必传,否则报错
    if(!req.url) throw Error('请求地址必传')
    return new Promise(resolve => {
        // Promise嵌套
        NewAxios.request({
            url:req.url,
            method:req.method || 'GET',
            data:req.data || {},
            params:req.params || {}
        }).then(({data}) => {
            reslove(data)
        }).catch(e => {
            resolve(e)
        })
    })
}
export default Ajax
// axios的拦截器(请求前)
// config是请求对象,里面有请求地址、请求数据、请求方式等属性
NewAxios.interceptors.request.use(config => {
    // 从vuex获取token
    let token = store.getters['common/token']// 定义不需要拦截的路由
    	otherPath = [
            '/user/validate/code',
            '/user/app/login'
        ]
    // 判断请求的路由是否需要拦截
    if (otherPath.includes(config.url)) {
        return config
    } else {
        if(!!token) {
        	// 在headers上添加一个token数据,用于后端请求权限校验
        	config.headers.token = token
        	// 如果通过拦截,返回一个请求对象
        	return config
    } else {
        	// 请求被拦截,返回一个Promise,axios不会发起异步请求
        	return Promise.reject({code:440,message:'axios拦截'})
    	}
    }
})

十九、实现组件集成

App端很多的组件库:echarts、vant、ant-design-mobile(vue)、vux、mint、ionic,根据官网文档使用。

二十、自定义指令

<template>
	<h1 v-format="data">Hello Word!</h1>
</template>

<script>
	export default {
        directives:{
            // 函数形式
            format(el,bindData,newVNode, oldVNode) {
                console.log(arguments)
                // el -> 页面元素
                // bindData -> 绑定的数据对象
                // newVNode -> 当前虚拟DOM
                // oldVNode -> 更新前的虚拟DOM
            },
            // 对象形式,有完整的生命周期
            format:{
                // 指令绑定时候触发
                bind() {
                    console.log(arguments)
                },
                // 虚拟节点插入到页面元素上时执行
                inserted(el,bindData) {
                    console.log(arguments)
                },
                // 更新
                update() {
                    console.log('component will update')
                },
                compinentUpdated() {
                    console.log('component updated')
                },
                unbind() {
                    console.log('unbind')
                }
            }
        }
    }
</script>

二十一、过滤器

<template>
	<!-- 过滤器用法{{绑定数据 | 过滤器方法名}} -->
	<h1>{{data | format}}</h1>
</template>
<script>
	export default {
        filters:{
            // 过滤器中的参数是绑定的数据
            format(data) {
                console.log(arguments)
                // 过滤器需要返回一个值,返回值会在页面上进行渲染
                return newData
            }
        }
    }
</script>

二十二、父子组件传值(不建议使用)

<script>
	export default {
        created() {
            // 相当于父组件中的this
            console.log( this.$parent )
            // 获取所有的 VueComponent 子组件,是一个数组
            console.log( this.$children )
        }
    }
</script>

二十三、$nextTick

<script>
	export default {
        methods:{
            changeValue() {
                this.$nextTick( () => {
                    // 页面数据渲染后执行的业务逻辑代码
                } )
            }
        }
    }
</script>
<script>
	export default {
        methods:{
            async changeValue() {
                await this.$nextTick()
                // 页面数据渲染后再执行这里的业务逻辑代码
            }
        }
    }
</script>

mat}}




## 二十二、父子组件传值(不建议使用)

```vue
<script>
	export default {
        created() {
            // 相当于父组件中的this
            console.log( this.$parent )
            // 获取所有的 VueComponent 子组件,是一个数组
            console.log( this.$children )
        }
    }
</script>

二十三、$nextTick

<script>
	export default {
        methods:{
            changeValue() {
                this.$nextTick( () => {
                    // 页面数据渲染后执行的业务逻辑代码
                } )
            }
        }
    }
</script>
<script>
	export default {
        methods:{
            async changeValue() {
                await this.$nextTick()
                // 页面数据渲染后再执行这里的业务逻辑代码
            }
        }
    }
</script>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java Vue框架是指使用Java语言和Vue.js框架来开发Web应用程序的一种技术架构。Java是一种跨平台的编程语言,具有强大的面向对象特性和丰富的生态系统,被广泛应用于企业级应用程序开发。而Vue.js是一种轻量级的JavaScript框架,用于构建用户界面,具有简洁的语法和灵活的组件化开发模式。 Java Vue框架的优势在于它能够充分发挥Java的后端能力和Vue.js的前端特性。Java作为后端语言,可以处理各种复杂的业务逻辑和数据处理,同时提供了可靠的安全性和性能。而Vue.js作为前端框架,能够提供丰富的用户界面和良好的用户体验,支持响应式设计和组件化开发。 使用Java Vue框架可以迅速构建现代化的Web应用程序。Java提供了强大的后端支持,包括数据库访问、事务处理、安全认证等功能。Vue.js提供了灵活的前端组件化开发模式,可以构建出复杂的用户界面,并实现前后端数据的无缝交互。这使得开发人员可以按照自己的需求,选择合适的组件和技术,快速构建出高质量的Web应用程序。 此外,Java Vue框架也具有良好的可维护性和扩展性。Java的面向对象特性使得代码可以更加模块化和可复用,便于团队协作和项目管理。Vue.js的组件化开发模式使得前端代码可以更好地组织和维护,而且可以根据需求进行灵活的扩展和定制。 综上所述,Java Vue框架结合了Java的后端能力和Vue.js的前端特性,可以快速构建现代化的Web应用程序,具有良好的可维护性和扩展性。这使得Java Vue框架成为开发人员的首选技术之一。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值