(给达达前端加星标,提高前端技能)javascript
面试官问:Vue如何安装的呢?php
达达回答:Vue的安装能够从两个方面进行安装,第一种是CDN引入,第二种是NPM安装。css
CDN引入html
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
NPM安装前端
npm install vue
面试官问,如何建立Vue项目?vue
达达写下代码:java
建立项目node
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Vue入门之Helloworld</title> <!--引入Vue库--> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> </head> <body> <!--建立一个Div--> <div id="app"> <!--Vue的模板的绑定数据的方法,用两对花括号进行绑定Vue中的数据对象的属性 --> {{message}} </div> <!--建立Vue的对象,并把数据绑定到上面建立好的div上去。--> <script type="text/javascript"> var app=new Vue({ // 建立Vue对象。Vue的核心对象。 el:'#app', // el属性:把当前Vue对象挂载到 div标签上,#app是id选择器 data:{ // data: 是Vue对象中绑定的数据 message:'hello Vue!' // message 自定义的数据 } }) </script> </body> </html>
输出的结果:react
hello Vue!
面试官问:v-if和v-show的区别是?webpack
达达回答:
内部指令
v-if用于显示与隐藏的元素
<div v-if="isShow">达达前端</div>
v-else,v-if不是它,就是它v-else
<div v-else>达达前端</div>
v-show
<div v-show="isShow">你好</div>
v-else-if
<div v-if="type === 'A'">A</div> <div v-else-if="type === 'B'">B</div> <div v-else-if="type === 'C'">C</div> <div v-else>Not A/B/C</div>
v-if和v-show的区别是:
v-if用于元素的被销毁和重建,使用这个指令开销较为高,在运行过程当中,尽可能用在不多改变时的状况下使用。v-if元素销毁和存在
v-show的用法,这个指令的使用开销较小,在常频繁地切换使用
面试官问:内部指令的用法有哪些,怎么用呢?
达达回答:好,慢慢讲述。
v-for的用法
<!-- 模板 --> <div id="app"> <ul> <li v-for="item in items"> {{item}} </li> </ul> </div> <!--JS代码 --> <script type="text/javascript"> var app=new Vue({ el:'#app', data:{ items:[ 1, 2, 3, 4] } }) </script>
对象遍历
<!-- 模板 --> <div id="app"> <ul> <li v-for="(value, key, index) in object"> {{ index }}. {{ key }} - {{ value }} </li> </ul> </div> <!--JS代码 --> <script type="text/javascript"> var app=new Vue({ el:'#app', data:{ object: { firstName: 'dada', lastName: 'qianduan' } } }) </script>
v-text的出现为了解决{{xx}}这个取值的问题,当网络很慢的状况下,或者是运行时出错的状况下,页面显示为{{xxx}}。
<div>{{ message }}</div> <!-- 同样的 --> <div v-text="message"></div>
v-html指令是用于输出html代码
<span v-html="msgHtml"></span>
v-on的用法
// html <div>{{count}}</div> <button v-on:click="add">加</button> // JS data:{ count: 1 }, methods: { add() { this.count++; } }
缩写
<button @click="add">加</button>
v-model的用法,model都须要在data中声明初始值:
data: { count: 1, }
input的用法
<input type="text" v-model="message">
textarea
<textarea cols="30" rows="10" v-model="message"></textarea>
checkbox
<input type="checkbox" id="first" value="1" v-model="status"> <label for="first">有效</label> <input type="checkbox" id="second" value="2" v-model="status"> <label for="second">无效</label> <div>状态:{{status}}</div>
radio
<input type="radio" id="one" value="男" v-model="sex"> <label for="one">男</label> <input type="radio" id="two" value="女" v-model="sex"> <label for="one">女</label> <div>性别:{{sex}}</div>
select
<select v-model="selected"> <option disabled value="">请选择</option> <option>A</option> <option>B</option> <option>C</option> </select> <div>Selected: {{ selected }}</div>
v-bind方法
// html <img v-bind:src="imgSrc" width="200px"> // js data: { imgSrc:'' }
缩写
<img :src="imgSrc" width="200px">
v-pre方法,用这个指令能够直接跳过vue的编译,直接输出原始值,若是在标签中加入v-pre就不会输出vue中的data值。
<div v-pre>{{message}}</div>
v-cloak能够在vue渲染时指定的整个dom后才进行显示,必须和css样式一块儿用
// css [v-cloak] { display: none; } // html <div v-cloak>{{message}}</div>
v-once只能显示一次,第一次渲染的值就不会改变了
<div v-once>{{message}}</div>
面试官问:你知道Vue生命周期吗?
达达回答:
new Vue() 实例化对象,init events & lifecycle 初始化,事件和生命周期
beforeCreate组件实例刚被建立,尚未实例化以前,执行一些初始化的操做,能够制做加载动画
init injections & reactivity 初始化,依赖注入和校验
created组件实例建立完成,属性已经绑定,可是dom尚未生成,$el属性还不存在,页面未被展现,结束加载动画,发起异步网络请求
has"el" option? no 判断是否存在el属性,若是有,则继续编译,若是没有,则中止编译,生命周期结束,知道在该vue实例上调用vm.$mount(el),即被唤醒继续执行编译,若是注释掉“el”,等程序到create就中止了
判断是否有template,若是有,则将其编译成render函数,若是没有,则将外部的HTML做为模板编译,template中的模板优先级高于outer html 的优先级。
yes的路线,compile template into render function
若是tremplate中组件的话,执行render方法渲染组件内容
compile el's outerhtml as template
beforeMount,完成虚拟dom配置,模板已经被编译,把data里面的数据和模板生成html,此时尚未挂载html到页面上
create vm.$el and replace "el" with it,给vue实例对象添加$el成员,而且替换掉挂载的dom元素
mounted,用上面编译好的html内容替换el属性指向dom对象,方法结束后,dom结构完成,页面显示出来,发起网络请求
Mounted,when data changes,beforeUpdate,当vue发现data中的数据发生了改变,会触发对应组件的从新渲染,通常在组件发生更新以前,调用这个函数,页面还不会展现修改的内容,但虚拟dom已经配置修改
virtual dom re-render and patch,从新渲染虚拟dom并经过diff算法对比vonde节点差别更新真实dom,updated,组件更新后,此方法执行后,修改后的页面展示出来,即为view从新渲染,数据更新
when wm.$destroy() is called,beforeDestroy,组件实例销毁前调用,实例仍然彻底可用
teardown watchers, child components and event listeners 拆卸观察者,子组件,事件监听者
destroyed,在vue实例销毁后调用,实例指示的全部东西都会被解除绑定,全部的事件监听都会被移除,全部的子实例都会被销毁
面试官问:在vue中经常使用的语句有哪些
达达回答:好的,请认真听讲
computed计算属性,用于对原数据进行修改
computed: { newPrice () { return '¥' + this.price + '元'; } }
methods方法属性,用于绑定方法
methods:{ add (num) { this.count += num; } }
watch数据变化监听器
watch: { question(val, oldVal) { console.log('new: %s, old: %s', val, oldVal); } }
filters 过滤器
filters: { filterA(value) { return value.toUpperCase(); } }
mixins用于减小代码污染,减小代码量,实现代码重用
var addLog={ updated:function(){ console.log("数据放生变化,变化成"+this.count+"."); } } var app = new Vue({ el:'#app', data:{ count: 100 }, // 混入 mixins: [addLog] })
extends用于扩展,对构造器进行扩展
var extendObj ={ created: function(){ console.log("我是"); } } var app = new Vue({ el:'#app', data:{ }, // 扩展 extends: extendObj })
面试官问,你知道哪些实例事件吗?
达达回答,vue有实例属性,实例方法,实例事件
$on接收两个参数,第一个参数是调用时的事件名称,第二个参数是一个匿名方法 app.$on('reduce',function(){ console.log('执行了reduce()'); this.count--; }); app.$once('reduceOnce',function(){ console.log('只执行一次的方法'); this.count--; }); function off(){ console.log('关闭事件'); app.$off('reduce'); } function reduce() { // 事件调用 console.log('emit事件调用'); app.$emit('reduce'); }
面试官问:你知道自定义指令吗
达达回答:知道吧
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Vue入门之自定义指令</title> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> </head> <body> <div id="app"> <div v-test="color"> {{num}} </div> </div> <button onclick="unbindApp()">解绑</button> <script type="text/javascript"> function unbindApp() { app.$destroy(); } // 自定义指令 Vue.directive("test",{ //被绑定 bind:function (el, binding, vnode) { console.log("1-bind 被绑定"); console.log("el:",el); console.log("binding:",binding); console.log("vnode:",vnode); el.style.color = binding.value; }, //被插入 inserted:function (el, binding, vnode) { console.log("2-inserted 被插入"); }, //更新 update:function (el, binding, vnode) { console.log("3-update 更新"); }, //更新完成 componentUpdated:function (el, binding, vnode) { console.log("4-componentUpdated 更新完成"); }, //解绑 unbind:function (el, binding, vnode) { console.log("5-unbind 解绑"); } }); var app = new Vue({ el:'#app', data:{ num: 123, color:'red' } }) </script> </body> </html>
面试官问:你用过组件吗?
达达回答,用过的
组件全局注册
Vue.component('button-counter', { data: function () { return { count: 0 } }, template: '<button v-on:click="count++">全局组件: {{ count }}</button>' }); new Vue({ el: '#app' }); <button-counter></button-counter>
组件局部注册
new Vue({ el: '#app', components:{ "button-inner":{ data: function() { return { inner: 0 } }, template: '<button v-on:click="inner++">局部组件: {{ inner }}</button>' } } }); <button-inner></button-inner>
props属性传值
new Vue({ el: '#app', components:{ "button-props":{ template:` <div > 参数1: {{ da }}:---参数2: {{fromHere}} </div> `, props:['da', 'fromHere'] } } }); // html使用 <button-props da="da" from-here="world"></button-props> props中须要驼峰取值
父子组件
// 子组件 var city = { template:`<div>dada</div>` } // 父组件 var parent = { template: `<div> <p> dadada!</p> <city></city> </div>`, components:{ "city": city } } // 实例化 new Vue({ el: '#app', // 定义局部组件 components:{ // 组件注册 "parent": parent } }); // html使用 <parent></parent>
面试官:你了解模板吗?
达达回答:还好
<div id="app"> </div> <script type="text/javascript"> // 实例化 new Vue({ el: '#app', data: { message: 'hello' }, template:`<h1 >模板</h1>` }); </script>
<div id="app"> <template id="demo2"> <h2 >template模板</h2> </template> </div> <script type="text/javascript"> // 实例化 new Vue({ el: '#app', data: { message: 'hello' }, template:'#demo2' }); </script>
<div id="app"> </div> <script type="x-template" id="demo3"> <h2 >script标签模板</h2> </script> <script type="text/javascript"> // 实例化 new Vue({ el: '#app', data: { message: 'hello' }, template:'#demo3' }); </script>
面试问:你了解插槽不?
达达回答:插槽就是slot,是组件的一块Hmtl模板
<div id="app"> <children> <span>123</span> </children> </div> <script type="text/javascript"> var app = new Vue({ el: '#app', components: { children: { template: "<button><slot></slot>单个插槽</button>" } } }); </script>
具名插槽slot,具名插槽能够在一个组件中出现n次
<div id="app"> <children> <span slot="first" @click="toknow">123</span> <span slot="second">456</span> </children> </div> <script type="text/javascript"> var app = new Vue({ el: '#app', methods: { toknow: function () { console.log("dada"); } }, components: { children: { template: "<button> <slot name='first'> </slot> 具名插槽 <slot name='second'> </slot> </button>" } } }); </script>
做用域插槽slot
<div id="app"> <!-- 将数据传递给组件 --> <tb-list :data="data"> <template slot-scope="scope"> <p>索引:{{JSON.stringify(scope)}}</p> <p>索引:{{scope.$index}}</p> <p>姓名:{{scope.row.name}}</p> <p>年龄: {{scope.row.age}}</p> <p>性别: {{scope.row.sex}}</p> </template> </tb-list> </div> <script type="text/javascript"> var app = new Vue({ el: '#app', data: { data: [{ name: 'dada', age: '12', sex: 'man' }] }, components: { // 做用域slot 'tb-list': { template: `<ul> <li v-for="(item, index) in data"> <slot :row="item" :$index="index"> </slot> </li> </ul>`, // 获取值 props: ['data'] } } }); </script>
面试官问:你用过vue-cli吗?说一说
达达回答:好的
vue-cli安装,第一用npm安装
npm -v
vue-cli安装
npm install vue-cli -g
vue -V -g表明全局安装,而后查看版本
初始化项目
用vue init命令来初始化项目 vue init <template-name> <project-name> init:表示要用vue-cli来初始化项目 <template-name>:表示模板名称 vue-cli官方提供的5种模板 webpack webpack-simple browserify browserify-simple simple <project-name>:标识项目名称,用户根据本身的项目来起名字。
项目初始化
vue init webpack my-vue-demo
Project name:项目名称 Project description:项目描述 Author:做者 Install vue-router? 是否安装vue的路由插件,须要安装,选择Y Use ESLint to lint your code? 是否用ESLint来限制你的代码错误和风格。不须要输入n,须要选择y setup unit tests with Karma + Mocha? 是否须要安装单元测试工具 Setup e2e tests with Nightwatch? 是否安装e2e来进行用户行为模拟测试
运行项目
npm run dev npm run build
面试官问:你了解vue-router吗?说一说
达达回答,嗯,了解。
安装
npm install vue-router --save
核心文件
import Vue from 'vue' import Router from 'vue-router' import HelloWorld from '@/components/HelloWorld' // Vue全局使用Router Vue.use(Router) export default new Router({ routes: [ //配置路由,这里是个数组 { //每个连接都是一个对象 path: '/', //连接路径 name: 'HelloWorld', //路由名称, component: HelloWorld //对应的组件模板 } ] })
使用
import Vue from 'vue' import App from './App' import router from './router' Vue.config.productionTip = false new Vue({ el: '#app', router, // 注入框架中 components: { App }, template: '<App/>' })
页面跳转
<router-link to="/">[显示字段]</router-link> <p>导航 : <router-link to="/">首页</router-link> <router-link to="/hello">hello</router-link> </p>
编程式导航
this.$router.push('/xxx') <button @click="goHome">回到首页</button> export default { name: 'app', methods: { goHome(){ this.$router.push('/home'); } } } // 同于 history.back() this.$router.go(-1) // 同于 history.forward() this.$router.go(1)
路由嵌套
<template> <div class="hello"> <h1>{{ msg }}</h1> <p>导航 : <router-link to="/home">首页</router-link> | <router-link to="/home/one">-子页面1</router-link> | <router-link to="/home/two">-子页面2</router-link> </p> <router-view/> </div> </template> <script> export default { name: 'Home', data () { return { msg: 'dada!' } } } </script> <style scoped> </style>
子页面
<template> <div class="hello"> <h1>{{ msg }}</h1> </div> </template> <script> export default { name: 'One', data () { return { msg: 'Hi, I am One Page!' } } } </script> <style scoped> </style> <template> <div class="hello"> <h1>{{ msg }}</h1> </div> </template> <script> export default { name: 'Two', data () { return { msg: 'Hi, I am Two Page!' } } } </script> <style scoped> </style>
路由配置
import Vue from 'vue' import Router from 'vue-router' import Home from '@/components/Home' import One from '@/components/One' import Two from '@/components/Two' Vue.use(Router) export default new Router({ routes: [ { path: '/', // 默认页面重定向到主页 redirect: '/home' }, { path: '/home', // 主页路由 name: 'Home', component: Home, children:[ // 嵌套子路由 { path:'one', // 子页面1 component:One }, { path:'two', // 子页面2 component:Two }, ] } ] })
路由传递参数
<router-link :to="{name:xxx, params: {key:value}}"> dada </router-link>
<router-link :to="{name: 'one', params:{username:'123'}}"> 子页面 </router-link>
{ path:'one', // 子页面 name: 'one', // 路由名称-命名路由 component:One }
<h2>{{$route.params.username}}</h2>
url中传递参数
{ path:'/home/two/:id/:name', // 子页面 component:Two },
<p>ID:{{ $route.params.id}}</p> <p>名称:{{ $route.params.name}}</p>
<router-link to="/home/two/1/达达">子页面</router-link>
编程式导航带参数
{ path:'/home/three', // 子页面 name: 'three', component:Three }
<p>ID:{{ $route.params.id}}</p> <p>名称:{{ $route.params.name}}</p>
<button @click="toThreePage">页面-params传参</button> // script methods: { toThreePage() { this.$router.push( { name: 'three', params: { id: 1, name: 'dada' } } ) } }
query传参数
{ path:'/home/three', // 子页面 name: 'three', component:Three }
<p>ID:{{ $route.query.id}}</p> <p>名称:{{ $route.query.name}}</p>
<button @click="toThreePage">页面-params传参</button> methods: { toThreePage() { this.$router.push( {path: '/home/three', query: {id: 1, name: 'da'}} ) } }
命名路由
{ path: 'one', // 子页面 name: 'one', // 路由名称-命名路由 component: One // 页面组件 }
// template跳转调用 <router-link :to="{name: 'one'}">子页面</router-link> // router.push函数跳转调用 router.push({ name: 'user'}})
import Vue from 'vue' import Router from 'vue-router' // 建立页面组件 const Header = { template: '<div>Header</div>' } const Left = { template: '<div>Left</div>' } const Right = { template: '<div>Right</div>' } Vue.use(Router) export default new Router({ routes: [ { path: '/', // 主页路由 components: { default: Header, a: Left, b: Right } } ] }) <template> <div id="app"> <router-view /> <router-view name="a" class="left" /> <router-view name="b" class="right" /> </div> </template> <script> export default { name: 'App' } </script> <style> #app { text-align: center; color: #2c3e50; width: 500px; border: 1px solid red; margin: 0 auto; } .left,.right{ float: left; width:48%; text-align: center; border:1px solid red } </style>
重定向
export default new Router({ routes: [ { path: '/', // 默认页面重定向到主页 redirect: '/home' // 重定向 }, { path: '/home', // 主页路由 component: Home, children:[ // 嵌套子路由 { path:'/home/two/:id/:name', // 子页面 component:Two }, { path:'/home/three/:id/:name', // 子页面 name: 'three', // 路由名称-命名路由 redirect: '/home/two/:id/:name' // 重定向-传递参数 }, ] } ] })
<router-link to="/">首页</router-link> | <router-link to="/home/two/1/lisi">子页面</router-link> | <router-link :to="{name: 'three', params: {id: 1, name: 'dada'}}"> 子页面 </router-link>
redirect: '/home' // 重定向-不带参数
redirect: '/home/two/:id/:name' // 重定向-传递参数
别名
{ path:'/one', // 子页面 component:One, alias: '/oneother' }
<router-link to="/oneother">子页面1</router-link>
过渡动画
<transition name="fade" mode="out-in"> <router-view /> </transition>
.fade-enter-active { transition: opacity .5s; } .fade-enter { opacity: 0; } .fade-leave { opacity: 1; } .fade-leave-active { opacity:0; transition: opacity .5s; }
mode模式
export default new Router({ mode: 'history', //mode模式 routes: [...] })
404
// 404 { path: '*', component: () => import('@/components/404') }
路由钩子,第一全局钩子,第二,路由单独钩子,第三,组件内钩子
const router = new VueRouter({ ... }) // 全局路由拦截-进入页面前执行 router.beforeEach((to, from, next) => { next(); }); router.afterEach(() => { }); export default router;
路由单独钩子
{ path:'/home/one', // 子页面 component: One, beforeEnter: (to, from, next) => { console.log('进入前执行'); next(); } }
组件内钩子
<script> export default { name: 'Two', data () { return { msg: 'dada' } }, beforeRouteEnter(to, from, next) { console.log('进入enter路由钩子') next() }, beforeRouteLeave(to,from, next){ console.log('进入leave路由钩子') next() }, beforeRouteUpdate(to, from, next) { console.log('进入update路由钩子') console.log(to.params.id) next() } } </script>
路由
import Home from '@/components/Home' { path: '/home', component: Home }
面试官问:你了解vuex是什么吗?要不也说说
达达回答:好的。
vuex是一个为 Vue.js 应用程序开发的状态管理模式。采用集中式存储管理应用的全部组件的状态,以相应的规则保证状态以一种可预测的方式发生变化。
单向数据流
vuex的核心
安装
npm install vuex --save
使用
import Vue from 'vue' import Vuex from 'vuex' Vue.use(Vuex) const state = { count: 1 } const mutations = { DA(state, n) { state.count += n; } } const getters = { count: function(state){ return state.count; } } const actions ={ // 触发mutations中相应的方法-通常小写 add ({commit}, data) { commit('DA', data) } } const store = new Vuex.Store({ state, mutations, getters, actions }); export default store;
<h2>{{ $store.state.count }}</h2>
computed: { count() { return this.$store.state.count; } }
computed: mapState({ // es5写法 count: function (state) { return state.count; }, // es6写法 count: state => state.count })
数组获取 computed: mapState(['count'])
computed: mapState({ count: 'count' })
<button @click="$store.commit('DA')">+</button> const mutations = { // 状态变动函数 DA(state) { state.count++; } }
每一个模块拥有本身的 state、mutation、action、getter、甚至是嵌套子模块,从上至下进行一样方式的分割。
// 模块A const moduleA = { state: { ... }, mutations: { ... }, actions: { ... }, getters: { ... } } // 模块B const moduleB = { state: { ... }, mutations: { ... }, actions: { ... } } // 组装 const store = new Vuex.Store({ modules: { a: moduleA, b: moduleB } }) // 取值 store.state.a // -> moduleA 的状态 store.state.b // -> moduleB 的状态
面试官最后一问:你了解axios吗?
达达回答:嗯,用过。
Axios 是基于 promise 的 HTTP 库,用在浏览器和 node.js 中。就是前端最火最简单的一个http请求解决方案。
安装
npm install vuex --save
代码封装
import fetch from '@/util/fetch' const TMPURL = ''; // url地址 const params = {}; // 参数 fetch.post(TMPURL + '/login/login', params);
import axios from 'axios'; const httpService = axios.create({ baseURL: process.env.BASE_API, // 需自定义 // 请求超时时间 timeout: 3000 }); // request拦截器 httpService.interceptors.request.use( config => { // 加入token if (true) { config.headers['User-Token'] = ''; } return config; }, error => Promise.reject(error); } ) // respone拦截器 httpService.interceptors.response.use( response => { const res = response.data; if (res.statuscode != 1) { return Promise.reject({ status: res.statuscode, message: res.message }); } else { return response.data; } }, error => { if (error && error.response) { switch (error.response.status) { case 400: error.message = '错误请求'; break; case 401: error.message = '未受权,请从新登陆'; break; case 403: error.message = '拒绝访问'; break; case 404: error.message = '请求错误,未找到该资源'; break; case 405: error.message = '请求方法未容许'; break; case 408: error.message = '请求超时'; break; case 500: error.message = '服务器端出错'; break; case 501: error.message = '网络未实现'; break; case 502: error.message = '网络错误'; break; case 503: error.message = '服务不可用'; break; case 504: error.message = '网络超时'; break; case 505: error.message = 'http版本不支持该请求'; break; default: error.message = `未知错误${error.response.status}`; } } else { error.message = "链接到服务器失败"; } return Promise.reject(error); } ) /* * get请求 * url:请求地址 * params:参数 * */ export function get(url, params = {}) { return new Promise((resolve, reject) => { httpService({ url: url, method: 'get', params: params }).then(response => { resolve(response); }).catch(error => { reject(error); }); }); } /* * post请求 * url:请求地址 * params:参数 * */ export function post(url, params = {}) { return new Promise((resolve, reject) => { httpService({ url: url, method: 'post', data: params }).then(response => { resolve(response); }).catch(error => { reject(error); }); }); } /* * 文件上传 * url:请求地址 * params:参数 * */ export function fileUpload(url, params = {}) { return new Promise((resolve, reject) => { httpService({ url: url, method: 'post', data: params, headers: { 'Content-Type': 'multipart/form-data' } }).then(response => { resolve(response); }).catch(error => { reject(error); }); }); } export default { get, post, fileUpload }
推荐系列
推荐阅读 点击标题可跳转
【面试Vue全家桶】vue前端交互模式-es7的语法结构?async/await
【面试须要】掌握JavaScript中的this,call,apply的原理
2019年的每一天日更只为等待她的出现,好好过余生,庆余年 | 掘金年度征文
以为本文对你有帮助?请分享给更多人
关注「达达前端」加星标,提高前端技能
在博客平台里,将来的路还很长,也但愿本身之后的文章你们能多多支持,多多批评指正,咱们一块儿进步,一块儿走花路。
很是感谢读者能看到这里,若是这个文章写得还不错,以为「达达」我有点东西的话,以为我可以坚持的学习,以为此人能够交朋友的话, 求点赞,求关注,求分享,对暖男我来讲真的
很是有用!!!
感谢阅读,原创不易,喜欢就点个[在看] or [转发朋友圈],这是我写做最大的动力。
意见反馈
若本号内容有作得不到位的地方(好比:涉及版权或其余问题),请及时联系咱们进行整改便可,会在第一时间进行处理。
这是一个有质量,有态度的公众号
点关注,有好运
好文章,我在看❤️