首页 > 其他分享 >vue的seo

vue的seo

时间:2023-01-12 10:26:17浏览次数:52  
标签:vue name 张老师 ssr seo data id

我们知道,常规用 Vue/React 开发的是 SPA 应用。
但是天然的单页面应用 SEO 就是不好。

虽然说现在也有各种技术可以改善了,比如使用服务端渲染、静态页面生成,不过也存在各种缺点。
但是即使这样,也抵不住 Vue/React 这类框架的潮流。

也有很多产品也可以通过其他亮点而不依赖 SEO 普及开,
也有需要登录才能用的,使用 SEO 也没有什么意义。

几个名词

CSR: Client Side Render 客户端渲染,即普通的SPA
SSR: Server Side Render 服务端渲染
SSG: Static Site Generation 静态生成, 也有人称其为预渲染Prerendering
这个在使用此类框架创建项目的时候,会让你选择。比如nuxtJS

? Rendering mode: // 选择你想要的 Nuxt 模式

Universal (SSR / SSG) // 通用模式 ssr或者ssg
 Single Page App // 普通spa模式

SSR vs SSG

如果你调研服务器端渲染 (SSR) 只是用来改善少数营销页面(例如 /, /about, /contact 等)的 SEO,那么你可能需要预渲染。无需使用 web 服务器实时动态编译 HTML,而是使用预渲染方式,在构建时 (build time) 简单地生成针对特定路由的静态 HTML 文件。优点是设置预渲染更简单,并可以将你的前端作为一个完全静态的站点。

SSG 性能最佳,SSR 适用范围最广,CSR 跳转体验最优,非得在三者之间做出抉择吗?不,我全都要

CSR模式

这是Vue/React默认的模式。在这种模式下,页面之间跳转体验良好,借助于vdom、historyApi等技术,让网站交互如原生app般流畅。 但是却对seo不好,尤其是国内搜索引擎,如百度爬虫。

<!DOCTYPE html>
<html lang="">
	<head>
		<meta charset="utf-8" />
		<meta http-equiv="X-UA-Compatible" content="IE=edge" />
		<meta name="viewport" content="width=device-width,initial-scale=1" />
		<link rel="icon" href="/favicon.ico" />
		<title>csr-vue</title>
		<link href="/js/about.addee37b.js" rel="prefetch" />
		<link href="/css/app.b087a504.css" rel="preload" as="style" />
		<link href="/js/app.a33b1734.js" rel="preload" as="script" />
		<link href="/js/chunk-vendors.2d69e2a7.js" rel="preload" as="script" />
		<link href="/css/app.b087a504.css" rel="stylesheet" />
	</head>
	<body>
		<noscript>
			<strong>
				We're sorry but csr-vue doesn't work properly without JavaScript enabled.
				Please enable it to continue.
			</strong>
		</noscript>
		<div id="app">
		</div>
		<script src="/js/chunk-vendors.2d69e2a7.js">
		</script>
		<script src="/js/app.a33b1734.js">
		</script>
	</body>
</html>

可以看到,客户端渲染是通过加载执行JS来创建DOM元素构建页面,但是爬虫只是请求静态资源,不会执行JS文件,所以抓取不到DOM结构,也分析不出来有用的信息。

SSR模式

ssr和ssg均有原生的编写模式,如vue的vue-server-renderer、react的react-dom/server。但是编写起来较为麻烦,除了研究外,实际用于生产的较少,作为研究原理性质可用。如果后边有时间 会单拉出来讲
现在我们使用框架来解决,vue对应的为nuxtJs(对应的react的框架为nextjs)。

用脚手架创建项目完毕npx create-nuxt-app ssr-vue,
并且本地运行启动npx create-nuxt-app ssr-vue

<!doctype html>
<html data-n-head-ssr lang="en" data-n-head="%7B%22lang%22:%7B%22ssr%22:%22en%22%7D%7D">

<head>
    <title>ssr-vue</title>
    <meta data-n-head="ssr" charset="utf-8">
    <meta data-n-head="ssr" name="viewport" content="width=device-width, initial-scale=1">
    <meta data-n-head="ssr" data-hid="description" name="description" content="">
    <link data-n-head="ssr" rel="icon" type="image/x-icon" href="/favicon.ico">
    <link rel="preload" href="/_nuxt/runtime.js" as="script">
    <link rel="preload" href="/_nuxt/commons/app.js" as="script">
    <link rel="preload" href="/_nuxt/vendors/app.js" as="script">
    <link rel="preload" href="/_nuxt/app.js" as="script">
    <link rel="preload" href="/_nuxt/pages/index.js" as="script">
    <link rel="preload" href="/_nuxt/components/logo.js" as="script">
    <style data-vue-ssr-id="3191d5ad:0">
        .nuxt-progress {
            position: fixed;
            top: 0px;
         ...
    </style>
</head>

<body>
    <div data-server-rendered="true" id="__nuxt">
        <!---->
        <!---->
        <div id="__layout">
            <div>
                <div class="container">
                    <div>
                      	<svg>...</svg>
                        <h1 class="title">
                            ssr-vue
                        </h1>
                        <div class="links"><a href="https://nuxtjs.org/" target="_blank" rel="noopener noreferrer" class="button--green">
                                Documentation
                            </a> <a href="https://github.com/nuxt/nuxt.js" target="_blank" rel="noopener noreferrer" class="button--grey">
                                GitHub
                            </a></div>
                    </div>
                </div>
            </div>
        </div>
    </div>
    <script>
        window.__NUXT__ = (function(a, b) {
            return {
                layout: "default",
                data: [{}],
                fetch: {},
                error: a,
                serverRendered: true,
                routePath: b,
                config: {
                    app: {
                        basePath: b,
                        assetsPath: "\u002F_nuxt\u002F",
                        cdnURL: a
                    }
                },
                logs: []
            }
        }(null, "\u002F"));
    </script>
    <script src="/_nuxt/runtime.js" defer></script>
    <script src="/_nuxt/pages/index.js" defer></script>
    <script src="/_nuxt/components/logo.js" defer></script>
    <script src="/_nuxt/commons/app.js" defer></script>
    <script src="/_nuxt/vendors/app.js" defer></script>
    <script src="/_nuxt/app.js" defer></script>
</body>
</html>

可以看到dom已经在服务端渲染完毕

我们不用官方脚手架生成的页面,下边我们自己写一个demo,包含请求

<template>
  <div class="container">
    <fieldset>
      <legend>ssr-asyncData数据</legend>
      <div v-for="item in teachers" :key="item.id">姓名: {{item.name}}</div>
    </fieldset>

     <fieldset>
      <legend>ssr-data数据</legend>
      <div v-for="item in teachers1" :key="item.id">姓名: {{item.name}}</div>
    </fieldset>

    <fieldset>
      <legend>ssr-created</legend>
      <div v-for="item in teachers2" :key="item.id">姓名: {{item.name}}</div>
    </fieldset>

    <fieldset>
      <legend>csr-mounted数据</legend>
      <div v-for="item in teachers3" :key="item.id">姓名: {{item.name}}</div>
    </fieldset>
  </div>
</template>

<script>
const getTeachers = ()=> {
  return new Promise((resolve,reject)=>{
    setTimeout(()=>{
      const teachers = [
        {id:202101,name:'张老师'},
        {id:202102,name:'丁老师'}
      ];
      resolve(teachers);
    },2000)
  })
}
export default {
  data(){ // 会走ssr
    return {
      teachers1: [
        {id:202101,name:'张老师1'},
        { id:202102,name:'丁老师1'}
      ],
      teachers2: [],
      teachers3: []
    }
  },

  mounted(){ // 会走csr
    this.teachers3 = [
      {id:202101,name:'张老师3'},
      {id:202102,name:'丁老师3'}
    ]
  },

  created(){ // 会走ssr
    this.teachers2 = [
      {id:202101,name:'张老师2'},
      {id:202102,name:'丁老师2'}
    ]
  },

  async asyncData({ params }) { // 会走ssr
    const teachers = await getTeachers();
    return {teachers}
  }
}
</script>

<style>
.container {
  margin: 0 auto;
  padding: 10px;
}
</style>

编译后,可以看到data和created、asyncData里的代码都会被ssr。而其他钩子里的数据都会被csr。
这是因为:

在任何 Vue 组件的生命周期内, 只有 beforeCreate 和 created 这两个方法会在 客户端和服务端被调用。其他生命周期函数仅在客户端被调用。
https://www.nuxtjs.cn/guide/plugins

Nuxt.js 会将 asyncData 返回的数据融合组件 data 方法返回的数据一并返回给当前组件。
https://www.nuxtjs.cn/guide/async-data

<!DOCTYPE html>
<html data-n-head-ssr="" lang="en" data-n-head="%7B%22lang%22:%7B%22ssr%22:%22en%22%7D%7D">
 <head> 
  <title>ssr-vue</title> 
  <meta data-n-head="ssr" charset="utf-8" /> 
  <meta data-n-head="ssr" name="viewport" content="width=device-width, initial-scale=1" /> 
  <meta data-n-head="ssr" data-hid="description" name="description" content="" /> 
  <link data-n-head="ssr" rel="icon" type="image/x-icon" href="/favicon.ico" /> 
  <link rel="preload" href="/_nuxt/runtime.js" as="script" />
  <link rel="preload" href="/_nuxt/commons/app.js" as="script" />
  <link rel="preload" href="/_nuxt/vendors/app.js" as="script" />
  <link rel="preload" href="/_nuxt/app.js" as="script" />
  <link rel="preload" href="/_nuxt/pages/index.js" as="script" />
  <link rel="preload" href="/_nuxt/pages/index.4ee7ce6db4f1f6ace22f.hot-update.js" as="script" />
  <style data-vue-ssr-id="3191d5ad:0">
	.nuxt-progress {
    position: fixed;
    top: 0px;
    ...
	</style> 
 </head> 
 <body> 
  <div data-server-rendered="true" id="__nuxt">
   <!---->
   <!---->
   <div id="__layout">
    <div>
     <div class="container">
      <fieldset>
       <legend>ssr-asyncData数据</legend> 
       <div>
        姓名: 张老师
       </div>
       <div>
        姓名: 丁老师
       </div>
      </fieldset> 
      <fieldset>
       <legend>ssr-data数据</legend> 
       <div>
        姓名: 张老师1
       </div>
       <div>
        姓名: 丁老师1
       </div>
      </fieldset> 
      <fieldset>
       <legend>ssr-created</legend> 
       <div>
        姓名: 张老师2
       </div>
       <div>
        姓名: 丁老师2
       </div>
      </fieldset> 
      <fieldset>
       <legend>csr-mounted数据</legend> 
      </fieldset>
     </div>
    </div>
   </div>
  </div>
  <script>window.__NUXT__=(function(a,b){return {layout:"default",data:[{teachers:[{id:202101,name:"张老师"},{id:202102,name:"丁老师"}]}],fetch:{},error:a,serverRendered:true,routePath:b,config:{app:{basePath:b,assetsPath:"\u002F_nuxt\u002F",cdnURL:a}},logs:[]}}(null,"\u002F"));</script>
  <script src="/_nuxt/runtime.js" defer=""></script>
  <script src="/_nuxt/pages/index.js" defer=""></script>
  <script src="/_nuxt/pages/index.4ee7ce6db4f1f6ace22f.hot-update.js" defer=""></script>
  <script src="/_nuxt/commons/app.js" defer=""></script>
  <script src="/_nuxt/vendors/app.js" defer=""></script>
  <script src="/_nuxt/app.js" defer=""></script>   
 </body>
</html>

----再举例子验证-----

<template>
  <div class="container">
    <span @click="goList">我是详情,点我跳转列表</span>
  </div>
</template>

<script>
export default {
  methods: {
    goList() {
      this.$router.push("/");
    },
  },
  mounted(){ // 客户端执行
    console.log('mounted');
  },
  created(){ // 客户端和服务端执行
      console.log('created');
  },
  asyncData(){ // 服务端执行
      console.log('asyncData');
  }
};
</script>

服务端会打印

浏览器也会打印

nuxtjs路由-入门

和传统的建立路由配置不同,nuxtjs更像小程序和原生html跳转。免路由配置
会依据 pages 目录结构自动生成 vue-router 模块的路由配置。

pages/
--| index.vue
--| detal.vue

index.vue

<template>
  <div class="container">
    <nuxt-link to="/detail">我是列表,点我跳转详情</nuxt-link>
  </div>
</template>

<script>
export default {}
</script>

<style>
.container {
  margin: 0 auto;
  padding: 10px;
}
</style>

detail.vue

<template>
  <div class="container">
    <span @click="goList">我是详情,点我跳转列表</span>
  </div>
</template>

<script>
export default {
  methods: {
    goList() {
      this.$router.push("/");
    },
  },
};
</script>

<style>
.container {
  margin: 0 auto;
  padding: 10px;
}
</style>

nuxtjs视图

Nuxt.js 应用中为指定的路由配置数据和视图,包括应用模板、页面、布局和 HTML 头部等内容。
其他可以参考文档,这里主要演示一个对于seo比较重要的头部信息description、keywords

<template>
  <div class="container">
    <nuxt-link to="/detail">我是列表,点我跳转详情</nuxt-link>
  </div>
</template>

<script>
export default {
  head: {
    title: "文章列表",
    meta: [
      { charset: "utf-8" },
      { name: "viewport", content: "width=device-width, initial-scale=1" },
      {
        name: "description",
        content: "这是一个神奇的网站",
      },
      {
        name: "keywords",
        content: "神奇,网站",
      },
    ],
    link: [
      {
        rel: "stylesheet",
        href: "https://fonts.googleapis.com/css?family=Roboto",
      },
    ],
  },
};
</script>

<style>
.container {
  margin: 0 auto;
  padding: 10px;
}
</style>

编译后代码,可以看到vue-ssr处理后html,已经通过header属性为html加上了标签

<!DOCTYPE html>
<html data-n-head-ssr="" lang="en" data-n-head="%7B%22lang%22:%7B%22ssr%22:%22en%22%7D%7D">
 <head> 
  <title>文章列表</title> 
  <meta data-n-head="ssr" charset="utf-8" /> 
  <meta data-n-head="ssr" name="viewport" content="width=device-width, initial-scale=1" /> 
  <meta data-n-head="ssr" data-hid="description" name="description" content="" /> 
  <meta data-n-head="ssr" charset="utf-8" /> 
  <meta data-n-head="ssr" name="viewport" content="width=device-width, initial-scale=1" /> 
  <meta data-n-head="ssr" name="description" content="这是一个神奇的网站" /> 
  <meta data-n-head="ssr" name="keywords" content="神奇,网站" /> 
  <link data-n-head="ssr" rel="icon" type="image/x-icon" href="/favicon.ico" /> 
  <link data-n-head="ssr" rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto" /> 
  <link rel="preload" href="/_nuxt/runtime.js" as="script" />
  <link rel="preload" href="/_nuxt/commons/app.js" as="script" />
  <link rel="preload" href="/_nuxt/vendors/app.js" as="script" />
  <link rel="preload" href="/_nuxt/app.js" as="script" />
  <link rel="preload" href="/_nuxt/pages/index.js" as="script" />
  <style data-vue-ssr-id="3191d5ad:0"></style>
  ...
 </head>
 <body>
  ...
</body>
</html>

SSG模式

ssg既对seo友好,也对服务器友好。
由于是开发的时候就是已经生成好了的静态资源,所以不需要服务器实时做处理。
同时也不会在发起请求,因为在编译打包的时候,就会访问后端数据,填充到静态页面中
但是也正因为如此,ssg页面常常会存在数据更新不及时,每次更新数据,都需要再次编译方可更新页面的问题,
所以ssg常用在不常更新数据的页面上,比如about、concat等等
举个例子

<template>
   <div class="container">
    <fieldset>
      <legend>ssr-asyncData数据</legend>
      <div v-for="item in teachers" :key="item.id">姓名: {{item.name}}</div>
    </fieldset>

     <fieldset>
      <legend>ssr-data数据</legend>
      <div v-for="item in teachers1" :key="item.id">姓名: {{item.name}}</div>
    </fieldset>

    <fieldset>
      <legend>ssr-created</legend>
      <div v-for="item in teachers2" :key="item.id">姓名: {{item.name}}</div>
    </fieldset>

    <fieldset>
      <legend>csr-mounted数据</legend>
      <div v-for="item in teachers3" :key="item.id">姓名: {{item.name}}</div>
    </fieldset>
  </div>
</template>

<script>
const getTeachers = ()=> {
  return new Promise((resolve,reject)=>{
    setTimeout(()=>{
      const teachers = [
        {id:202101,name:'张老师'},
        {id:202102,name:'丁老师'}
      ];
      resolve(teachers);
    },2000)
  })
}
export default {
  head: {
    title: "文章列表",
    meta: [
      { charset: "utf-8" },
      { name: "viewport", content: "width=device-width, initial-scale=1" },
      {
        name: "description",
        content: "这是一个神奇的网站",
      },
      {
        name: "keywords",
        content: "神奇,网站",
      },
    ],
    link: [
      {
        rel: "stylesheet",
        href: "https://fonts.googleapis.com/css?family=Roboto",
      },
    ],
  },
  data(){ // 会走ssg
    return {
      teachers1: [
        {id:202101,name:'张老师1'},
        { id:202102,name:'丁老师1'}
      ],
      teachers2: [],
      teachers3: []
    }
  },
   mounted(){ // 会走csr
    this.teachers3 = [
      {id:202101,name:'张老师3'},
      {id:202102,name:'丁老师3'}
    ]
  },

  created(){ // 会走ssg
    this.teachers2 = [
      {id:202101,name:'张老师2'},
      {id:202102,name:'丁老师2'}
    ]
  },
  async asyncData({ params }) { // 会走ssg
    const teachers = await getTeachers();
    return {teachers}
  }
};
</script>

<style>
.container {
  margin: 0 auto;
  padding: 10px;
}
</style>

然后我们运行ssg的命令,生产静态网页
npm run generate
进入dist,启动项目,我用的是http-server

<!DOCTYPE html>
<html data-n-head-ssr="" lang="en" data-n-head="%7B%22lang%22:%7B%22ssr%22:%22en%22%7D%7D">
 <head> 
  <title>文章列表</title>
  <meta data-n-head="ssr" charset="utf-8" />
  <meta data-n-head="ssr" name="viewport" content="width=device-width,initial-scale=1" />
  <meta data-n-head="ssr" data-hid="description" name="description" content="" />
  <meta data-n-head="ssr" charset="utf-8" />
  <meta data-n-head="ssr" name="viewport" content="width=device-width,initial-scale=1" />
  <meta data-n-head="ssr" name="description" content="这是一个神奇的网站" />
  <meta data-n-head="ssr" name="keywords" content="神奇,网站" />
  <link data-n-head="ssr" rel="icon" type="image/x-icon" href="/favicon.ico" />
  <link data-n-head="ssr" rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto" />
  <link rel="preload" href="/_nuxt/e4e7482.js" as="script" />
  <link rel="preload" href="/_nuxt/2a8f614.js" as="script" />
  <link rel="preload" href="/_nuxt/699e2f6.js" as="script" />
  <link rel="preload" href="/_nuxt/34083f3.js" as="script" />
  <style data-vue-ssr-id="7e56e4e3:0 56b15182:0 1b7833da:0">.nuxt-progress{position:fixed;top:0;left:0;right:0;height:2px;width:0;opacity:1;transition:width .1s,opacity .4s;background-color:#000;z-index:999999}.nuxt-progress.nuxt-progress-notransition{transition:none}.nuxt-progress-failed{background-color:red}html{font-family:"Source Sans Pro",-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;font-size:16px;word-spacing:1px;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%;-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;box-sizing:border-box}*,:after,:before{box-sizing:border-box;margin:0}.button--green{display:inline-block;border-radius:4px;border:1px solid #3b8070;color:#3b8070;text-decoration:none;padding:10px 30px}.button--green:hover{color:#fff;background-color:#3b8070}.button--grey{display:inline-block;border-radius:4px;border:1px solid #35495e;color:#35495e;text-decoration:none;padding:10px 30px;margin-left:15px}.button--grey:hover{color:#fff;background-color:#35495e}.container{margin:0 auto;padding:10px}</style> 
 </head> 
 <body> 
  <div data-server-rendered="true" id="__nuxt">
   <!---->
   <div id="__layout">
    <div>
     <div class="container">
      <fieldset>
       <legend>ssr-asyncData数据</legend> 
       <div>
        姓名: 张老师
       </div>
       <div>
        姓名: 丁老师
       </div>
      </fieldset> 
      <fieldset>
       <legend>ssr-data数据</legend> 
       <div>
        姓名: 张老师1
       </div>
       <div>
        姓名: 丁老师1
       </div>
      </fieldset> 
      <fieldset>
       <legend>ssr-created</legend> 
       <div>
        姓名: 张老师2
       </div>
       <div>
        姓名: 丁老师2
       </div>
      </fieldset> 
      <fieldset>
       <legend>csr-mounted数据</legend> 
      </fieldset>
     </div>
    </div>
   </div>
  </div>
  <script>window.__NUXT__=function(e){return{layout:"default",data:[{teachers:[{id:202101,name:"张老师"},{id:202102,name:"丁老师"}]}],fetch:{},error:e,serverRendered:!0,routePath:"/",config:{app:{basePath:"/",assetsPath:"/_nuxt/",cdnURL:e}}}}(null)</script>
  <script src="/_nuxt/e4e7482.js" defer=""></script>
  <script src="/_nuxt/34083f3.js" defer=""></script>
  <script src="/_nuxt/2a8f614.js" defer=""></script>
  <script src="/_nuxt/699e2f6.js" defer=""></script>   
 </body>
</html>

可以看到 ssg和ssr一样,也只会在data、created、asyncDate执行,唯一的和ssr的区别是,服务器不在实时参与渲染。即nuxtJs的执行时机是在这些属性和方法中

关于部署

ssg和csr是一样的,比较简单。编译后 直接拖到服务器容器上就行
ssr则较为麻烦,ssr以来后端node进程(npm start) 最好用pm2管理 不会独占进程

标签:vue,name,张老师,ssr,seo,data,id
From: https://www.cnblogs.com/dingshaohua/p/17045696.html

相关文章

  • Vue 之 element 输入框验证及常用正则
    1.控制输入位数限制输入为10位,这种方式可以使输入框中输入10位后不能输入后续内容因为number输入框自动将最后一位小数点忽略不计,因此“.”,"2.","3.3."这三种情况均为......
  • Vue 中 Promise 的then方法异步使用及async/await 异步使用总结
    转载请注明出处:1.Promise的then方法使用then方法是 Promise中处理的是异步调用,异步调用是非阻塞式的,在调用的时候并不知道它什么时候结束,也就不会等到他......
  • Vue.js 双向数据绑定原理
    Vue双向数据绑定原理涉及到Vue中的响应式系统和模板编译。在Vue中,响应式系统是通过Object.defineProperty或者Proxy来实现的。当Vue创建一个Vue实例时,它会遍......
  • 【Java】Vue-Element-Admin 嵌入Druid监控面板
     我看到若依做了Druid面板的嵌入,我自己的项目干脆也做一个 一、后台服务SpringBoot:Druid配置项:spring:datasource:url:jdbc:mysql://127.0.0.1:3308/tt?s......
  • vue.js 虚拟DOM
    Vue.js使用虚拟DOM来优化更新流程。虚拟DOM是一个JavaScript对象,它可以描述一个真实的DOM结构,并在数据发生变化时重新渲染。当Vue组件的数据发生变化时,Vue会......
  • day07-Vue04
    Vue0412.Vue2脚手架模块化开发目前开发模式的问题:开发效率低不够规范维护和升级,可读性比较差12.1基本介绍官网地址什么是VueCli脚手架12.2环境配置,搭建项目......
  • Vue.js 响应式原理
    Vue.js是一个渐进式的JavaScript框架,它使用了响应式系统来维护应用程序的状态。响应式系统是Vue.js的核心部分,它使得应用程序能够自动地更新视图,当数据发生变化时。在Vue.......
  • 10个提高开发效率的Vue3常用插件(快来收藏)
    本篇文章给大家总结分享几个好用的 Vue 插件,可以帮助开发者提高开发效率、解决移动端各种滚动场景需求,希望对大家有所帮助!1、vue-multiselect-nextVue.js 的通用选择/......
  • 【转】前后端分离项目(vue+springboot)集成pageoffice实现在线编辑office文件
    前后端分离项目下使用PageOffice原理图集成步骤前端vue项目在您Vue项目的根目录下index.html中引用后端项目根目录下pageoffice.js文件。例如:<scripttype="text/......
  • Win10+Vue环境配置
    发现前年写的代码是答辩,决定试试Vue1.下载npmnpm 是 Node.js 的包管理工具,用来安装各种Node.js的扩展。下载地址安装的时候什么选项都不用勾选。2.修改扩展......