21 |
22 |
59 |
60 |
61 |
--------------------------------------------------------------------------------
/cnd/project-axios/json.aspx:
--------------------------------------------------------------------------------
1 | {
2 | "company":{
3 | "findMeta":{
4 | "quickFind":[1010,1013,1005,1008],
5 | "allFind":[1000,1001,1002,1003,1009,1004,1005,1010,1006,1007,1012,1011,1008],
6 | "colCount":4,
7 | "customer":{
8 | "100": {
9 | "name":"方案二",
10 | "keys":[1002,1003,1006]
11 | },
12 | "101":{
13 | "name":"方案三",
14 | "keys":[1007,1004,1010]
15 | }
16 | }
17 | },
18 | "findItem":{
19 | "1010":{
20 | "controlId": "1010",
21 | "colName": "private,city,area,c1,c2,c3,c4,c5",
22 | "controlType": 200,
23 | "placeholder": "省市区",
24 | "title": "省市区",
25 | "level": 2,
26 | "optionKind": 2,
27 | "optionList": [
28 | { "value": 1, "label": "浙江", "isLeaf": false },
29 | { "value": 2, "label": "江苏", "isLeaf": false },
30 | { "value": 3, "label": "辽宁", "isLeaf": false }
31 | ],
32 | "optionList2": [
33 | { "parent": 1, "value": 11, "label": "杭州" },
34 | { "parent": 1, "value": 12, "label": "宁波" },
35 | { "parent": 1, "value": 13, "label": "温州" },
36 | { "parent": 2, "value": 21, "label": "南京" },
37 | { "parent": 2, "value": 22, "label": "无锡" },
38 | { "parent": 3, "value": 31, "label": "沈阳" },
39 | { "parent": 3, "value": 32, "label": "大连" }
40 | ],
41 | "tdCount":3
42 | },
43 | "1012":{
44 | "controlId": "1012",
45 | "colName": "education",
46 | "controlType": 183,
47 | "placeholder": "学历",
48 | "title": "学历",
49 | "optionList": [
50 | { "value": 1, "label": "高中" },
51 | { "value": 2, "label": "大专" },
52 | { "value": 3, "label": "本科" },
53 | { "value": 4, "label": "硕士" },
54 | { "value": 5, "label": "博士" }
55 | ],
56 | "tdCount":3
57 | },
58 | "1000":{
59 | "controlId": 1000,
60 | "colName": "companyName",
61 | "controlType": 101,
62 | "class": "",
63 | "placeholder": "公司名称",
64 | "title": "公司名称",
65 | "size": 10,
66 | "maxlength": 100,
67 | "optionList": [],
68 | "findKind":"402",
69 | "findKindList": [401,403,402,404,405,406],
70 | "tdCount":1
71 | },
72 | "1001":{
73 | "controlId": 1001,
74 | "colName": "companyCode",
75 | "controlType": 131,
76 | "class": "",
77 | "placeholder": "公司邮编",
78 | "title": "公司邮编",
79 | "min": 100000,
80 | "max": 999999,
81 | "step": 1,
82 | "maxlength": 6,
83 | "optionList": [] ,
84 | "findKind":"401",
85 | "findKindList": [411,417,412,431,413,414,415,416],
86 | "tdCount":1
87 | },
88 | "1002":{
89 | "controlId": 1002,
90 | "colName": "legalPerson",
91 | "controlType": 101,
92 | "class": "",
93 | "placeholder": "法人姓名",
94 | "title": "法人",
95 | "autocomplete": "on",
96 | "size": 10,
97 | "maxlength": 50,
98 | "optionList": [] ,
99 | "findKind":"403",
100 | "findKindList": [401,403,402,404,405,406],
101 | "tdCount":1
102 | },
103 | "1003":{
104 | "controlId": 1003,
105 | "colName": "liaisonMan",
106 | "controlType": 101,
107 | "class": "",
108 | "placeholder": "联系人姓名",
109 | "title": "联系人",
110 | "size": 10,
111 | "maxlength": 50,
112 | "optionList": [],
113 | "findKind":"404",
114 | "findKindList": [401,403,402,404,405,406],
115 | "tdCount":1
116 | },
117 | "1004": {
118 | "controlId": "1004",
119 | "colName": "address",
120 | "controlType": 101,
121 | "class": "",
122 | "placeholder": "公司地址",
123 | "title": "公司地址",
124 | "size": 10,
125 | "maxlength": 50,
126 | "optionKey": "",
127 | "optionList": [],
128 | "findKind":"405",
129 | "findKindList": [401,403,402,404,405,406],
130 | "tdCount":1
131 | },
132 | "1005": {
133 | "controlId": "1005",
134 | "colName": "telphone",
135 | "controlType": 103,
136 | "placeholder": "公司电话",
137 | "title": "公司电话",
138 | "size": 10,
139 | "maxlength": 50,
140 | "optionKey": "",
141 | "optionList": [],
142 | "findKind":"401,402",
143 | "findKindList": [401,403,402,404,405,406],
144 | "tdCount":1
145 | },
146 | "1006": {
147 | "controlId": "1006",
148 | "colName": "URL",
149 | "controlType": 105,
150 | "class": "",
151 | "placeholder": "公司网址",
152 | "title": "公司网址",
153 | "autocomplete": "on",
154 | "size": 10,
155 | "maxlength": 50,
156 | "optionKey": "",
157 | "optionList": [],
158 | "findKind":"401,402",
159 | "findKindList": [401,403,402,404,405,406],
160 | "tdCount":1
161 | },
162 | "1007": {
163 | "controlId": "1007",
164 | "colName": "Email",
165 | "controlType": 104,
166 | "class": "",
167 | "placeholder": "公司邮件",
168 | "title": "公司邮件",
169 | "size": 10,
170 | "maxlength": 50,
171 | "optionKey": "",
172 | "optionList": [],
173 | "findKind":"402",
174 | "findKindList": [401,403,402,404,405,406],
175 | "tdCount":1
176 | },
177 | "1008": {
178 | "controlId": 1008,
179 | "colName": "type",
180 | "title": "公司类型",
181 | "controlType": 190,
182 | "placeholder": "公司类型",
183 | "class": "",
184 | "optionList": [
185 | { "value": 1, "title": "有限责任公司" },
186 | { "value": 2, "title": "股份有限责任公司" },
187 | { "value": 3, "title": "个人独资企业" },
188 | { "value": 4, "title": "合伙企业" },
189 | { "value": 5, "title": "个体工商户" }
190 | ],
191 | "findKind":"401",
192 | "findKindList": ["401","402"],
193 | "tdCount":1
194 | },
195 | "1009": {
196 | "controlId": 1009,
197 | "colName": "createDate",
198 | "controlType": 141,
199 | "class": "",
200 | "title": "成立日期",
201 | "placeholder": "成立日期",
202 | "min": "1950-01-01",
203 | "max": "2999-12-31",
204 | "step": 1,
205 | "findKind":"423",
206 | "findKindList": [421,427,422,423,424,425,426],
207 | "tdCount":3
208 | },
209 | "1013": {
210 | "controlId": 1013,
211 | "colName": "createTime",
212 | "controlType": 149,
213 | "class": "",
214 | "title": "成立时间",
215 | "placeholder": "成立时间",
216 | "min": "1950-01-01",
217 | "max": "2999-12-31",
218 | "step": 1,
219 | "findKind":"423",
220 | "findKindList": [421,427,422,423,424,425,426],
221 | "tdCount":3
222 | },
223 | "1011":{
224 | "controlId": 1011,
225 | "colName": "hobby",
226 | "controlType": 182,
227 | "isClear": true,
228 | "disabled": false,
229 | "required": true,
230 | "readonly": false,
231 | "pattern": "",
232 | "class": "",
233 | "title": "爱好",
234 | "optionList": [
235 | { "value": 1, "label": "篮球" },
236 | { "value": 2, "label": "足球" },
237 | { "value": 3, "label": "排球" }
238 | ],
239 | "tdCount":3
240 | }
241 | }
242 | },
243 | "person":{
244 | "findMeta":{
245 | "quickFind":[2000,2001,2002,2003],
246 | "allFind":[2000,2001,2002,2003,2004,2005],
247 | "colCount":4,
248 | "customer":{
249 | "200": {
250 | "name":"方案一",
251 | "keys":[2000,2004,2005]
252 | },
253 | "201":{
254 | "name":"方案二",
255 | "keys":[2002,2004,2005]
256 | }
257 | }
258 | },
259 | "findItem":{
260 | "2000":{
261 | "controlId": 100,
262 | "colName": "personId",
263 | "controlType": 101,
264 | "class": "",
265 | "placeholder": "工号",
266 | "title": "工号",
267 | "size": 10,
268 | "maxlength": 10,
269 | "optionList": [],
270 | "tdCount":1
271 | },
272 | "2001":{
273 | "controlId": "2001",
274 | "colName": "personName",
275 | "controlType": 101,
276 | "isClear": true,
277 | "disabled": false,
278 | "required": true,
279 | "readonly": false,
280 | "pattern": "",
281 | "class": "",
282 | "placeholder": "员工姓名",
283 | "title": "姓名",
284 | "autocomplete": "on",
285 | "size": 10,
286 | "maxlength": "50",
287 | "tdCount":1
288 | },
289 | "2002": {
290 | "controlId": 2002,
291 | "colName": "Gender",
292 | "controlType": 183,
293 | "isClear": true,
294 | "disabled": false,
295 | "required": true,
296 | "readonly": false,
297 | "pattern": "",
298 | "class": "",
299 | "title": "性别",
300 | "optionList": [
301 | { "value": "男", "title": "男" },
302 | { "value": "女", "title": "女" }
303 | ],
304 | "tdCount":3
305 | },
306 | "2003":{
307 | "controlId": "2012",
308 | "colName": "nation",
309 | "controlType": 106,
310 | "isClear": true,
311 | "disabled": false,
312 | "required": true,
313 | "readonly": false,
314 | "pattern": "",
315 | "class": "",
316 | "placeholder": "员工姓名",
317 | "title": "民族",
318 | "optionKey": "minzu",
319 | "optionList": [
320 | { "value": 1, "title": "汉" },
321 | { "value": 2, "title": "蒙古" },
322 | { "value": 3, "title": "满族" },
323 | { "value": 4, "title": "回族" },
324 | { "value": 5, "title": "朝鲜" }
325 | ]
326 | },
327 | "2004":{
328 | "controlId": "2012",
329 | "colName": "education",
330 | "controlType": 190,
331 | "isClear": true,
332 | "disabled": false,
333 | "required": true,
334 | "readonly": false,
335 | "pattern": "",
336 | "class": "",
337 | "placeholder": "学历",
338 | "title": "学历",
339 | "optionList": [
340 | { "value": 1, "title": "高中" },
341 | { "value": 2, "title": "大专" },
342 | { "value": 3, "title": "本科" },
343 | { "value": 4, "title": "硕士" },
344 | { "value": 5, "title": "博士" }
345 | ],
346 | "tdCount":1
347 | },
348 | "2005":{
349 | "controlId": 100,
350 | "colName": "hobby",
351 | "controlType": 182,
352 | "isClear": true,
353 | "disabled": false,
354 | "required": true,
355 | "readonly": false,
356 | "pattern": "",
357 | "class": "",
358 | "title": "爱好",
359 | "optionList": [
360 | { "value": 1, "title": "篮球" },
361 | { "value": 2, "title": "足球" },
362 | { "value": 3, "title": "排球" }
363 | ],
364 | "tdCount":3
365 | }
366 | }
367 | }
368 | }
--------------------------------------------------------------------------------
/cnd/project-axios/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/naturefwvue/nf-vue-cnd/7670d199337cc527a04865181c5aacd8168fb901/cnd/project-axios/public/favicon.ico
--------------------------------------------------------------------------------
/cnd/project-axios/src/app.js:
--------------------------------------------------------------------------------
1 |
2 | // vue3的对象
3 | const App = {
4 | setup() { // 传说中的setup
5 |
6 | const store = Vuex.useStore()
7 | // 状态的控制事件
8 | const setCount = () =>{
9 | store.commit('setCount')
10 | }
11 |
12 | return { // 返回给模板,否则模板访问不到。
13 | setCount
14 | }
15 | }
16 | }
17 |
18 | export default App
19 |
--------------------------------------------------------------------------------
/cnd/project-axios/src/component/HelloWorld.vue:
--------------------------------------------------------------------------------
1 |
10 |
11 |
19 |
--------------------------------------------------------------------------------
/cnd/project-axios/src/component/test.js:
--------------------------------------------------------------------------------
1 | const test = {
2 | template: `
3 | 这是 组件测试
5 | `,
6 | model: {
7 | prop: ['str']
8 | },
9 | props: {
10 | str: String
11 | },
12 | setup(props) {
13 | // 在setup里面获取参数值
14 | const str1 = Vue.ref(props.str)
15 |
16 | return {
17 | str1
18 | }
19 | }
20 | }
21 |
22 | export default test
--------------------------------------------------------------------------------
/cnd/project-axios/src/main.js:
--------------------------------------------------------------------------------
1 | import store from './store/index.js?v=6'
2 | import router from './router/index.js?v=8'
3 | import App from './app.js?v=6'
4 |
5 | // 创建vue3的实例
6 | const app = Vue.createApp(App)
7 | .use(store) // 挂载vuex
8 | .use(router) // 挂载路由
9 | .use(ElementPlus) // 加载ElementPlus
10 | .mount('#app') // 挂载Vue的app实例
11 |
12 |
--------------------------------------------------------------------------------
/cnd/project-axios/src/router/index.js:
--------------------------------------------------------------------------------
1 | // import Home from '../views/home.js?v=2'
2 |
3 | const routes = [
4 | {
5 | path: '/',
6 | name: 'Home',
7 | component: () => import('../views/home.js?v=8')
8 | },
9 | {
10 | path: '/state',
11 | name: 'state',
12 | component: () => import('../views/state.js?v=8')
13 | },
14 | {
15 | path: '/component',
16 | name: 'component',
17 | component: () => import('../views/component.js?v=8')
18 | }
19 | ]
20 |
21 | const router = VueRouter.createRouter({
22 | history: VueRouter.createWebHistory(),
23 | routes
24 | })
25 |
26 | export default router
27 |
--------------------------------------------------------------------------------
/cnd/project-axios/src/store/index.js:
--------------------------------------------------------------------------------
1 |
2 | export default Vuex.createStore({
3 | state: {
4 | count: 0,
5 | myObject: {
6 | time: '现在的时间'
7 | }
8 | },
9 | getters: {
10 | getCount: (state) => {
11 | return state.count
12 | },
13 | getMyObject: (state) => {
14 | return Vue.readonly(state.myObject)
15 | },
16 | getTime: (state) => {
17 | return state.myObject.time
18 | }
19 | },
20 | mutations: {
21 | setCount(state) {
22 | state.count++
23 | },
24 | setTime(state) {
25 | state.myObject.time = '现在时间:' + new Date()
26 | }
27 | },
28 | actions: {
29 | },
30 | modules: {
31 | }
32 | })
33 |
--------------------------------------------------------------------------------
/cnd/project-axios/src/views/component.js:
--------------------------------------------------------------------------------
1 | // 引入组件
2 | import test from '../component/test.js?v=7'
3 |
4 | const demo = {
5 | template: `
6 |
8 | `,
9 | components: {
10 | test
11 | },
12 | setup() {
13 |
14 | return {
15 | }
16 | }
17 | }
18 |
19 | export default demo
--------------------------------------------------------------------------------
/cnd/project-axios/src/views/home.js:
--------------------------------------------------------------------------------
1 |
2 | const testManage = () => {
3 | const hello = Vue.ref('你好,世界')
4 | const clickMe = () => {
5 | hello.value = '好的,收到' + new Date().valueOf()
6 | }
7 |
8 | return {
9 | hello,
10 | clickMe
11 | }
12 | }
13 |
14 | // vue3的对象
15 | const home = {
16 | template: `
17 |
29 | `,
30 | setup() { // 传说中的setup
31 | // 使用外面的定义,分解setup内部的代码
32 | const { hello, clickMe } = testManage()
33 |
34 | const value = Vue.reactive({
35 | name: 'jyk'
36 | })
37 |
38 |
39 | return {
40 | value,
41 | hello,
42 | clickMe
43 | }
44 | }
45 | }
46 |
47 | export default home
--------------------------------------------------------------------------------
/cnd/project-axios/src/views/state.js:
--------------------------------------------------------------------------------
1 | // vue3的对象
2 | const demo = {
3 | template: `
4 |
6 | `,
7 | setup() { // 传说中的setup
8 | const store = Vuex.useStore()
9 | // 在代码里面获取状态
10 | const count = Vue.computed(() => store.getters.getCount)
11 |
12 | return {
13 | count
14 | }
15 | }
16 | }
17 |
18 | export default demo
--------------------------------------------------------------------------------
/cnd/project-axios/vuex.vue:
--------------------------------------------------------------------------------
1 |
15 |
16 |
82 |
--------------------------------------------------------------------------------
/cnd/project-axios/web.config:
--------------------------------------------------------------------------------
1 |
2 |
20 |
--------------------------------------------------------------------------------
/cnd/project-compositionapi/README.md:
--------------------------------------------------------------------------------
1 |
2 | # 演示一下 vue3 的响应性和composition API
3 |
4 | * vue3 的 reactive
5 | * vue3 的 ref
6 | * vue3 的 监听和计算属性
7 | * vue3 的 composition API
8 |
9 | 在线演示:
10 | https://naturefwvue.github.io/nf-vue-cnd/cnd/project-compositionapi
11 |
--------------------------------------------------------------------------------
/cnd/project-compositionapi/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
12 |
13 |
14 |
15 |
31 |
32 |
58 |
77 |
78 |
79 |
93 |
94 |
95 | 首页
96 | reactive
97 | ref
98 | setup
99 | 监听和计算属性
100 | 生命周期
101 | 代码复用
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
127 |
128 |
129 |
130 |
--------------------------------------------------------------------------------
/cnd/project-compositionapi/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/naturefwvue/nf-vue-cnd/7670d199337cc527a04865181c5aacd8168fb901/cnd/project-compositionapi/public/favicon.ico
--------------------------------------------------------------------------------
/cnd/project-compositionapi/src/app.js:
--------------------------------------------------------------------------------
1 |
2 | // import { Set_Count, Set_Count_sy } from './store/mutation-types.js'
3 |
4 | export default {
5 | name: 'app',
6 | setup() {
7 | const store = Vuex.useStore()
8 |
9 | // 状态的控制事件
10 | const setCount = () =>{
11 | store.commit('setCount')
12 | store.commit('setTime')
13 | store.commit('setArray')
14 | // store._mutations.setCount[0] // 这是什么?
15 | }
16 |
17 | return {
18 | // 设置state
19 | setCount
20 | }
21 | }
22 | }
--------------------------------------------------------------------------------
/cnd/project-compositionapi/src/components/test.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | 这是 组件测试
4 | 父组件传递参数:{{str}}
5 | setup 获取参数:{{str1}}
6 |
--------------------------------------------------------------------------------
/cnd/project-compositionapi/src/components/test.js:
--------------------------------------------------------------------------------
1 | export default {
2 | name: 'component-test',
3 | template: '',
4 | props: {
5 | str: String,
6 | obj: Object
7 | },
8 | setup(props) {
9 | // 在setup里面获取参数值
10 | let str1 = Vue.ref(props.str)
11 | str1.value += '--内部改一下。'
12 | console.log('组件属性——props:', props)
13 | console.log('组件属性——obj:', props.obj)
14 | console.log('组件属性——props:', Vue.isReadonly(props))
15 | console.log('组件属性——obj:', Vue.isReadonly(props.obj))
16 |
17 | return {
18 | str1
19 | }
20 | }
21 | }
--------------------------------------------------------------------------------
/cnd/project-compositionapi/src/main.js:
--------------------------------------------------------------------------------
1 | /*
2 | import store from './store/index.js?v=28'
3 | import router from './router/index.js?v=28'
4 | import App from './app.js?v=28'
5 |
6 |
7 | // 创建vue3的实例
8 | const app = Vue.createApp(App)
9 | .use(store) // 挂载vuex
10 | .use(router) // 挂载路由
11 | .use(ElementPlus) // 加载ElementPlus
12 | .mount('#app') // 挂载Vue的app实例
13 |
14 | */
15 |
16 | const ver = window.__ver || ''
17 |
18 | Promise.all([
19 | import('./store/index.js' + ver),
20 | import('./router/index.js' + ver),
21 | import('./app.js' + ver),
22 | ]).then((res) => {
23 | // 创建vue3的实例
24 | const app = Vue.createApp(res[2].default)
25 | .use(res[0].default) // 挂载vuex
26 | .use(res[1].default) // 挂载路由
27 | .use(ElementPlus) // 加载ElementPlus
28 | .mount('#app') // 挂载Vue的app实例
29 | })
30 |
--------------------------------------------------------------------------------
/cnd/project-compositionapi/src/router/index.js:
--------------------------------------------------------------------------------
1 |
2 | const routes = [
3 | {
4 | path: '/',
5 | name: 'Home',
6 | component: () => myImport('views/home')
7 | },
8 | {
9 | path: '/reactive', /** reactive 的导航页面 */
10 | name: 'reactive',
11 | component: () => myImport('views/reactive/index'),
12 | children: [
13 | { // es6的Proxy
14 | path: 'proxy',
15 | name: 'ret-proxy',
16 | component: () => myImport('views/reactive/proxy')
17 | },
18 | { // 用Proxy套个娃
19 | path: 'proxy',
20 | name: 'ret-proxy-reactive',
21 | component: () => myImport('views/reactive/proxy-reactive')
22 | },
23 | { // reactive 响应式
24 | path: 'reactive',
25 | name: 'ret-reactive',
26 | component: () => myImport('views/reactive/reactive')
27 | },
28 | { // shallowReactive 响应式
29 | path: 'shallowReactive',
30 | name: 'ret-reactive-shallow',
31 | component: () => myImport('views/reactive/reactive-shallow')
32 | },
33 | { // readonly 只读
34 | path: 'readonly',
35 | name: 'ret-readonly',
36 | component: () => myImport('views/reactive/readonly')
37 | },
38 | { // shallowReadonly 只读
39 | path: 'shallowReadonly',
40 | name: 'ret-readonly-shallow',
41 | component: () => myImport('views/reactive/readonly-shallow')
42 | },
43 | { // toRaw
44 | path: 'toRaw',
45 | name: 'ret-toRaw',
46 | component: () => myImport('views/reactive/toraw')
47 | },
48 | { // toRaw
49 | path: 'MarkRaw',
50 | name: 'ret-MarkRaw',
51 | component: () => myImport('views/reactive/markraw')
52 | },
53 | {
54 | path: 'let',
55 | name: 'ret-let',
56 | component: () => myImport('views/reactive/let')
57 | },
58 | { // 验证对象类型
59 | path: 'check',
60 | name: 'ret-check',
61 | component: () => myImport('views/reactive/check')
62 | }
63 |
64 | ]
65 | },
66 | {
67 | path: '/ref',
68 | name: 'ref',
69 | component: () => myImport('views/component')
70 | },
71 | {
72 | path: '/look',
73 | name: 'look',
74 | component: () => myImport('views/look/index'),
75 | children: [
76 | { // es6的Proxy
77 | path: 'watch',
78 | name: 'look-watch',
79 | component: () => myImport('views/look/watch')
80 | }
81 | ]
82 | },
83 | {
84 | path: '/store',
85 | name: 'store',
86 | component: () => myImport('views/store')
87 | }
88 | ]
89 |
90 | const router = VueRouter.createRouter({
91 | history: VueRouter.createWebHistory(),
92 | routes
93 | })
94 |
95 | export default router
96 |
--------------------------------------------------------------------------------
/cnd/project-compositionapi/src/script/appImport.js:
--------------------------------------------------------------------------------
1 | // 直接放在Window里面好了。。。
2 | window.myImport = (url) => {
3 | return new Promise((resolve, reject) => {
4 | const ver = window.__ver || ''
5 | const baseUrl = window.__basrUrl || '/src/'
6 | // 先加载js
7 | import(baseUrl + url + '.js' + ver).then((resjs) => {
8 | const js = resjs.default
9 | if (js.template === '') {
10 | // 如果模板是空的,表示需要加载html作为模板
11 | axios.get(baseUrl + url + '.html' + ver).then((resHTML) => {
12 | js.template = resHTML.data
13 | resolve(js)
14 | })
15 | } else {
16 | // 否则直接使用js注册组件
17 | resolve(js)
18 | }
19 | })
20 | })
21 | }
22 |
--------------------------------------------------------------------------------
/cnd/project-compositionapi/src/script/nf-indexedDB.config.js:
--------------------------------------------------------------------------------
1 | const config = {
2 | dbName: 'dbTest-reactive',
3 | ver: 1,
4 | debug: true,
5 | objectStores: [ // 建库依据
6 | {
7 | objectStoreName: 'reactive'
8 | }
9 | ]
10 | }
11 |
12 | export default config
13 |
--------------------------------------------------------------------------------
/cnd/project-compositionapi/src/store/index.js:
--------------------------------------------------------------------------------
1 |
2 | import { Set_Count } from './mutation-types.js'
3 |
4 | export default Vuex.createStore({
5 | state: {
6 | // 表单弹窗的状态
7 | formState: {
8 | editState: 'add', // 编辑状态,add:添加;update:修改;show :只读显示
9 | id: 0, // 0:添加;其他:要修改或者显示的数据的ID
10 | isOpen: false, // 是否打开弹窗(模态)
11 | model: {} // 这里只是演示异步加载,实际项目中并不适合这么做
12 | }
13 | },
14 | mutations: {
15 | // 改变表单弹窗的状态
16 | setFormState(state, form) {
17 | // 可以设置单独的属性,这里偷懒了。
18 | Object.assign(state.formState, form)
19 | }
20 | },
21 | modules: {
22 | }
23 | })
24 |
--------------------------------------------------------------------------------
/cnd/project-compositionapi/src/store/map-form.js:
--------------------------------------------------------------------------------
1 | const mapForm = () => {
2 | const store = Vuex.useStore()
3 | const readonly = Vue.readonly
4 |
5 | // 返回可读可写的表单弹窗状态
6 | const formState = () => {
7 | return store.state.formState
8 | }
9 |
10 | // 返回只读的表单弹窗状态
11 | const getFormState = () => {
12 | return readonly(store.state.formState)
13 | }
14 |
15 | // 打开弹窗
16 | const openForm = () =>{
17 | store.commit('setFormState', { isOpen: true})
18 | }
19 |
20 | // 打开弹窗
21 | const closeForm = () =>{
22 | store.commit('setFormState', { isOpen: false})
23 | }
24 |
25 | // 设置添加数据
26 | const addData = () =>{
27 | store.commit('setFormState', {
28 | isOpen: true,
29 | id: 0,
30 | editState: 'add'
31 | })
32 | }
33 |
34 | // 设置修改状态
35 | const updateData = (id) =>{
36 | store.commit('setFormState', {
37 | isOpen: true,
38 | id: id,
39 | editState: 'update'
40 | })
41 | }
42 |
43 | // 设置只读状态
44 | const showData = (id) =>{
45 | store.commit('setFormState', {
46 | isOpen: true,
47 | id: id,
48 | editState: 'show'
49 | })
50 | }
51 |
52 | // 异步获取数据
53 | const loadData = (id) =>{
54 | return new Promise((resolve, reject) => {
55 | setTimeout(() => {
56 | store.commit('setFormState', {
57 | model: {
58 | title: '假装异步获取了数据'
59 | }
60 | })
61 | resolve('成功了!')
62 | }, 1000);
63 | })
64 |
65 | }
66 |
67 | return {
68 | formState, // 可读写状态
69 | getFormState, // 只读状态
70 | openForm, // 打开弹窗
71 | closeForm, // 关闭弹窗
72 | addData, // 添加新纪录并且打开弹窗
73 | updateData, // 修改记录并且打开弹窗
74 | showData, // 显示数据并且打开弹窗
75 | loadData // 异步加载数据
76 | }
77 |
78 | }
79 |
80 | export default mapForm
--------------------------------------------------------------------------------
/cnd/project-compositionapi/src/store/map.js:
--------------------------------------------------------------------------------
1 |
2 | const map = () => {
3 | const store = Vuex.useStore()
4 |
5 | /**
6 | * 获取count,
7 | * 用computed实现相应
8 | */
9 | const getCount = () => {
10 | return Vue.computed(() => store.state.count)
11 | }
12 |
13 | /**
14 | * 获取count,
15 | ** 用 ref 实现相应
16 | */
17 | const getRefCount = () => {
18 | return Vue.ref(store.state.count)
19 | }
20 |
21 | /**
22 | * 获取对象
23 | */
24 | const getObject = () => {
25 | return store.state.myObject
26 | }
27 |
28 | /**
29 | * 获取只读对象
30 | */
31 | const getReadonlyObject = () => {
32 | return Vue.readonly(store.state.myObject)
33 | }
34 |
35 | /**
36 | * 获取数组
37 | */
38 | const getArray = () => {
39 | return store.state.myArray
40 | }
41 | /**
42 | * 获取只读数组
43 | */
44 | const getReadonlyArray = () => {
45 | return Vue.readonly(store.state.myArray)
46 | }
47 |
48 | /**
49 | * 查询数组
50 | ** id:要查询的数据
51 | */
52 | const filterArray = (id) => {
53 | return Vue.computed(() => store.getters.filterArray(id))
54 | }
55 |
56 | return {
57 | getCount,
58 | getRefCount,
59 | getObject,
60 | getReadonlyObject,
61 | getArray,
62 | getReadonlyArray,
63 | filterArray
64 | }
65 |
66 | }
67 |
68 | export default map
--------------------------------------------------------------------------------
/cnd/project-compositionapi/src/store/mutation-types.js:
--------------------------------------------------------------------------------
1 | export const Set_Count = 'set_count'
2 | export const Set_Count_sy = Symbol('set_count')
3 |
--------------------------------------------------------------------------------
/cnd/project-compositionapi/src/views/component.html:
--------------------------------------------------------------------------------
1 |
2 | 演示一下组件里面使用组件的方式
3 |
4 |
5 |
--------------------------------------------------------------------------------
/cnd/project-compositionapi/src/views/component.js:
--------------------------------------------------------------------------------
1 | export default {
2 | name: 'template',
3 | template: ``,
4 | components: {
5 | test: Vue.defineAsyncComponent(
6 | () => myImport('components/test')
7 | )
8 | },
9 | setup () {
10 | const value = Vue.ref('传入组件的参数')
11 | return {
12 | value
13 | }
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/cnd/project-compositionapi/src/views/home.js:
--------------------------------------------------------------------------------
1 | const { ref, reactive } = Vue
2 |
3 | const testManage = () => {
4 | const hello = ref('你好,世界')
5 | const clickMe = () => {
6 | hello.value = '好的,收到,现在时间:' + new Date()
7 | }
8 |
9 | return {
10 | hello,
11 | clickMe
12 | }
13 | }
14 |
15 | // vue3的对象
16 | export default {
17 | template: `
18 |
我是 {{value.name}}
19 |
20 | 老规矩:{{hello}}
21 | 快点我
22 |
23 | 这里演示 Vue3 的 响应式 和 composition API 的各种用法
24 |
25 | `,
26 | setup() {
27 | // 使用外面的定义,分解setup内部的代码
28 | const { hello, clickMe } = testManage()
29 |
30 | const value = reactive({
31 | name: 'jyk'
32 | })
33 |
34 |
35 | return {
36 | value,
37 | hello,
38 | clickMe
39 | }
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/cnd/project-compositionapi/src/views/look/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | watch
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/cnd/project-compositionapi/src/views/look/index.js:
--------------------------------------------------------------------------------
1 |
2 |
3 | /**
4 | * 监听和计算属性
5 | */
6 | export default {
7 | name: 'look',
8 | template: '',
9 | setup () {
10 | const value = Vue.ref('数据绑定的演示')
11 |
12 | return {
13 | value
14 | }
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/cnd/project-compositionapi/src/views/look/watch.js:
--------------------------------------------------------------------------------
1 | const watch = Vue.watch
2 |
3 | import { person, personReactive, objectReactive } from '../reactive/person.js'
4 |
5 | /**
6 | * watch 监听
7 | *
8 | */
9 | export default {
10 | name: 'watch-watch',
11 | template: `
12 |
13 | 展示 watch
14 | js 对象:{{ personReactive }}
15 |
16 | 修改属性
17 |
18 | `,
19 | setup () {
20 | // 查看 reactive 实例结构
21 | console.log('reactive', personReactive)
22 | // 获取嵌套对象属性
23 |
24 | // 监听属性
25 | watch(() => personReactive.name, (v1,v2) => {
26 | console.log('name改变了', v1)
27 | })
28 |
29 | // 监听对象
30 | watch(() => personReactive, (v1,v2) => {
31 | console.log('改变了', v1)
32 | },
33 | {
34 | deep:true
35 | })
36 |
37 | const update = () => {
38 | personReactive.name = '改变' + Math.random()
39 | personReactive.contacts.QQ = Math.random()
40 | }
41 |
42 | return {
43 | person, // js对象
44 | personReactive, // perosn 套上 reactive
45 | objectReactive, // {} 套上 reactive
46 | update // 修改属性
47 | }
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/cnd/project-compositionapi/src/views/reactive/check.html:
--------------------------------------------------------------------------------
1 |
2 | 验证类型函数
3 |
4 | 待验证类型
5 | isProxy
6 | isReactive
7 | isReadonly
8 |
9 |
10 | object
11 | {{obj.check1}}
12 | {{obj.check2}}
13 | {{obj.check3}}
14 |
15 |
16 | 自定义Proxy (object)
17 | {{myproxy.check1}}
18 | {{myproxy.check2}}
19 | {{myproxy.check3}}
20 |
21 |
22 | 自定义Proxy (Reactive)
23 | {{myproxyReactive.check1}}
24 | {{myproxyReactive.check2}}
25 | {{myproxyReactive.check3}}
26 |
27 |
28 |
29 | reactive (object)
30 | {{reto.check1}}
31 | {{reto.check2}}
32 | {{reto.check3}}
33 |
34 |
41 |
42 |
43 | shallowReactive (object)
44 | {{shallowRetObj.check1}}
45 | {{shallowRetObj.check2}}
46 | {{shallowRetObj.check3}}
47 |
48 |
49 | shallowReactive (Reactive)
50 | {{shallowRetRet.check1}}
51 | {{shallowRetRet.check2}}
52 | {{shallowRetRet.check3}}
53 |
54 |
55 |
56 | readonly (object)
57 | {{readObj.check1}}
58 | {{readObj.check2}}
59 | {{readObj.check3}}
60 |
61 |
62 | readonly (Reactive)
63 | {{readRet.check1}}
64 | {{readRet.check2}}
65 | {{readRet.check3}}
66 |
67 |
68 |
69 | shallowReadonly (object)
70 | {{shallowReadObj.check1}}
71 | {{shallowReadObj.check2}}
72 | {{shallowReadObj.check3}}
73 |
74 |
75 | shallowReadonly (Reactive)
76 | {{shallowReadRet.check1}}
77 | {{shallowReadRet.check2}}
78 | {{shallowReadRet.check3}}
79 |
80 |
81 |
82 |
--------------------------------------------------------------------------------
/cnd/project-compositionapi/src/views/reactive/check.js:
--------------------------------------------------------------------------------
1 | const isProxy = Vue.isProxy
2 | const isReactive = Vue.isReactive
3 | const isReadonly = Vue.isReadonly
4 | const toRaw = Vue.toRaw
5 |
6 | import {
7 | person, // object 对象
8 | personReactive, // object 的 reactive 代理
9 | // 深层读写
10 | objectReactive, // reactive (object)
11 | // 浅层读写
12 | objectShallowReactive, // 浅层 代理
13 | // 浅层 reactive 的读写
14 | retShallowReactive,
15 | // 浅层只读
16 | objectShallowReadonly, // 浅层只读 object
17 | reactiveShallowReadonly, // 浅层只读 reactive
18 | // 深层只读
19 | objectReadonly , // 深层只读 object
20 | reactiveReadonly // 深层只读 reactive
21 | } from './person.js?v=1'
22 |
23 | const myProxy = (obj) => {
24 | const pp = new Proxy(obj, {
25 | get: function (target, key, receiver) {
26 | if (typeof key !== 'symbol') {
27 | console.log(`getting ${key}!`, target[key])
28 | } else {
29 | console.log('getting symbol:', key, target[key])
30 | }
31 | return Reflect.get(target, key, receiver)
32 | },
33 | set: function (target, key, value, receiver) {
34 | console.log(`setting ${key}:${value}!`)
35 | return Reflect.set(target, key, value, receiver)
36 | }
37 | })
38 | return pp
39 | }
40 |
41 | /**
42 | * 验证类型
43 | * isPoxy、isReactive、isReadonly做对比测试
44 | */
45 | export default {
46 | name: 'reactive-check',
47 | template: ``,
48 | setup () {
49 |
50 | const myProxyObject = myProxy({title:'222', __v_isReactive: true})
51 | console.log('myProxyObject', myProxyObject)
52 | const myProxyReactive = myProxy(objectReactive)
53 | console.log('myProxyReactive', myProxyReactive)
54 |
55 | // 试一试 __v_isReadonly
56 | console.log('objectReactive', objectReactive)
57 | console.log('__v_isReadonly'
58 | , objectReactive.__v_isReadonly
59 | , objectReactive.__v_isReactive
60 | )
61 |
62 | // 取原型
63 | const raw = toRaw(myProxyReactive)
64 | console.log('自己定义的Proxy取原型', raw)
65 |
66 | return {
67 | obj: { // js对象
68 | check1: isProxy(person),
69 | check2: isReactive(person),
70 | check3: isReadonly(person)
71 | },
72 | myproxy: { // 自己定义的Proxy object
73 | check1: isProxy(myProxyObject),
74 | check2: isReactive(myProxyObject),
75 | check3: isReadonly(myProxyObject)
76 | },
77 | myproxyReactive: { // 自己定义的Proxy reactive
78 | check1: isProxy(myProxyReactive),
79 | check2: isReactive(myProxyReactive),
80 | check3: isReadonly(myProxyReactive)
81 | },
82 | // 深层响应 reactive(object)
83 | reto: { // reactive(object)
84 | check1: isProxy(objectReactive),
85 | check2: isReactive(objectReactive),
86 | check3: isReadonly(objectReactive)
87 | },
88 | // 浅层响应 参数:object
89 | shallowRetObj: {
90 | check1: isProxy(objectShallowReactive),
91 | check2: isReactive(objectShallowReactive),
92 | check3: isReadonly(objectShallowReactive)
93 | },
94 | // 浅层响应 参数:reactive
95 | shallowRetRet: {
96 | check1: isProxy(retShallowReactive),
97 | check2: isReactive(retShallowReactive),
98 | check3: isReadonly(retShallowReactive)
99 | },
100 |
101 | // 深层只读,参数 object =======================
102 | readObj: { // readonly object
103 | check1: isProxy(objectReadonly),
104 | check2: isReactive(objectReadonly),
105 | check3: isReadonly(objectReadonly)
106 | },
107 | // 深层只读,参数 reactive
108 | readRet: { // readonly reactive
109 | check1: isProxy(reactiveReadonly),
110 | check2: isReactive(reactiveReadonly),
111 | check3: isReadonly(reactiveReadonly)
112 | },
113 | // 浅层只读 参数:object
114 | shallowReadObj: {
115 | check1: isProxy(objectShallowReadonly),
116 | check2: isReactive(objectShallowReadonly),
117 | check3: isReadonly(objectShallowReadonly)
118 | },
119 | // 浅层只读 参数:reactive
120 | shallowReadRet: {
121 | check1: isProxy(reactiveShallowReadonly),
122 | check2: isReactive(reactiveShallowReadonly),
123 | check3: isReadonly(reactiveShallowReadonly)
124 | },
125 | person
126 | }
127 | }
128 | }
129 |
--------------------------------------------------------------------------------
/cnd/project-compositionapi/src/views/reactive/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | ES6的Proxy
5 | 用Proxy套个娃
6 | reactive
7 | shallowReactive
8 | MarkRaw
9 | readonly
10 | shallowReadonly
11 | toRaw取原型
12 | 判断类型
13 | 响应性测试
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/cnd/project-compositionapi/src/views/reactive/index.js:
--------------------------------------------------------------------------------
1 |
2 | /**
3 | * reactive的导航页面
4 | * 1、定义reactive看效果
5 | * 2、只读模式
6 | * 3、类型判断
7 | * 4、响应性测试
8 | */
9 | export default {
10 | name: 'reactive',
11 | template: '',
12 | setup () {
13 | const value = Vue.ref('数据绑定的演示')
14 |
15 | return {
16 | value
17 | }
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/cnd/project-compositionapi/src/views/reactive/let.html:
--------------------------------------------------------------------------------
1 |
2 | 展示reactive的定义
3 |
4 |
--------------------------------------------------------------------------------
/cnd/project-compositionapi/src/views/reactive/let.js:
--------------------------------------------------------------------------------
1 | export default {
2 | name: 'About',
3 | template: '',
4 | setup () {
5 | const value = Vue.ref('数据绑定的演示')
6 |
7 | return {
8 | value
9 | }
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/cnd/project-compositionapi/src/views/reactive/markraw.js:
--------------------------------------------------------------------------------
1 | const reactive = Vue.reactive
2 | const markRaw = Vue.markRaw
3 |
4 | const testmarkRaw = () => {
5 | // js对象
6 | const object = markRaw({
7 | name: 'jyk',
8 | age: 18,
9 | contacts: {
10 | QQ: 11111,
11 | phone: 123456789
12 | }
13 | })
14 |
15 | // reactive的对象
16 | const retObject1 = reactive({
17 | name: object.name
18 | })
19 |
20 | const retObject2 = reactive(object)
21 |
22 | return {
23 | object,
24 | retObject1,
25 | retObject2
26 | }
27 | }
28 |
29 | /**
30 | * MarkRaw 做个标记,不响应。
31 | * 自己定义一个Proxy,看看效果
32 | */
33 | export default {
34 | name: 'reactive-Proxy',
35 | components: {
36 | test: Vue.defineAsyncComponent(() => myImport('components/test'))
37 | },
38 | template: `
39 |
40 | markRaw 标记
41 | retObject1:{{retObject1}}
42 | 11
43 | 修改状态
44 |
45 | `,
46 | setup () {
47 | const {
48 | object,
49 | retObject1,
50 | retObject2
51 | } = testmarkRaw()
52 |
53 | console.log('作为初始值:', retObject1)
54 | console.log('无法变成响应式:', retObject2)
55 |
56 | // 修改数据
57 | const update = () => {
58 | // 新增属性
59 | // myProxyReactive['new'] = '这是一个新属性' + Math.random()
60 | }
61 |
62 | return {
63 | object,
64 | retObject1,
65 | retObject2,
66 | update
67 | }
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/cnd/project-compositionapi/src/views/reactive/person.js:
--------------------------------------------------------------------------------
1 |
2 | const reactive = Vue.reactive
3 | const shallowReactive = Vue.shallowReactive
4 | const readonly = Vue.readonly
5 | const shallowReadonly = Vue.shallowReadonly
6 |
7 | /**
8 | * 普通js对象的 person
9 | */
10 | export const person = {
11 | name: 'jyk',
12 | age: 18,
13 | contacts: {
14 | QQ: 11111,
15 | phone: 123456789
16 | }
17 | }
18 |
19 | /**
20 | * person 的 reactive 代理
21 | */
22 | export const personReactive = reactive(person)
23 |
24 | /**
25 | * js对象的 reactive 响应式代理
26 | */
27 | export const objectReactive = reactive({
28 | name: 'jykReactive',
29 | age: 18,
30 | contacts: {
31 | QQ: 11111,
32 | phone: 123456789
33 | }
34 | })
35 |
36 | /**
37 | * js对象的 shallowReactive 响应式代理
38 | */
39 | export const objectShallowReactive = shallowReactive({
40 | name: 'jykShallowReactive',
41 | age: 18,
42 | contacts: {
43 | QQ: 11111,
44 | phone: 123456789
45 | }
46 | })
47 |
48 | /**
49 | * reactive 的 shallowReactive 响应式代理
50 | */
51 | export const retShallowReactive = shallowReactive(objectReactive)
52 |
53 | // ================================================
54 |
55 | /**
56 | * person 的 readonly 代理
57 | */
58 | export const objectReadonly = readonly(person)
59 |
60 | /**
61 | * reactive 的 readonly 代理
62 | */
63 | export const reactiveReadonly = readonly(objectReactive)
64 |
65 | /**
66 | * person 的 shallowReadonly 响应式代理
67 | */
68 | export const objectShallowReadonly = shallowReadonly(person)
69 |
70 | /**
71 | * reactive 的 shallowReadonly 响应式代理
72 | */
73 | export const reactiveShallowReadonly = shallowReadonly(objectReactive)
74 |
75 | // ================================================
76 |
--------------------------------------------------------------------------------
/cnd/project-compositionapi/src/views/reactive/proxy-reactive.js:
--------------------------------------------------------------------------------
1 | const reactive = Vue.reactive
2 | const watch = Vue.watch
3 |
4 | const test = () => {
5 | // js对象
6 | const object = {
7 | name: 'jyk',
8 | age: 18,
9 | contacts: {
10 | QQ: 11111,
11 | phone: 123456789
12 | }
13 | }
14 |
15 | // reactive的对象
16 | const retObject = reactive({
17 | name: 'jyk',
18 | age: 18,
19 | contacts: {
20 | QQ: 11111,
21 | phone: 123456789
22 | }
23 | })
24 |
25 | /**
26 | * 用Proxy定义一个 reactive 的套娃,实现可以监听任意属性变化的目的
27 | * @param {*} _target 要拦截的目标
28 | * @param {*} callback 属性变化后的回调函数
29 | */
30 | const myReactive = (_target, callback) => {
31 | let _change = (key, value) => {console.log('内部函数')}
32 | const proxy = new Proxy(_target, {
33 | get: function (target, key, receiver) {
34 | if (typeof key !== 'symbol') {
35 | console.log(`getting ${key}!`, target[key])
36 | } else {
37 | console.log('getting symbol:', key, target[key])
38 | }
39 | // 调用原型方法
40 | return Reflect.get(target, key, receiver)
41 | },
42 | set: function (target, key, value, receiver) {
43 | console.log(`setting ${key}:${value}!`)
44 | // 源头监听
45 | if (typeof callback === 'function') {
46 | callback(key, value)
47 | }
48 | // 任意位置监听
49 | if (typeof _target.__watch === 'function') {
50 | _change(key, value)
51 | }
52 | // 调用原型方法
53 | return Reflect.set(target, key, value, target)
54 | }
55 | })
56 | // 实现任意位置的监听,
57 | proxy.__watch = (callback) => {
58 | if (typeof callback === 'function') {
59 | _change = callback
60 | }
61 | }
62 | // 返回实例
63 | return proxy
64 | }
65 |
66 | const myProxy = (_target) => {
67 | const proxy = new Proxy(_target, {
68 | get: function (target, key, receiver) {
69 | console.log(`getting ${key}:`, target[key])
70 | // 调用原型方法
71 | return Reflect.get(target, key, receiver)
72 | },
73 | set: function (target, key, value, receiver) {
74 | console.log(`setting ${key}:${value}!`)
75 | // 调用原型方法
76 | return Reflect.set(target, key, value, receiver)
77 | }
78 | })
79 | // 返回实例
80 | return proxy
81 | }
82 |
83 | return {
84 | object,
85 | retObject,
86 | myReactive,
87 | myProxy
88 | }
89 | }
90 |
91 | /**
92 | * ES6的Proxy
93 | * 自己定义一个Proxy,看看效果
94 | */
95 | export default {
96 | name: 'reactive-Proxy',
97 | template: `
98 |
99 | 用 Proxy 给reactive 套个娃看看效果
100 | 拦截reactive的myProxy:{{myProxyReactive}}
101 | 修改状态
102 |
103 | `,
104 | setup () {
105 | const {
106 | object,
107 | retObject,
108 | myReactive,
109 | myProxy
110 | } = test()
111 |
112 | console.log('object', object)
113 | console.log('retObject', retObject)
114 |
115 | // 定义一个拦截普通对象的Proxy
116 | const myProxyObject = myReactive(object, ((key, value) =>{
117 | console.log(`obj外部获得通知:${key}:${value}`)
118 | }))
119 | console.log('myProxyObject', myProxyObject)
120 |
121 | // 定义一个拦截reactive的Proxy
122 | // 并且实现源头的监听
123 | const myProxyReactive = myReactive(retObject,
124 | ((key, value) =>{
125 | console.log(`ret外部获得通知:${key}:${value}`)
126 | })
127 | )
128 | console.log('myProxyReactive', myProxyReactive)
129 |
130 | // 任意位置的监听
131 | myProxyReactive.__watch((key, value) => {
132 | console.log(`任意位置的监听:${key}:${value}`)
133 | })
134 |
135 | // 定义自己写的Proxy
136 | const testProxy = myProxy({
137 | name: 'jyk',
138 | age: 18
139 | })
140 | console.log('自己定义的Proxy实例:')
141 | console.log(testProxy)
142 |
143 | // 测试拦截情况
144 | testProxy.name = '新的名字'
145 | console.log(testProxy.name)
146 |
147 | // 深度监听
148 | watch(() => retObject, (v1, v2) => {
149 | console.log('监听属性', v1, v2)
150 | },{
151 | deep: true // 深度监听
152 | })
153 |
154 | // 修改数据
155 | const update = () => {
156 | // retObject.name = 'reactive修改name'
157 | retObject['newprops'] = '新增一个属性:' + Math.random()
158 | myProxyReactive.name = '自定义的拦截修改name' + Math.random()
159 | myProxyReactive.contacts.QQ = 123456
160 | // 新增属性
161 | // myProxyReactive['new'] = '这是一个新属性' + Math.random()
162 | }
163 |
164 | return {
165 | object,
166 | retObject,
167 | myProxyObject,
168 | myProxyReactive,
169 | update
170 | }
171 | }
172 | }
173 |
--------------------------------------------------------------------------------
/cnd/project-compositionapi/src/views/reactive/proxy.js:
--------------------------------------------------------------------------------
1 |
2 | const test = () => {
3 | // js对象
4 | const object = {
5 | name: 'jyk',
6 | age: 18,
7 | contacts: {
8 | QQ: 11111,
9 | phone: 123456789
10 | }
11 | }
12 |
13 | /**
14 | * 模仿reactive,定义一个Proxy实例,观察拦截情况
15 | * @param {*} _target 原型对象
16 | */
17 | const myProxy = (_target) => {
18 | const proxy = new Proxy(_target, {
19 | get: function (target, key, receiver) {
20 | console.log('getting',key, ':', target[key])
21 | // 调用原型方法
22 | return Reflect.get(target, key, receiver)
23 | },
24 | set: function (target, key, value, receiver) {
25 | console.log(`setting ${key} : ${value}`)
26 | // 调用原型方法
27 | return Reflect.set(target, key, value, receiver)
28 | }
29 | })
30 | // 返回实例
31 | return proxy
32 | }
33 |
34 | return {
35 | object,
36 | myProxy
37 | }
38 | }
39 |
40 | /**
41 | * ES6的Proxy
42 | * 自己定义一个Proxy,看看效果
43 | */
44 | export default {
45 | name: 'es6-Proxy',
46 | template: `
47 |
48 | ES6的proxy
49 | 自己定义的myProxy:{{testProxy}}
50 | 修改状态
51 |
52 | `,
53 | setup () {
54 | const {
55 | object,
56 | myProxy
57 | } = test()
58 |
59 | console.log('object', object)
60 |
61 | // 定义自己写的Proxy
62 | const testProxy = myProxy({
63 | name: 'jyk',
64 | age: 18,
65 | contacts: {
66 | QQ: 11111,
67 | phone: 123456789
68 | }
69 | })
70 | console.log('自己定义的Proxy实例:')
71 | console.log(testProxy)
72 |
73 | // 测试拦截情况
74 | testProxy.name = '新的名字'
75 | console.log(testProxy.name)
76 |
77 | // 伪造一个reactive,看看toRaw好用不。
78 | const raw = Vue.toRaw(Vue.toRaw(myProxy({name: 'jyk',__v_isReactive: true})))
79 | console.log('伪装成reactive 的raw11', raw)
80 |
81 | // 修改数据
82 | const update = () => {
83 | // retObject.name = 'reactive修改name'
84 | testProxy['newprops'] = '新增一个属性:' + Math.random()
85 | testProxy.name = '自定义的拦截修改name' + Math.random()
86 | testProxy.contacts.QQ = 123456
87 | // 新增属性
88 | // myProxyReactive['new'] = '这是一个新属性' + Math.random()
89 | }
90 |
91 | return {
92 | object,
93 | testProxy,
94 | update
95 | }
96 | }
97 | }
98 |
--------------------------------------------------------------------------------
/cnd/project-compositionapi/src/views/reactive/reactive-shallow.js:
--------------------------------------------------------------------------------
1 |
2 | import { person, objectShallowReactive } from './person.js'
3 |
4 | /**
5 | * 定义 shallowReactive
6 | */
7 | export default {
8 | name: 'reactive-shallowReactive',
9 | template: `
10 |
11 | 展示 shallowReactive
12 | shallowReactive 对象:{{objectShallowReactive}}
13 | shallowReactive 的name属性:{{objectShallowReactive.name}} (有响应)
14 | shallowReactive 的contacts属性 的 QQ属性:{{objectShallowReactive.contacts.QQ}} (没有相应)
15 |
16 | 单独的 name:{{name}} (没有相应)
17 | 单独的 contacts:{{contacts}} (没有响应)
18 |
19 | 修改属性
20 |
21 | `,
22 | setup () {
23 | // 查看 shallowReactive 实例结构
24 | console.log('shallowReactive', objectShallowReactive)
25 | // 获取嵌套对象属性
26 | const contacts = objectShallowReactive.contacts
27 | // 因为浅层,所以没有响应性
28 | console.log('contacts属性:', contacts)
29 | // 获取简单类型的属性
30 | let name = objectShallowReactive.name
31 | // 属性是简单类型的,所以失去响应性
32 | console.log('name属性:', name)
33 |
34 | const update = () => {
35 | // 修改原型
36 | person.name = '修改原型的name' + Math.random()
37 |
38 | // 修改属性
39 | objectShallowReactive.name = '设置代理的name属性' // + Math.random()
40 | objectShallowReactive.contacts.QQ = 123 + Math.random()
41 |
42 | // 修改结构的属性
43 | name = '设置解构的name属性' + Math.random()
44 | contacts.QQ = 123 + Math.random()
45 | }
46 |
47 | return {
48 | person, // js对象
49 | objectShallowReactive, // perosn 套上 reactive
50 | name, // 结构的name属性
51 | contacts, // 结构的对象属性
52 | update // 修改属性
53 | }
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/cnd/project-compositionapi/src/views/reactive/reactive.js:
--------------------------------------------------------------------------------
1 | const reactive = Vue.reactive
2 |
3 | import { person, personReactive, objectReactive } from './person.js'
4 |
5 | /**
6 | * reactive 的结构
7 | * 属性的深层响应性
8 | *
9 | */
10 | export default {
11 | name: 'reactive-reactive',
12 | template: `
13 |
14 | 展示 reactive
15 | js 对象:{{person}}
16 | reactive 对象:{{objectReactive}}
17 | reactive 的name属性:{{objectReactive.name}}
18 | reactive 的contacts属性 的 QQ属性:{{objectReactive.contacts.QQ}}
19 |
20 | 单独的 name:{{name}} (没有相应)
21 | 单独的 contacts:{{contacts}} (有响应)
22 |
23 | reactive 数组:{{reactiveArray}}
24 |
25 | 修改属性
26 | 整体赋值
27 |
28 | `,
29 | setup () {
30 | // 查看 reactive 实例结构
31 | console.log('reactive', personReactive)
32 | // 获取嵌套对象属性
33 | const contacts = personReactive.contacts
34 | console.log('contacts属性:', contacts) // 因为深层响应,所以依然有响应性
35 | // 获取简单类型的属性
36 | let name = personReactive.name
37 | console.log('name属性:', name) // 属性是简单类型的,所以失去响应性
38 |
39 | // js对象
40 | console.log('person', person)
41 |
42 | // reactive 的数组
43 | const reactiveArray = reactive([
44 | {
45 | name: 'jyk',
46 | age: 18
47 | },
48 | {
49 | name: 'jyk111',
50 | age: 19
51 | }
52 | ])
53 |
54 | const update = () => {
55 | // 修改原型
56 | person.name = '修改原型的name' + Math.random()
57 |
58 | // 修改 person 的代理 属性
59 | personReactive.name = '修改person代理的name属性' + Math.random()
60 |
61 | // 修改属性
62 | objectReactive.name = '设置代理的name属性' + Math.random()
63 | objectReactive.contacts.QQ = 123 + Math.random()
64 |
65 | // 修改结构的属性
66 | name = '设置解构的name属性' + Math.random()
67 | contacts.QQ = 123 + Math.random()
68 | // retArray
69 | // console.log('现在的person', person)
70 | }
71 |
72 | const setReactive = () => {
73 | // 直接赋值
74 | Object.assign(objectReactive, {name: '合并', age: 111, newp: '新属性'})
75 | // reactiveArray.length = 0 // 容易照成闪烁
76 | setTimeout(() => {
77 | const newArray = [
78 | { name: '11', age: 18 },
79 | { name: '22', age: 18 },
80 | { name: '33', age: 18 }
81 | ]
82 | // 可以防止闪烁
83 | reactiveArray.length = 0
84 | reactiveArray.push(...newArray)
85 | }, 1000);
86 | }
87 |
88 | return {
89 | person, // js对象
90 | personReactive, // perosn 套上 reactive
91 | objectReactive, // {} 套上 reactive
92 | name, // 结构的name属性
93 | contacts, // 结构的对象属性
94 | reactiveArray, // 数组的响应性
95 | update, // 修改属性
96 | setReactive // 直接设置
97 | }
98 | }
99 | }
100 |
--------------------------------------------------------------------------------
/cnd/project-compositionapi/src/views/reactive/readonly-shallow.js:
--------------------------------------------------------------------------------
1 | import {
2 | person, // object 对象
3 | objectReactive, // 普通的 object 的 reactive 代理
4 | objectShallowReadonly, // reactive 的 readonly 代理
5 | reactiveShallowReadonly // 普通的 object 的 readonly 代理
6 | } from './person.js'
7 |
8 | /**
9 | * 定义 shallowReadonly
10 | *
11 | */
12 | export default {
13 | name: 'reactive-shallowReadonly',
14 | template: `
15 |
16 | 展示 shallowReadonly
17 | object 的只读代理:{{objectShallowReadonly}}
18 | reactive 的 只读代理:{{reactiveShallowReadonly}}
19 | reactive 对象:{{objectReactive}}
20 |
21 | 修改属性
22 |
23 | `,
24 | setup () {
25 | // 查看 readonly 实例结构
26 | console.log('object 的 objectShallowReadonly')
27 | console.log(objectShallowReadonly)
28 | console.log('reactive 的 reactiveShallowReadonly')
29 | console.log(reactiveShallowReadonly)
30 |
31 | // 修改数据
32 | const update = () => {
33 |
34 | }
35 |
36 | return {
37 | objectShallowReadonly,
38 | reactiveShallowReadonly,
39 | objectReactive,
40 | update
41 | }
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/cnd/project-compositionapi/src/views/reactive/readonly.js:
--------------------------------------------------------------------------------
1 |
2 | import {
3 | person, // object 对象
4 | objectReactive, // object 的 reactive 代理
5 | reactiveReadonly, // reactive 的 readonly 代理
6 | objectReadonly // object 的 readonly 代理
7 | } from './person.js'
8 |
9 | /**
10 | * 展示 readonly
11 | *
12 | */
13 | export default {
14 | name: 'reactive-readonly',
15 | template: `
16 |
17 | 展示 readonly
18 | js 对象的只读代理:{{objectReadonly}}
19 | reactive 的 只读代理:{{reactiveReadonly}}
20 | reactive 对象:{{objectReactive}}
21 |
22 | 修改属性
23 |
24 | `,
25 | setup () {
26 | // 查看 readonly 实例结构
27 | console.log('object 的readonly')
28 | console.log(objectReadonly)
29 | console.log('reactive 的readonly')
30 | console.log(reactiveReadonly)
31 |
32 | // 获取嵌套对象属性
33 | const contacts = reactiveReadonly.contacts
34 | console.log('contacts属性:', contacts) // 因为深层响应,所以依然有响应性
35 | // 获取简单类型的属性
36 | let name = reactiveReadonly.name
37 | console.log('name属性:', name) // 属性是简单类型的,所以失去响应性
38 |
39 | // 修改数据
40 | const update = () => {
41 | // 可以影响readonlyObject.name的值,但是模板不会刷新
42 | person.name = '修改对象原型的name'
43 | // 不会修改,有警告
44 | objectReadonly.name = '改只读纯对象的name'
45 | // 不会修改,有警告
46 | objectReadonly.contacts.QQ = 1232222
47 | // 不会修改,有警告
48 | reactiveReadonly.name = '改只读reactive的name'
49 | // 不会修改,有警告
50 | reactiveReadonly.contacts.QQ = 345
51 | // 可以修改 readonly代理的值,并且可以更新模板
52 | person.name = '改原型reactive的name'
53 | // 可以修改 readonly代理的值,并且可以更新模板
54 | person.contacts.QQ = 789
55 |
56 | }
57 |
58 | return {
59 | person,
60 | objectReactive,
61 | reactiveReadonly,
62 | objectReadonly,
63 | update
64 | }
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/cnd/project-compositionapi/src/views/reactive/toraw.js:
--------------------------------------------------------------------------------
1 | const toRaw = Vue.toRaw
2 |
3 | import {
4 | person, // object 对象
5 | objectReactive, // 普通的 object 的 reactive 代理
6 | objectShallowReactive, // reactive 的 shallowReactive 代理
7 | objectReadonly, // 普通的 object 的 readonly 代理
8 | objectShallowReadonly
9 | } from './person.js'
10 |
11 | import indexedDB from '../../script/nf-indexedDB.js'
12 |
13 | /**
14 | * toRaw 取原型
15 | * 序列化
16 | * 存储
17 | */
18 | export default {
19 | name: 'reactive-toRaw',
20 | template: `
21 |
22 | 展示 toRaw
23 |
24 | 修改属性
25 |
26 |
27 | `,
28 | setup () {
29 |
30 | const { setup, addObject} = indexedDB()
31 |
32 | console.log('reacive 的原型', toRaw(objectReactive))
33 | console.log('shallowReactive 的原型', toRaw(objectShallowReactive))
34 | console.log('readonly 的原型', toRaw(objectReadonly))
35 | console.log('shallowReadonly 的原型', toRaw(objectShallowReadonly))
36 |
37 | // 转为json
38 | const json1 = JSON.stringify(person)
39 | console.log('json1', json1)
40 | const json2 = JSON.stringify(toRaw(objectReactive))
41 | console.log('json2', json2)
42 | const json3 = JSON.stringify(objectReactive)
43 | console.log('json3', json3)
44 |
45 | // 保存到
46 | const update = () => {
47 | const storage = window.sessionStorage
48 | //写入 reactive
49 | storage['test-reactive'] = objectReactive
50 | storage['test-json'] = json3
51 | // 直接存入 indexedDB会报错
52 | // addObject('reactive', objectReactive)
53 | // 存入原型
54 | addObject('reactive', toRaw(objectReactive))
55 |
56 | }
57 |
58 | return {
59 | objectReactive,
60 | objectReadonly,
61 | update
62 | }
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/cnd/project-compositionapi/src/views/store.html:
--------------------------------------------------------------------------------
1 |
2 | 这里演示一下 vuex 的一些操作:
3 |
4 | ref的count :{{refCount}}
5 | 计算属性的Count :{{comCount}}
6 | 只读对象 :{{readonlyObject}}
7 |
8 |
--------------------------------------------------------------------------------
/cnd/project-compositionapi/src/views/store.js:
--------------------------------------------------------------------------------
1 |
2 |
3 | // 获取状态
4 | const indirectManage = () => {
5 | const store = Vuex.useStore()
6 |
7 | // 用toRef获取 count,有相应性,可以直接修改state
8 | const refCount = Vue.toRef(store.state, 'count')
9 | // 计算属性获取count,有相应性,不可以直接修改state
10 | const comCount = Vue.computed(() => store.state.count + 10)
11 | // 只读的对象,有响应性,浅层不可以修改,但是深层还是可以修改。
12 | const readonlyObject = Vue.readonly(store.state.myObject)
13 |
14 | console.log('refCount:', refCount)
15 | console.log('comCount:', comCount)
16 | console.log('readonlyObject:', readonlyObject)
17 | console.log('================')
18 |
19 | // 定时修改 count 看响应性
20 | setTimeout(() => {
21 | // store.commit('setCount')
22 | // refCount.value += 200 // 会直接改vuex的state
23 | }, 2000)
24 |
25 | return {
26 | refCount,
27 | comCount,
28 | readonlyObject
29 | }
30 | }
31 |
32 |
33 | export default {
34 | name: 'vuex_store',
35 | template: '',
36 | components: {
37 | },
38 | setup () {
39 | const value = Vue.ref('状态管理的演示')
40 |
41 | // 获取状态
42 | const { refCount, comCount, readonlyObject } = indirectManage()
43 |
44 | return {
45 | value,
46 | refCount, comCount, readonlyObject
47 | }
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/cnd/project-compositionapi/web.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/cnd/project-template/README.md:
--------------------------------------------------------------------------------
1 |
2 | # CND 的工程化开发的模板
3 |
4 | * vue的全家桶和UI库采用CDN方式加载。
5 | * 支持路由,Router。
6 | * 支持状态管理,Vuex。
7 | * 支持UI库: element-plus、ant Design Vue,其他的没测试。
8 | * 支持axios。
9 | * 采用工程化的目录结构和代码编写方式。
10 | * vue文件需要拆分成 html 文件 + js 文件的方式。
11 | * 用版本号更新浏览器的js文件的缓存。
12 |
13 | # 特点
14 |
15 | * 建立网站即可运行,不需要安装、打包。
16 | * 不需要webpack
17 | * 不需要node_modules 文件夹
18 | * jQuery的风格,可以断点跟踪调试
19 |
20 | 在线演示:
21 | https://naturefwvue.github.io/nf-vue-cnd/cnd/project-template
22 |
--------------------------------------------------------------------------------
/cnd/project-template/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
CDN模式下的工程化开发的模板
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
28 |
29 |
48 |
49 |
50 |
51 | 这里是CDN仿工程化开发的模板... 如果你没看到“首页”的内容,说明网页没有在网站的更目录。
52 |
53 |
54 |
55 |
56 | 首页
57 | 关于
58 | 异步组件
59 | 状态管理
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 | vuex状态演示
69 | $store.state :{{$store.state}}
70 |
71 | 更改状态
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
--------------------------------------------------------------------------------
/cnd/project-template/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/naturefwvue/nf-vue-cnd/7670d199337cc527a04865181c5aacd8168fb901/cnd/project-template/public/favicon.ico
--------------------------------------------------------------------------------
/cnd/project-template/src/app.js:
--------------------------------------------------------------------------------
1 |
2 | // import { Set_Count, Set_Count_sy } from './store/mutation-types.js'
3 |
4 | export default {
5 | name: 'app',
6 | setup() {
7 | const store = Vuex.useStore()
8 |
9 | // 状态的控制事件
10 | const setCount = () =>{
11 | store.commit('setCount')
12 | store.commit('setTime')
13 | store.commit('setArray')
14 | // store._mutations.setCount[0] // 这是什么?
15 | }
16 |
17 | return {
18 | // 设置state
19 | setCount
20 | }
21 | }
22 | }
--------------------------------------------------------------------------------
/cnd/project-template/src/components/test.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | 这是 组件测试
4 | 父组件传递参数:{{str}}
5 | setup 获取参数:{{str1}}
6 |
--------------------------------------------------------------------------------
/cnd/project-template/src/components/test.js:
--------------------------------------------------------------------------------
1 | export default {
2 | name: 'component-test',
3 | template: '',
4 | props: {
5 | str: String
6 | },
7 | setup(props) {
8 | // 在setup里面获取参数值
9 | let str1 = Vue.ref(props.str)
10 | str1.value += '--内部改一下。'
11 |
12 | return {
13 | str1
14 | }
15 | }
16 | }
--------------------------------------------------------------------------------
/cnd/project-template/src/main.js:
--------------------------------------------------------------------------------
1 | /*
2 | import store from './store/index.js?v=28'
3 | import router from './router/index.js?v=28'
4 | import App from './app.js?v=28'
5 |
6 |
7 | // 创建vue3的实例
8 | const app = Vue.createApp(App)
9 | .use(store) // 挂载vuex
10 | .use(router) // 挂载路由
11 | .use(ElementPlus) // 加载ElementPlus
12 | .mount('#app') // 挂载Vue的app实例
13 |
14 | */
15 |
16 | const ver = window.__ver || ''
17 |
18 | Promise.all([
19 | import('./store/index.js' + ver),
20 | import('./router/index.js' + ver),
21 | import('./app.js' + ver),
22 | ]).then((res) => {
23 | // 创建vue3的实例
24 | const app = Vue.createApp(res[2].default)
25 | .use(res[0].default) // 挂载vuex
26 | .use(res[1].default) // 挂载路由
27 | .use(ElementPlus) // 加载ElementPlus
28 | .mount('#app') // 挂载Vue的app实例
29 | })
30 |
--------------------------------------------------------------------------------
/cnd/project-template/src/router/index.js:
--------------------------------------------------------------------------------
1 |
2 | const routes = [
3 | {
4 | path: '/',
5 | name: 'Home',
6 | component: () => myImport('views/home')
7 | },
8 | {
9 | path: '/About',
10 | name: 'About',
11 | component: () => myImport('views/About')
12 | },
13 | {
14 | path: '/component',
15 | name: 'component',
16 | component: () => myImport('views/component')
17 | },
18 | {
19 | path: '/store',
20 | name: 'store',
21 | component: () => myImport('views/store')
22 | }
23 | ]
24 |
25 | const router = VueRouter.createRouter({
26 | history: VueRouter.createWebHistory(),
27 | routes
28 | })
29 |
30 | export default router
31 |
--------------------------------------------------------------------------------
/cnd/project-template/src/script/appImport.js:
--------------------------------------------------------------------------------
1 | // 直接放在Window里面好了。。。
2 | window.myImport = (url) => {
3 | return new Promise((resolve, reject) => {
4 | const ver = window.__ver || ''
5 | const baseUrl = window.__basrUrl || '/src/'
6 | // 先加载js
7 | import(baseUrl + url + '.js' + ver).then((resjs) => {
8 | const js = resjs.default
9 | if (js.template === '') {
10 | // 如果模板是空的,表示需要加载html作为模板
11 | axios.get(baseUrl + url + '.html' + ver).then((resHTML) => {
12 | js.template = resHTML.data
13 | resolve(js)
14 | })
15 | } else {
16 | // 否则直接使用js注册组件
17 | resolve(js)
18 | }
19 | })
20 | })
21 | }
22 |
--------------------------------------------------------------------------------
/cnd/project-template/src/store/index.js:
--------------------------------------------------------------------------------
1 |
2 | import { Set_Count } from './mutation-types.js'
3 |
4 | export default Vuex.createStore({
5 | state: {
6 | count: 0,
7 | myObject: {
8 | time: '现在的时间:'
9 | },
10 | myArray: [1,2,2,3,4]
11 | },
12 | getters: {
13 | getAddCount: (state) => {
14 | return state.count + 1
15 | },
16 | getTime: (state) => {
17 | return state.myObject.time + new Date()
18 | },
19 | filterArray: (state) => (id) => {
20 | return state.myArray.filter((item) => item === id)
21 | }
22 | },
23 | mutations: {
24 | // 计数器
25 | setCount(state, num = 1) {
26 | state.count += num
27 | },
28 | [Set_Count](state, num = 1) {
29 | state.count += num
30 | },
31 | // 设置当前时间
32 | setTime(state) {
33 | state.myObject.time = '现在时间:' + new Date()
34 |
35 | },
36 | // 设置数组的值
37 | setArray(state, val = 4) {
38 | state.myArray[1] = val
39 | },
40 | reloadArray(state, arr) {
41 | state.myArray.lenth = 0
42 | state.myArray = [...arr]
43 | }
44 | },
45 | actions: {
46 | // 异步获取数组
47 | getArray(context) {
48 | setTimeout(() => {
49 | context.commit('setArray', new Date().valueOf())
50 | }, 10000)
51 | },
52 | // 异步获取数组
53 | getArrayPromise(context) {
54 | return new Promise((resolve, reject) => {
55 | setTimeout(() => {
56 | const time = new Date().valueOf()
57 | resolve(time)
58 | }, 2000)
59 | })
60 | },
61 | // axios
62 | getDat2(context) {
63 | const ajax = axios.get('demo.json')
64 | ajax.then((response) => {
65 | const arr = response.data.company.formItem
66 | console.log('getData - axios - response', arr)
67 | // context.commit('reloadArray', arr)
68 | })
69 | .catch((error) => {
70 | console.log('getData - axios - error', error)
71 | })
72 | return ajax // 直接返回 axios 的promise的实例
73 | }
74 | },
75 | modules: {
76 | }
77 | })
78 |
--------------------------------------------------------------------------------
/cnd/project-template/src/store/map.js:
--------------------------------------------------------------------------------
1 |
2 | const map = () => {
3 | const store = Vuex.useStore()
4 |
5 | /**
6 | * 获取count,
7 | * 用computed实现相应
8 | */
9 | const getCount = () => {
10 | return Vue.computed(() => store.state.count)
11 | }
12 |
13 | /**
14 | * 获取count,
15 | ** 用 ref 实现相应
16 | */
17 | const getRefCount = () => {
18 | return Vue.ref(store.state.count)
19 | }
20 |
21 | /**
22 | * 获取对象
23 | */
24 | const getObject = () => {
25 | return store.state.myObject
26 | }
27 |
28 | /**
29 | * 获取只读对象
30 | */
31 | const getReadonlyObject = () => {
32 | return Vue.readonly(store.state.myObject)
33 | }
34 |
35 | /**
36 | * 获取数组
37 | */
38 | const getArray = () => {
39 | return store.state.myArray
40 | }
41 | /**
42 | * 获取只读数组
43 | */
44 | const getReadonlyArray = () => {
45 | return Vue.readonly(store.state.myArray)
46 | }
47 |
48 | /**
49 | * 查询数组
50 | ** id:要查询的数据
51 | */
52 | const filterArray = (id) => {
53 | return Vue.computed(() => store.getters.filterArray(id))
54 | }
55 |
56 | return {
57 | getCount,
58 | getRefCount,
59 | getObject,
60 | getReadonlyObject,
61 | getArray,
62 | getReadonlyArray,
63 | filterArray
64 | }
65 |
66 | }
67 |
68 | export default map
--------------------------------------------------------------------------------
/cnd/project-template/src/store/mutation-types.js:
--------------------------------------------------------------------------------
1 | export const Set_Count = 'set_count'
2 | export const Set_Count_sy = Symbol('set_count')
3 |
--------------------------------------------------------------------------------
/cnd/project-template/src/views/About.html:
--------------------------------------------------------------------------------
1 |
2 | 演示一下由路由加载的组件。
3 | html 和 js分开写的方式。
4 | 插值演示:{{value}}
5 |
6 |
--------------------------------------------------------------------------------
/cnd/project-template/src/views/About.js:
--------------------------------------------------------------------------------
1 | export default {
2 | name: 'About',
3 | template: '',
4 | setup () {
5 | const value = Vue.ref('数据绑定的演示')
6 |
7 | return {
8 | value
9 | }
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/cnd/project-template/src/views/component.html:
--------------------------------------------------------------------------------
1 |
2 | 演示一下组件里面使用组件的方式
3 |
4 |
5 |
--------------------------------------------------------------------------------
/cnd/project-template/src/views/component.js:
--------------------------------------------------------------------------------
1 | export default {
2 | name: 'template',
3 | template: ``,
4 | components: {
5 | test: Vue.defineAsyncComponent(
6 | () => myImport('components/test')
7 | )
8 | },
9 | setup () {
10 | const value = Vue.ref('传入组件的参数')
11 | return {
12 | value
13 | }
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/cnd/project-template/src/views/home.js:
--------------------------------------------------------------------------------
1 | const { ref, reactive } = Vue
2 |
3 | const testManage = () => {
4 | const hello = ref('你好,世界')
5 | const clickMe = () => {
6 | hello.value = '好的,收到,现在时间:' + new Date()
7 | }
8 |
9 | return {
10 | hello,
11 | clickMe
12 | }
13 | }
14 |
15 | // vue3的对象
16 | export default {
17 | template: `
18 |
我是 {{value.name}}
19 |
20 | 老规矩:{{hello}}
21 | 快点我
22 |
23 | 这里是一种CND的开发方式
24 | vue全家桶和UI库用 CND方式 加载。
25 | js代码用 import 方式加载。
26 | 目录结构参考了vue-cli建立的项目。
27 | 支持组件、路由、状态管理等功能。
28 | 不用webpack、npm等,建立网站就可以用。
29 | 状态计数:{{$store.state.count}}
30 |
31 | `,
32 | setup() {
33 | // 使用外面的定义,分解setup内部的代码
34 | const { hello, clickMe } = testManage()
35 |
36 | const value = reactive({
37 | name: 'jyk'
38 | })
39 |
40 |
41 | return {
42 | value,
43 | hello,
44 | clickMe
45 | }
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/cnd/project-template/src/views/store.html:
--------------------------------------------------------------------------------
1 |
2 | 这里演示一下 vuex 的一些操作:
3 |
4 | ref的count :{{refCount}}
5 | 计算属性的Count :{{comCount}}
6 | 只读对象 :{{readonlyObject}}
7 |
8 |
--------------------------------------------------------------------------------
/cnd/project-template/src/views/store.js:
--------------------------------------------------------------------------------
1 |
2 |
3 | // 获取状态
4 | const indirectManage = () => {
5 | const store = Vuex.useStore()
6 |
7 | // 用toRef获取 count,有相应性,可以直接修改state
8 | const refCount = Vue.toRef(store.state, 'count')
9 | // 计算属性获取count,有相应性,不可以直接修改state
10 | const comCount = Vue.computed(() => store.state.count + 10)
11 | // 只读的对象,有响应性,浅层不可以修改,但是深层还是可以修改。
12 | const readonlyObject = Vue.readonly(store.state.myObject)
13 |
14 | console.log('refCount:', refCount)
15 | console.log('comCount:', comCount)
16 | console.log('readonlyObject:', readonlyObject)
17 | console.log('================')
18 |
19 | // 定时修改 count 看响应性
20 | setTimeout(() => {
21 | // store.commit('setCount')
22 | // refCount.value += 200 // 会直接改vuex的state
23 | }, 2000)
24 |
25 | return {
26 | refCount,
27 | comCount,
28 | readonlyObject
29 | }
30 | }
31 |
32 |
33 | export default {
34 | name: 'vuex_store',
35 | template: '',
36 | components: {
37 | },
38 | setup () {
39 | const value = Vue.ref('状态管理的演示')
40 |
41 | // 获取状态
42 | const { refCount, comCount, readonlyObject } = indirectManage()
43 |
44 | return {
45 | value,
46 | refCount, comCount, readonlyObject
47 | }
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/cnd/project-template/web.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/cnd/project-vuex/README.md:
--------------------------------------------------------------------------------
1 |
2 | # 介绍vuex的相关内容
3 |
4 | * state
5 | * getter
6 |
7 | 在线演示:
8 | https://naturefwvue.github.io/nf-vue-cnd/cnd/project-vuex
9 |
--------------------------------------------------------------------------------
/cnd/project-vuex/a.html:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/naturefwvue/nf-vue-cnd/7670d199337cc527a04865181c5aacd8168fb901/cnd/project-vuex/a.html
--------------------------------------------------------------------------------
/cnd/project-vuex/demo.json:
--------------------------------------------------------------------------------
1 | {
2 | "company":{
3 | "formMeta":{
4 | "name":"company",
5 | "allColumn":[1000,1001,1002,1003,1004,1005,1006,1007,1008,1009],
6 | "state":"add",
7 | "colCount":1
8 | },
9 | "formItem":{
10 | "1000":{
11 | "controlId": 1000,
12 | "colName": "companyName",
13 | "controlType": 101,
14 | "isClear": true,
15 | "disabled": false,
16 | "required": true,
17 | "readonly": false,
18 | "pattern": "",
19 | "class": "",
20 | "placeholder": "请输入公司名称",
21 | "title": "公司名称",
22 | "autocomplete": "on",
23 | "size": 30,
24 | "maxlength": 100,
25 | "optionList": [],
26 | "tdCount":1
27 | },
28 | "1001":{
29 | "controlId": 1001,
30 | "colName": "companyCode",
31 | "controlType": 131,
32 | "isClear": true,
33 | "disabled": false,
34 | "required": true,
35 | "readonly": false,
36 | "pattern": "",
37 | "class": "",
38 | "placeholder": "公司邮编",
39 | "title": "公司邮编",
40 | "autocomplete": "on",
41 | "min": 100000,
42 | "max": 999999,
43 | "step": 1,
44 | "maxlength": 6,
45 | "optionList": [],
46 | "tdCount":1
47 | },
48 | "1002":{
49 | "controlId": 1002,
50 | "colName": "legalPerson",
51 | "controlType": 101,
52 | "isClear": true,
53 | "disabled": false,
54 | "required": true,
55 | "readonly": false,
56 | "pattern": "",
57 | "class": "",
58 | "placeholder": "请输入法人姓名",
59 | "title": "法人",
60 | "autocomplete": "on",
61 | "size": 20,
62 | "maxlength": 50,
63 | "optionList": [],
64 | "tdCount":1
65 | },
66 | "1003":{
67 | "controlId": 1003,
68 | "colName": "liaisonMan",
69 | "controlType": 101,
70 | "isClear": true,
71 | "disabled": false,
72 | "required": true,
73 | "readonly": false,
74 | "pattern": "",
75 | "class": "",
76 | "placeholder": "请输入联系人姓名",
77 | "title": "联系人",
78 | "autocomplete": "on",
79 | "size": 20,
80 | "maxlength": 50,
81 | "optionList": [],
82 | "tdCount":1
83 | },
84 | "1004": {
85 | "controlId": "1004",
86 | "colName": "address",
87 | "controlType": 101,
88 | "isClear": true,
89 | "defaultValue": "",
90 | "autofocus": false,
91 | "disabled": false,
92 | "required": true,
93 | "readonly": false,
94 | "pattern": "",
95 | "class": "",
96 | "placeholder": "请输入公司地址",
97 | "title": "公司地址",
98 | "autocomplete": "on",
99 | "size": 30,
100 | "maxlength": 50,
101 | "optionKey": "",
102 | "optionList": [],
103 | "tdCount":1
104 | },
105 | "1005": {
106 | "controlId": "1005",
107 | "colName": "telphone",
108 | "controlType": 103,
109 | "isClear": true,
110 | "defaultValue": "",
111 | "autofocus": false,
112 | "disabled": false,
113 | "required": true,
114 | "readonly": false,
115 | "pattern": "",
116 | "class": "",
117 | "placeholder": "请输入公司电话",
118 | "title": "公司电话",
119 | "autocomplete": "on",
120 | "size": 30,
121 | "maxlength": 50,
122 | "optionKey": "",
123 | "optionList": [],
124 | "tdCount":1
125 | },
126 | "1006": {
127 | "controlId": "1006",
128 | "colName": "URL",
129 | "controlType": 105,
130 | "isClear": true,
131 | "defaultValue": "",
132 | "autofocus": false,
133 | "disabled": false,
134 | "required": true,
135 | "readonly": false,
136 | "pattern": "",
137 | "class": "",
138 | "placeholder": "https://www.",
139 | "title": "公司网址",
140 | "autocomplete": "on",
141 | "size": 30,
142 | "maxlength": 50,
143 | "optionKey": "",
144 | "optionList": [],
145 | "tdCount":1
146 | },
147 | "1007": {
148 | "controlId": "1007",
149 | "colName": "Email",
150 | "controlType": 104,
151 | "isClear": true,
152 | "defaultValue": "",
153 | "autofocus": false,
154 | "disabled": false,
155 | "required": true,
156 | "readonly": false,
157 | "pattern": "",
158 | "class": "",
159 | "placeholder": "@",
160 | "title": "公司邮件",
161 | "autocomplete": "on",
162 | "size": 30,
163 | "maxlength": 50,
164 | "optionKey": "",
165 | "optionList": [],
166 | "tdCount":1
167 | },
168 | "1008": {
169 | "controlId": 1008,
170 | "colName": "type",
171 | "title": "公司类型",
172 | "controlType": 190,
173 | "isClear": true,
174 | "defaultValue": "",
175 | "autofocus": false,
176 | "disabled": false,
177 | "required": true,
178 | "pattern": "",
179 | "class": "",
180 | "optionList": [
181 | { "value": 1, "title": "有限责任公司" },
182 | { "value": 2, "title": "股份有限责任公司" },
183 | { "value": 3, "title": "个人独资企业" },
184 | { "value": 4, "title": "合伙企业" },
185 | { "value": 5, "title": "个体工商户" }
186 | ],
187 | "tdCount":1
188 | },
189 | "1009": {
190 | "controlId": 1009,
191 | "colName": "createDate",
192 | "controlType": 140,
193 | "isClear": true,
194 | "defaultValue": "",
195 | "autofocus": false,
196 | "disabled": false,
197 | "required": true,
198 | "readonly": false,
199 | "pattern": "",
200 | "class": "",
201 | "title": "成立日期",
202 | "min": "1950-01-01",
203 | "max": "2999-12-31",
204 | "step": 1,
205 | "tdCount":1
206 | },
207 | "1010":{
208 | "controlId": "2012",
209 | "colName": "education",
210 | "controlType": 183,
211 | "isClear": true,
212 | "disabled": false,
213 | "required": true,
214 | "readonly": false,
215 | "pattern": "",
216 | "class": "",
217 | "placeholder": "",
218 | "title": "学历",
219 | "optionList": [
220 | { "value": 1, "title": "高中" },
221 | { "value": 2, "title": "大专" },
222 | { "value": 3, "title": "本科" },
223 | { "value": 4, "title": "硕士" },
224 | { "value": 5, "title": "博士" }
225 | ]
226 | },
227 | "1011":{
228 | "controlId": 100,
229 | "colName": "hobby",
230 | "controlType": 182,
231 | "isClear": true,
232 | "disabled": false,
233 | "required": true,
234 | "readonly": false,
235 | "pattern": "",
236 | "class": "",
237 | "title": "爱好",
238 | "optionList": [
239 | { "value": 1, "title": "篮球" },
240 | { "value": 2, "title": "足球" },
241 | { "value": 3, "title": "排球" }
242 | ]
243 | }
244 | }
245 | },
246 | "person":{
247 | "formMeta":{
248 | "name":"person",
249 | "allColumn":[2000,2001,2002,2003,2012,2030],
250 | "state":"add",
251 | "colCount":1
252 | },
253 | "formItem":{
254 | "2000":{
255 | "controlId": 2000,
256 | "colName": "personId",
257 | "controlType": 101,
258 | "isClear": true,
259 | "disabled": false,
260 | "required": true,
261 | "readonly": false,
262 | "pattern": "",
263 | "class": "",
264 | "placeholder": "请输入",
265 | "title": "工号",
266 | "autocomplete": "on",
267 | "size": 10,
268 | "maxlength": 10,
269 | "optionList": []
270 | },
271 | "2001":{
272 | "controlId": 2001,
273 | "colName": "personName",
274 | "controlType": 101,
275 | "isClear": true,
276 | "disabled": false,
277 | "required": true,
278 | "readonly": false,
279 | "pattern": "",
280 | "class": "",
281 | "placeholder": "请输入员工姓名",
282 | "title": "姓名",
283 | "autocomplete": "on",
284 | "size": 10,
285 | "maxlength": "50"
286 | },
287 | "2002": {
288 | "controlId": 2002,
289 | "colName": "Gender",
290 | "controlType": 183,
291 | "isClear": true,
292 | "disabled": false,
293 | "required": true,
294 | "readonly": false,
295 | "pattern": "",
296 | "class": "",
297 | "title": "性别",
298 | "optionList": [
299 | { "value": "男", "title": "男" },
300 | { "value": "女", "title": "女" }
301 | ]
302 | },
303 | "2003":{
304 | "controlId": 2012,
305 | "colName": "nation",
306 | "controlType": 106,
307 | "isClear": true,
308 | "disabled": false,
309 | "required": true,
310 | "readonly": false,
311 | "pattern": "",
312 | "class": "",
313 | "placeholder": "请输入员工姓名",
314 | "title": "民族",
315 | "optionKey": "minzu",
316 | "optionList": [
317 | { "value": 1, "title": "汉" },
318 | { "value": 2, "title": "蒙古" },
319 | { "value": 3, "title": "满族" },
320 | { "value": 4, "title": "回族" },
321 | { "value": 5, "title": "朝鲜" }
322 | ]
323 | },
324 | "2012":{
325 | "controlId": 2012,
326 | "colName": "education",
327 | "controlType": 190,
328 | "isClear": true,
329 | "disabled": false,
330 | "required": true,
331 | "readonly": false,
332 | "pattern": "",
333 | "class": "",
334 | "placeholder": "",
335 | "title": "学历",
336 | "optionList": [
337 | { "value": 1, "title": "高中" },
338 | { "value": 2, "title": "大专" },
339 | { "value": 3, "title": "本科" },
340 | { "value": 4, "title": "硕士" },
341 | { "value": 5, "title": "博士" }
342 | ]
343 | },
344 | "2030":{
345 | "controlId": 2030,
346 | "colName": "hobby",
347 | "controlType": 182,
348 | "isClear": true,
349 | "disabled": false,
350 | "required": true,
351 | "readonly": false,
352 | "pattern": "",
353 | "class": "",
354 | "title": "爱好",
355 | "optionList": [
356 | { "value": 1, "title": "篮球" },
357 | { "value": 2, "title": "足球" },
358 | { "value": 3, "title": "排球" }
359 | ]
360 | }
361 | }
362 | }
363 | }
--------------------------------------------------------------------------------
/cnd/project-vuex/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
CDN 的工程化开发 的模板
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
28 |
29 |
48 |
49 |
50 |
51 | 这里演示一下vuex的演示...
52 |
53 |
54 |
55 |
56 | 首页
57 | state 的演示
58 | state2 的演示
59 | getter 的演示
60 | setter 的演示
61 | action 的演示
62 | module 的演示
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 | vuex状态演示
71 | 模板:
72 | $store :{{$store.state}}
73 | $store - myObject :{{$store.state.myObject}}
74 |
75 | 更新状态
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
--------------------------------------------------------------------------------
/cnd/project-vuex/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/naturefwvue/nf-vue-cnd/7670d199337cc527a04865181c5aacd8168fb901/cnd/project-vuex/public/favicon.ico
--------------------------------------------------------------------------------
/cnd/project-vuex/src/app.js:
--------------------------------------------------------------------------------
1 |
2 | // import { Set_Count, Set_Count_sy } from './store/mutation-types.js'
3 |
4 | export default {
5 | setup() {
6 | const store = Vuex.useStore()
7 |
8 | // 状态的控制事件
9 | const setCount = () =>{
10 | store.commit('setCount')
11 | store.commit('setTime')
12 | store.commit('setArray')
13 | // store._mutations.setCount[0] // 这是什么?
14 | }
15 |
16 | return {
17 | // 设置state
18 | setCount
19 | }
20 | }
21 | }
--------------------------------------------------------------------------------
/cnd/project-vuex/src/component/HelloWorld.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
{{ msg }}
4 |
{{ msg1 }}
5 |
6 | 尝试一下vue文件,目前没找到方法,也许需要Babel和webpack。
7 |
8 |
9 |
10 |
11 |
12 |
26 |
--------------------------------------------------------------------------------
/cnd/project-vuex/src/component/test.html:
--------------------------------------------------------------------------------
1 |
2 | 这是一个测试看看动态加载的组件
3 |
{{title}}
4 |
--------------------------------------------------------------------------------
/cnd/project-vuex/src/component/test.js:
--------------------------------------------------------------------------------
1 |
2 | const aa = '外部定义'
3 |
4 | const test = {
5 | template: `
6 | 这是 组件测试
7 | 参数:{{str1}}
8 | 外部函数:{{aa}}
9 | `,
10 | props: {
11 | str: String
12 | },
13 | setup(props) {
14 | // 在setup里面获取参数值
15 | const str1 = Vue.ref(props.str)
16 | // alert('test的alert')
17 | return {
18 | str1,
19 | aa
20 | }
21 | }
22 | }
23 |
24 | export default test
--------------------------------------------------------------------------------
/cnd/project-vuex/src/main.js:
--------------------------------------------------------------------------------
1 | /*
2 | import store from './store/index.js?v=28'
3 | import router from './router/index.js?v=28'
4 | import App from './app.js?v=28'
5 |
6 |
7 | // 创建vue3的实例
8 | const app = Vue.createApp(App)
9 | .use(store) // 挂载vuex
10 | .use(router) // 挂载路由
11 | .use(ElementPlus) // 加载ElementPlus
12 | .mount('#app') // 挂载Vue的app实例
13 |
14 | */
15 |
16 | const ver = window.__ver || ''
17 |
18 | Promise.all([
19 | import('./store/index.js' + ver),
20 | import('./router/index.js' + ver),
21 | import('./app.js' + ver),
22 | ]).then((res) => {
23 | // 创建vue3的实例
24 | const app = Vue.createApp(res[2].default)
25 | .use(res[0].default) // 挂载vuex
26 | .use(res[1].default) // 挂载路由
27 | .use(ElementPlus) // 加载ElementPlus
28 | .mount('#app') // 挂载Vue的app实例
29 | })
30 |
--------------------------------------------------------------------------------
/cnd/project-vuex/src/router/index.js:
--------------------------------------------------------------------------------
1 | // import myImport from '../script/myImport.js?v=29'
2 |
3 | const routes = [
4 | {
5 | path: '/',
6 | name: 'Home',
7 | component: () => myImport('views/home')
8 | },
9 | {
10 | path: '/state',
11 | name: 'state',
12 | component: () => myImport('views/01stateall')
13 | },
14 | {
15 | path: '/state2',
16 | name: 'state2',
17 | component: () => myImport('views/02statemember')
18 | },
19 | {
20 | path: '/getter',
21 | name: 'getter',
22 | component: () => myImport('views/03getter')
23 | },
24 | {
25 | path: '/setter',
26 | name: 'setter',
27 | component: () => myImport('views/04setter')
28 | },
29 | {
30 | path: '/action',
31 | name: 'action',
32 | component: () => myImport('views/05action')
33 | },
34 | {
35 | path: '/module',
36 | name: 'module',
37 | component: () => myImport('views/06module')
38 | }
39 | ]
40 |
41 | const router = VueRouter.createRouter({
42 | history: VueRouter.createWebHistory(),
43 | routes
44 | })
45 |
46 | export default router
47 |
--------------------------------------------------------------------------------
/cnd/project-vuex/src/script/appImport.js:
--------------------------------------------------------------------------------
1 | // 直接放在Window里面好了。。。
2 | window.myImport = (url) => {
3 | return new Promise((resolve, reject) => {
4 | const ver = window.__ver || ''
5 | const baseUrl = window.__basrUrl || '/src/'
6 | // 先加载js
7 | import(baseUrl + url + '.js' + ver).then((resjs) => {
8 | const js = resjs.default
9 | if (js.template === '') {
10 | // 如果模板是空的,表示需要加载html作为模板
11 | axios.get(baseUrl + url + '.html' + ver).then((resHTML) => {
12 | js.template = resHTML.data
13 | resolve(js)
14 | })
15 | } else {
16 | // 否则直接使用js注册组件
17 | resolve(js)
18 | }
19 | })
20 | })
21 | }
22 |
--------------------------------------------------------------------------------
/cnd/project-vuex/src/script/myImport.js:
--------------------------------------------------------------------------------
1 | // 同步加载的方式
2 | const myImport2 = (url) => {
3 | return new Promise((resolve, reject) => {
4 | const ver = window.__ver || ''
5 | const baseUrl = window.__basrUrl || '/src/'
6 | Promise.all([
7 | axios.get(baseUrl + url + '.html' + ver),
8 | import(baseUrl + url + '.js' + ver)
9 | ]).then((req) => {
10 | resolve({
11 | template: req[0].data,
12 | props: req[1].default.props,
13 | setup: req[1].default.setup
14 | })
15 | })
16 | })
17 | }
18 |
19 | // 加载html和js
20 | const myImport = (url) => {
21 | return new Promise((resolve, reject) => {
22 | const ver = window.__ver || ''
23 | const baseUrl = window.__basrUrl || '/src/'
24 | // 先加载js
25 | import(baseUrl + url + '.js' + ver).then((resjs) => {
26 | const js = resjs.default
27 | if (js.template === '') {
28 | // 如果模板是空的,表示需要加载html作为模板
29 | axios.get(baseUrl + url + '.html' + ver).then((resHTML) => {
30 | js.template = resHTML.data
31 | resolve(js)
32 | })
33 | } else {
34 | // 否则直接使用js注册组件
35 | resolve(js)
36 | }
37 | })
38 | })
39 | }
40 |
41 | export default myImport
--------------------------------------------------------------------------------
/cnd/project-vuex/src/store/index.js:
--------------------------------------------------------------------------------
1 |
2 | import { Set_Count, Set_Count_sy } from './mutation-types.js'
3 |
4 | import user from './user.js'
5 |
6 | const myPlugin = store => {
7 | console.log('插件--store', store)
8 | // 当 store 初始化后调用
9 | store.subscribe((mutation, state) => {
10 | console.log('插件--store', store)
11 | console.log('插件--', mutation)
12 |
13 | // 每次 mutation 之后调用
14 | // mutation 的格式为 { type, payload }
15 |
16 | })
17 | }
18 |
19 | export default Vuex.createStore({
20 | // plugins: [myPlugin],
21 | state: {
22 | count: 0,
23 | myObject: {
24 | time: '现在的时间:'
25 | },
26 | myArray: [1,2,2,3,4]
27 | },
28 | getters: {
29 | getAddCount: (state) => {
30 | return state.count + 1
31 | },
32 | getTime: (state) => {
33 | return state.myObject.time + new Date()
34 | },
35 | filterArray: (state) => (id) => {
36 | return state.myArray.filter((item) => item === id)
37 | }
38 | },
39 | mutations: {
40 | // 计数器
41 | setCount(state, num = 1) {
42 | state.count += num
43 |
44 | },
45 | [Set_Count](state, num = 1) {
46 | state.count += num
47 | },
48 | // 设置当前时间
49 | setTime(state) {
50 | state.myObject.time = '现在时间:' + new Date()
51 |
52 | },
53 | // 设置数组的值
54 | setArray(state, val = 4) {
55 | state.myArray[1] = val
56 | },
57 | reloadArray(state, arr) {
58 | state.myArray.lenth = 0
59 | state.myArray = [...arr]
60 | }
61 | },
62 | actions: {
63 | // 异步获取数组
64 | getArray(context) {
65 | console.log('================================')
66 | console.log('异步getArray——context', context)
67 | setTimeout(() => {
68 | context.commit('setArray', new Date().valueOf())
69 | }, 10000)
70 | },
71 | // 异步获取数组
72 | getArrayPromise(context) {
73 | return new Promise((resolve, reject) => {
74 | console.log('================================')
75 | console.log('异步 getArrayPromise ——context', context)
76 | setTimeout(() => {
77 | const time = new Date().valueOf()
78 | // context.commit('setArray', time)
79 | resolve(time)
80 | }, 2000)
81 | })
82 | },
83 | // axios
84 | getData(context) {
85 | return new Promise((resolve, reject) => {
86 | axios.get('demo.json')
87 | .then((response) => {
88 | const arr = response.data.company.formItem
89 | console.log('getData - axios - response', response)
90 | // context.commit('reloadArray', response.data.company.formItem)
91 | resolve(arr)
92 | })
93 | .catch((error) => {
94 | console.log('getData - axios - error', error)
95 | })
96 | })
97 | },
98 | // axios
99 | getDat2(context) {
100 | const ajax = axios.get('demo.json')
101 | ajax.then((response) => {
102 | const arr = response.data.company.formItem
103 | console.log('getData - axios - response', arr)
104 | // context.commit('reloadArray', arr)
105 | })
106 | .catch((error) => {
107 | console.log('getData - axios - error', error)
108 | })
109 | return ajax // 直接返回 axios 的promise的实例
110 | }
111 | },
112 | modules: {
113 | myObject: user,
114 | user: user,
115 | person: user
116 | }
117 | })
118 |
--------------------------------------------------------------------------------
/cnd/project-vuex/src/store/map.js:
--------------------------------------------------------------------------------
1 |
2 | const map = () => {
3 | const store = Vuex.useStore()
4 |
5 | /**
6 | * 获取count,
7 | * 用computed实现相应
8 | */
9 | const getCount = () => {
10 | return Vue.computed(() => store.state.count)
11 | }
12 |
13 | /**
14 | * 获取count,
15 | ** 用 ref 实现相应
16 | */
17 | const getRefCount = () => {
18 | return Vue.ref(store.state.count)
19 | }
20 |
21 | /**
22 | * 获取对象
23 | */
24 | const getObject = () => {
25 | return store.state.myObject
26 | }
27 |
28 | /**
29 | * 获取只读对象
30 | */
31 | const getReadonlyObject = () => {
32 | return Vue.readonly(store.state.myObject)
33 | }
34 |
35 | /**
36 | * 获取数组
37 | */
38 | const getArray = () => {
39 | return store.state.myArray
40 | }
41 | /**
42 | * 获取只读数组
43 | */
44 | const getReadonlyArray = () => {
45 | return Vue.readonly(store.state.myArray)
46 | }
47 |
48 | /**
49 | * 查询数组
50 | ** id:要查询的数据
51 | */
52 | const filterArray = (id) => {
53 | return Vue.computed(() => store.getters.filterArray(id))
54 | }
55 |
56 | return {
57 | getCount,
58 | getRefCount,
59 | getObject,
60 | getReadonlyObject,
61 | getArray,
62 | getReadonlyArray,
63 | filterArray
64 | }
65 |
66 | }
67 |
68 | export default map
--------------------------------------------------------------------------------
/cnd/project-vuex/src/store/map2.js:
--------------------------------------------------------------------------------
1 |
2 |
3 | /*
4 | * 获取计数器
5 | */
6 | export const getCount = () => {
7 | return Vuex.useStore().state.count
8 | }
9 |
10 | export const getCount1 = () => {
11 | return Vuex.useStore().state.state.getter.getCount
12 | }
13 |
--------------------------------------------------------------------------------
/cnd/project-vuex/src/store/mutation-types.js:
--------------------------------------------------------------------------------
1 | export const Set_Count = 'set_count'
2 | export const Set_Count_sy = Symbol('set_count')
3 |
--------------------------------------------------------------------------------
/cnd/project-vuex/src/store/user.js:
--------------------------------------------------------------------------------
1 |
2 | const user = {
3 | namespaced: true, // 避免重名
4 | state: () => ({
5 | userInfo: {
6 | userId: 123,
7 | userCode: '',
8 | userNick: ''
9 | },
10 | userRole: []
11 | }),
12 | mutations: {
13 | setUser(state, code) {
14 | state.userInfo.userCode = code
15 | }
16 | },
17 | getters: {
18 | getUser(state) {
19 | return state.userInfo
20 | }
21 | },
22 | actions: {
23 | // { state, commit, rootState }
24 | setUsera (store, code) {
25 | store.commit('setUser', code)
26 | }
27 | }
28 | }
29 |
30 | export default user
--------------------------------------------------------------------------------
/cnd/project-vuex/src/views/01stateall.html:
--------------------------------------------------------------------------------
1 |
2 | 整体22:
3 | allState :{{allState}}
4 |
5 | 成员 :
6 | memberCount : {{memberCount}} (用简单类型的成员定义,没有相应性)
7 | memberObject :{{memberObject}} (用引用类型的成员定义,自带响应性)
8 |
9 |
10 |
--------------------------------------------------------------------------------
/cnd/project-vuex/src/views/01stateall.js:
--------------------------------------------------------------------------------
1 |
2 | // 整体获取
3 | const allStateManage = () => {
4 | const store = Vuex.useStore()
5 |
6 | // 看看state的类型
7 | console.log('state:', store.state)
8 | console.log('state.count:', store.state.count)
9 | console.log('state.myObject:', store.state.myObject)
10 |
11 | // 获得整体的state
12 | const allState = store.state
13 | console.log('allState:', allState)
14 | console.log('================')
15 |
16 | // 定时修改 count 看响应性
17 | setTimeout(() => {
18 | // store.commit('setCount')
19 | allState.count += 101 // 会直接改vuex的state
20 | }, 1000)
21 |
22 | return {
23 | allState
24 | }
25 | }
26 |
27 |
28 | export default {
29 | name: 'vuex_state_all',
30 | template: '',
31 | components: {
32 | },
33 | setup () {
34 | const value = Vue.ref('state_all')
35 |
36 | // 获取state
37 | const { allState } = allStateManage()
38 |
39 | return {
40 | value,
41 | allState
42 | }
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/cnd/project-vuex/src/views/02statemember.html:
--------------------------------------------------------------------------------
1 |
2 | 间接获取:
3 | refCount :{{refCount}} (ref)
4 | comCount :{{comCount}} (计算属性)
5 | readonlyObject : {{readonlyObject}} (只读的reactive)
6 |
7 |
--------------------------------------------------------------------------------
/cnd/project-vuex/src/views/02statemember.js:
--------------------------------------------------------------------------------
1 |
2 | // 直接获取state的成员
3 | const stateMemberManage = () => {
4 | const store = Vuex.useStore()
5 |
6 | // 看看state的类型
7 | let memberCount = store.state.count // 失去响应性
8 | const memberObject = store.state.myObject
9 | console.log('memberCount', memberCount)
10 | console.log('memberObject', memberObject)
11 | console.log('================')
12 |
13 | // 定时修改 count 看响应性
14 | setTimeout(() => {
15 | // memberCount += 101
16 | // const 定义的会报错,不允许赋值,常量。
17 | // let 定义的可以修改,但是没有相应性
18 | }, 1000)
19 |
20 | return {
21 | memberCount,
22 | memberObject
23 | }
24 | }
25 |
26 |
27 | export default {
28 | name: 'vuex_action',
29 | template: '',
30 | components: {
31 | },
32 | setup () {
33 | const value = Vue.ref('测试动态加载组件333')
34 |
35 | // action
36 | const { memberCount, memberObject } = stateMemberManage()
37 |
38 | return {
39 | value,
40 | memberCount,
41 | memberObject
42 | }
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/cnd/project-vuex/src/views/03getter.html:
--------------------------------------------------------------------------------
1 |
2 | 这里演示一下 vuex 的 getter 的相关操作:
3 |
4 | addCount :{{addCount}} (计算属性,导致整体都 +1)
5 | getAddCount :{{getAddCount}} (getter,自己没有相应性)
6 | comGetAddCount :{{comGetAddCount}} (getter,需要套一个computed才能相应)
7 | filterArray :{{filterArray}} (getter,需要套一个computed才能相应)
8 | comFilterArray :{{comFilterArray}} (getter,需要套一个computed才能相应)
9 |
10 |
--------------------------------------------------------------------------------
/cnd/project-vuex/src/views/03getter.js:
--------------------------------------------------------------------------------
1 |
2 |
3 | // 间接获取
4 | const indirectManage = () => {
5 | const store = Vuex.useStore()
6 |
7 | // 用toRef获取 count,有相应性,可以直接修改state
8 | const refCount = Vue.toRef(store.state, 'count')
9 | // 计算属性获取count,有相应性,不可以直接修改state
10 | const comCount = '' // Vue.computed(() => store.state.count)
11 | // 只读的对象,有相应性,浅层不可以修改,但是深层还是可以修改。
12 | const readonlyObject = Vue.readonly(store.state.myObject)
13 |
14 | console.log('refCount:', refCount)
15 | console.log('comCount:', comCount)
16 | console.log('readonlyObject:', readonlyObject)
17 | console.log('================')
18 |
19 | // 定时修改 count 看响应性
20 | setTimeout(() => {
21 | // store.commit('setCount')
22 | // refCount.value += 200 // 会直接改vuex的state
23 | }, 2000)
24 |
25 | return {
26 | refCount,
27 | comCount,
28 | readonlyObject
29 | }
30 | }
31 |
32 |
33 | // 处理后返回
34 | const operationManage = () => {
35 | const store = Vuex.useStore()
36 | // 计算属性获取count
37 | const addCount = Vue.computed(() => store.state.count + 1)
38 | const getAddCount = store.getters.getAddCount
39 | const comGetAddCount = Vue.computed(() => store.getters.getAddCount)
40 | const filterArray = store.getters.filterArray(2)
41 | const comFilterArray = Vue.computed(() => store.getters.filterArray(2))
42 |
43 | console.log('addCount :', addCount)
44 | console.log('getAddCount :', getAddCount)
45 | console.log('comGetAddCount :', comGetAddCount)
46 | console.log('filterArray :', filterArray)
47 | console.log('comFilterArray :', comFilterArray)
48 | console.log('================')
49 |
50 | return {
51 | addCount,
52 | getAddCount,
53 | comGetAddCount,
54 | filterArray,
55 | comFilterArray
56 | }
57 |
58 | }
59 |
60 | export default {
61 | name: 'vuex_getter',
62 | template: '',
63 | components: {
64 | },
65 | setup () {
66 | const value = Vue.ref('getter')
67 |
68 | // 间接获取成员
69 | const { refCount, comCount, readonlyObject } = indirectManage()
70 |
71 | // 间接获取成员
72 | const {
73 | addCount,
74 | getAddCount,
75 | comGetAddCount,
76 | filterArray,
77 | comFilterArray
78 | } = operationManage()
79 |
80 | return {
81 | value,
82 | addCount,
83 | getAddCount,
84 | comGetAddCount,
85 | filterArray,
86 | comFilterArray,
87 | refCount, comCount, readonlyObject
88 | }
89 | }
90 | }
91 |
--------------------------------------------------------------------------------
/cnd/project-vuex/src/views/04setter.html:
--------------------------------------------------------------------------------
1 |
2 | 这里演示一下 vuex 的 mutations 的相关操作:
3 | commitSetCount :{{commitSetCount}}
4 |
--------------------------------------------------------------------------------
/cnd/project-vuex/src/views/04setter.js:
--------------------------------------------------------------------------------
1 |
2 |
3 | // 设置state
4 | const mutationsManage = () => {
5 | const store = Vuex.useStore()
6 |
7 | let commitSetCount = Vue.computed({
8 | get: () => store.state.count + 1,
9 | set: (val) => {
10 | // store.commit('setCount', val)
11 | }
12 | })
13 | console.log('commitSetCount :', commitSetCount)
14 | console.log('================')
15 |
16 | // 定时修改 count 看响应性
17 | setTimeout(() => {
18 | // commitSetCount.value = 202 // 会直接改vuex的state
19 | }, 2000)
20 |
21 | return {
22 | commitSetCount
23 | }
24 | }
25 |
26 | export default {
27 | name: 'vuex_setter',
28 | template: '',
29 | components: {
30 | },
31 | setup () {
32 | const value = Vue.ref('setter')
33 |
34 | // mutations
35 | const { commitSetCount } = mutationsManage()
36 |
37 | return {
38 | value,
39 | // 突变
40 | commitSetCount,
41 | }
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/cnd/project-vuex/src/views/05action.html:
--------------------------------------------------------------------------------
1 |
2 | 这里演示一下 vuex 的 action 的相关操作
3 | value22 :{{value}}
4 |
5 |
--------------------------------------------------------------------------------
/cnd/project-vuex/src/views/05action.js:
--------------------------------------------------------------------------------
1 |
2 | // 异步操作
3 | const actionManame = () => {
4 | const store = Vuex.useStore()
5 |
6 | const getArray = store.dispatch('getArray')
7 | console.log('外部调用 getArray', getArray)
8 | getArray.then((data) => {
9 | console.log('===========')
10 | console.log('getArray 异步操作完成,返回数据:', data)
11 | console.log('===========')
12 | })
13 |
14 | const getArrayPromise = store.dispatch('getArrayPromise')
15 | console.log('外部调用 getArrayPromise', getArrayPromise)
16 | getArrayPromise.then((data) => {
17 | console.log('===========')
18 | console.log('getArrayPromise 异步操作完成,返回数据:', data)
19 | console.log('===========')
20 | })
21 |
22 | store.dispatch('getData').then((data) => {
23 | console.log('===========')
24 | console.log('getData 异步操作完成,返回数据:', data)
25 | console.log('===========')
26 |
27 | })
28 |
29 | return {
30 | getArray,
31 | getArrayPromise
32 | }
33 | }
34 |
35 |
36 | export default {
37 | name: 'vuex_action',
38 | template: '',
39 | components: {
40 | },
41 | setup () {
42 | const value = Vue.ref('测试动态加载组件333')
43 |
44 | // action
45 | const { getArray, getArrayPromise } = actionManame()
46 |
47 | return {
48 | value,
49 | getArray,
50 | getArrayPromise
51 | }
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/cnd/project-vuex/src/views/06map.html:
--------------------------------------------------------------------------------
1 |
2 | 封装:
3 | mapCount :{{mapCount}}
4 |
5 |
--------------------------------------------------------------------------------
/cnd/project-vuex/src/views/06map.js:
--------------------------------------------------------------------------------
1 |
2 | import map from './store/map.js?v=12'
3 |
4 | export default {
5 | name: 'vuex_map',
6 | template: '',
7 | components: {
8 | },
9 | setup () {
10 | const value = Vue.ref('map')
11 |
12 | // 通过map 获取 count
13 | // 可以使用别名
14 | const {
15 | getCount: mapGetCount
16 | } = map()
17 |
18 | const mapCount = mapGetCount()
19 | return {
20 | value,
21 | mapCount
22 | }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/cnd/project-vuex/src/views/06module.html:
--------------------------------------------------------------------------------
1 |
2 | 模块演示:
3 | 用户信息: {{userInfo}}
4 |
--------------------------------------------------------------------------------
/cnd/project-vuex/src/views/06module.js:
--------------------------------------------------------------------------------
1 |
2 | const moduleManage = () => {
3 | const store = Vuex.useStore()
4 |
5 | const userInfo = store.state.user.userInfo
6 |
7 | const userInfo2 = store.getters['user/getUser']
8 |
9 | // store.commit('setUser', '没有命名空间的code')
10 |
11 | // store.dispatch('setUsera', 'actionde的code')
12 |
13 | store.commit('user/setUser', 'user的code')
14 | store.commit('myObject/setUser', 'myObject的code')
15 | store.commit('person/setUser', 'person的code')
16 |
17 | store.dispatch('user/setUsera', 'action的user的code')
18 |
19 |
20 | return {
21 | userInfo,
22 | userInfo2
23 | }
24 | }
25 |
26 | export default {
27 | name: 'vuex_module',
28 | template: '',
29 | components: {
30 | },
31 | setup () {
32 | const value = Vue.ref('module')
33 |
34 | const {
35 | userInfo
36 | } = moduleManage()
37 |
38 | return {
39 | value,
40 | userInfo
41 | }
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/cnd/project-vuex/src/views/home.js:
--------------------------------------------------------------------------------
1 | const { ref } = Vue
2 |
3 | const testManage = () => {
4 | const hello = ref('你好,世界')
5 | const clickMe = () => {
6 | hello.value = '好的22,收到' + new Date().valueOf()
7 | }
8 |
9 | return {
10 | hello,
11 | clickMe
12 | }
13 | }
14 |
15 | // vue3的对象
16 | const home = {
17 | template: `
18 |
这是home
19 |
20 | 我是{{value.name}}。
21 | 老规矩:{{hello}}
22 |
23 | 本项目采用“混合”模式开发,
24 | vue全家桶和UI库用script标签加载。
25 | 代码用import方式加载。
26 | 目录结构参考了cli建立的项目。
27 | 支持组件、路由、状态管理等功能。
28 | 状态计数:{{$store.state.count}}
29 |
30 | `,
31 | setup() { // 传说中的setup
32 | // 使用外面的定义,分解setup内部的代码
33 | const { hello, clickMe } = testManage()
34 |
35 | const value = Vue.reactive({
36 | name: 'jyk'
37 | })
38 |
39 |
40 | return {
41 | value,
42 | hello,
43 | clickMe
44 | }
45 | }
46 | }
47 |
48 | export default home
--------------------------------------------------------------------------------
/cnd/project-vuex/vuex.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 | vuex 的尝试
4 | test: {{test}}
5 | computedVuex: {{computedVuex}}
6 | get2: {{get2}}
7 | get: {{get}}
8 | myRef: {{myRef2}}
9 | $store:{{$store}}
10 |
11 |
12 |
13 |
14 |
15 |
16 |
82 |
--------------------------------------------------------------------------------
/cnd/project-vuex/web.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/cnd/project/README.md:
--------------------------------------------------------------------------------
1 |
2 | # 一种尝试
3 | * vue的全家桶和UI库,采用传统的方式加载(CND)。
4 | * 自己写的js代码,采用ES6的import方式加载。
5 | * 目录结构采用工程化的项目的结构。
6 | * 首页用vite项目的首页。
7 | * 不用babel做转义(因为还不会用)。
8 | * 不用webpack(因为总是报错,头痛...)。
9 |
10 |
11 | 在线演示:
12 | https://naturefwvue.github.io/nf-vue-cnd/cnd/project
13 |
14 |
--------------------------------------------------------------------------------
/cnd/project/a.html:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/naturefwvue/nf-vue-cnd/7670d199337cc527a04865181c5aacd8168fb901/cnd/project/a.html
--------------------------------------------------------------------------------
/cnd/project/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
一种怪异的方式
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
34 |
35 |
36 |
37 | 这是一个尝试...
38 |
39 |
40 |
41 |
42 | 首页
43 | 查看状态管理
44 | 查看组件加载
45 |
46 |
47 |
48 |
49 | vuex状态演示
50 | $store - count:{{$store.state.count}}
51 |
vuex的 计数
52 |
53 |
54 |
55 |
56 |
57 |
--------------------------------------------------------------------------------
/cnd/project/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/naturefwvue/nf-vue-cnd/7670d199337cc527a04865181c5aacd8168fb901/cnd/project/public/favicon.ico
--------------------------------------------------------------------------------
/cnd/project/src/app.js:
--------------------------------------------------------------------------------
1 |
2 | // vue3的对象
3 | const App = {
4 | setup() { // 传说中的setup
5 |
6 | const store = Vuex.useStore()
7 | // 状态的控制事件
8 | const setCount = () =>{
9 | store.commit('setCount')
10 | }
11 |
12 | return { // 返回给模板,否则模板访问不到。
13 | setCount
14 | }
15 | }
16 | }
17 |
18 | export default App
19 |
--------------------------------------------------------------------------------
/cnd/project/src/component/HelloWorld.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
{{ msg }}
4 |
5 | 尝试一下vue文件,目前没找到方法,也许需要Babel和webpack。
6 |
7 |
8 |
9 |
10 |
11 |
19 |
--------------------------------------------------------------------------------
/cnd/project/src/component/test.js:
--------------------------------------------------------------------------------
1 | const test = {
2 | template: `
3 | 这是 组件测试
4 | 参数:{{str1}}
5 | `,
6 | model: {
7 | prop: ['str']
8 | },
9 | props: {
10 | str: String
11 | },
12 | setup(props) {
13 | // 在setup里面获取参数值
14 | const str1 = Vue.ref(props.str)
15 |
16 | return {
17 | str1
18 | }
19 | }
20 | }
21 |
22 | export default test
--------------------------------------------------------------------------------
/cnd/project/src/main.js:
--------------------------------------------------------------------------------
1 | import store from './store/index.js?v=6'
2 | import router from './router/index.js?v=8'
3 | import App from './app.js?v=6'
4 |
5 | // 创建vue3的实例
6 | const app = Vue.createApp(App)
7 | .use(store) // 挂载vuex
8 | .use(router) // 挂载路由
9 | .use(ElementPlus) // 加载ElementPlus
10 | .mount('#app') // 挂载Vue的app实例
11 |
12 |
--------------------------------------------------------------------------------
/cnd/project/src/router/index.js:
--------------------------------------------------------------------------------
1 | // import Home from '../views/home.js?v=2'
2 |
3 | const routes = [
4 | {
5 | path: '/',
6 | name: 'Home',
7 | component: () => import('../views/home.js?v=8')
8 | },
9 | {
10 | path: '/state',
11 | name: 'state',
12 | component: () => import('../views/state.js?v=8')
13 | },
14 | {
15 | path: '/component',
16 | name: 'component',
17 | component: () => import('../views/component.js?v=8')
18 | }
19 | ]
20 |
21 | const router = VueRouter.createRouter({
22 | history: VueRouter.createWebHistory(),
23 | routes
24 | })
25 |
26 | export default router
27 |
--------------------------------------------------------------------------------
/cnd/project/src/store/index.js:
--------------------------------------------------------------------------------
1 |
2 | export default Vuex.createStore({
3 | state: {
4 | count: 0,
5 | myObject: {
6 | time: '现在的时间'
7 | }
8 | },
9 | getters: {
10 | getCount: (state) => {
11 | return state.count
12 | },
13 | getMyObject: (state) => {
14 | return Vue.readonly(state.myObject)
15 | },
16 | getTime: (state) => {
17 | return state.myObject.time
18 | }
19 | },
20 | mutations: {
21 | setCount(state) {
22 | state.count++
23 | },
24 | setTime(state) {
25 | state.myObject.time = '现在时间:' + new Date()
26 | }
27 | },
28 | actions: {
29 | },
30 | modules: {
31 | }
32 | })
33 |
--------------------------------------------------------------------------------
/cnd/project/src/views/component.js:
--------------------------------------------------------------------------------
1 | // 引入组件
2 | import test from '../component/test.js?v=7'
3 |
4 | const demo = {
5 | template: `
6 |
这是组件演示
7 |
8 | `,
9 | components: {
10 | test
11 | },
12 | setup() {
13 |
14 | return {
15 | }
16 | }
17 | }
18 |
19 | export default demo
--------------------------------------------------------------------------------
/cnd/project/src/views/home.js:
--------------------------------------------------------------------------------
1 |
2 | const testManage = () => {
3 | const hello = Vue.ref('你好,世界')
4 | const clickMe = () => {
5 | hello.value = '好的,收到' + new Date().valueOf()
6 | }
7 |
8 | return {
9 | hello,
10 | clickMe
11 | }
12 | }
13 |
14 | // vue3的对象
15 | const home = {
16 | template: `
17 |
这是home
18 |
19 | 我是{{value.name}}。
20 | 老规矩:{{hello}}
21 |
22 | 本项目采用“混合”模式开发,
23 | vue全家桶和UI库用script标签加载。
24 | 代码用import方式加载。
25 | 目录结构参考了cli建立的项目。
26 | 支持组件、路由、状态管理等功能。
27 | 状态计数:{{$store.state.count}}
28 |
29 | `,
30 | setup() { // 传说中的setup
31 | // 使用外面的定义,分解setup内部的代码
32 | const { hello, clickMe } = testManage()
33 |
34 | const value = Vue.reactive({
35 | name: 'jyk'
36 | })
37 |
38 |
39 | return {
40 | value,
41 | hello,
42 | clickMe
43 | }
44 | }
45 | }
46 |
47 | export default home
--------------------------------------------------------------------------------
/cnd/project/src/views/state.js:
--------------------------------------------------------------------------------
1 | // vue3的对象
2 | const demo = {
3 | template: `
4 |
这里是状态演示
5 | setup 里面的 count:{{count}}
6 | `,
7 | setup() { // 传说中的setup
8 | const store = Vuex.useStore()
9 | // 在代码里面获取状态
10 | const count = Vue.computed(() => store.getters.getCount)
11 |
12 | return {
13 | count
14 | }
15 | }
16 | }
17 |
18 | export default demo
--------------------------------------------------------------------------------
/cnd/project/vuex.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 | vuex 的尝试
4 | test: {{test}}
5 | computedVuex: {{computedVuex}}
6 | get2: {{get2}}
7 | get: {{get}}
8 | myRef: {{myRef2}}
9 | $store:{{$store}}
10 |
11 |
12 |
13 |
14 |
15 |
16 |
82 |
--------------------------------------------------------------------------------
/cnd/project/web.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/web.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------